]> git.lyx.org Git - lyx.git/blob - src/lyxlength.C
some more changes
[lyx.git] / src / lyxlength.C
1 /* This file is part of
2  * ======================================================
3  *
4  *           LyX, The Document Processor
5  *
6  *           Copyright 1995 Matthias Ettrich
7  *           Copyright 1995-2001 The LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include "lyxlength.h"
18 #include "lengthcommon.h"
19 #include "lyxrc.h"
20
21 #include "support/lstrings.h"
22
23 #include "Lsstream.h"
24
25 #include <cstdlib>
26
27 using std::abs;
28
29 LyXLength::LyXLength()
30         : val_(0), unit_(LyXLength::PT)
31 {}
32
33
34 LyXLength::LyXLength(double v, LyXLength::UNIT u)
35         : val_(v), unit_(u)
36 {}
37
38
39 #ifndef NO_PEXTRA_REALLY
40 // compatibility stuff < version 1.2.0pre and for 
41 // "old" 1.2.0 files before the pre
42 namespace {
43 string const convertOldRelLength(string const & oldLength) 
44 {
45         // we can have only one or none of the following
46         if (oldLength.find("c%") != string::npos) {
47                 return subst(oldLength,"c%","col%");
48                     
49         } else if (oldLength.find("t%") != string::npos) {
50                 if (oldLength.find("text%") != string::npos)
51                     return oldLength;
52                 else
53                     return subst(oldLength,"t%","text%");
54
55         } else if (oldLength.find("l%") != string::npos) {
56                 if (oldLength.find("col%") != string::npos)
57                     return oldLength;
58                 else
59                     return subst(oldLength,"l%","line%");
60
61         } else if (oldLength.find("p%") != string::npos)
62                 return subst(oldLength,"p%","page%");
63
64         return oldLength;
65 }
66 } // end anon
67 #endif
68
69 LyXLength::LyXLength(string const & data)
70         : val_(0), unit_(LyXLength::PT)
71 {
72         LyXLength tmp;
73
74 #ifndef NO_PEXTRA_REALLY
75         // this is needed for 1.1.x minipages with width like %t
76         if (!isValidLength (convertOldRelLength(data), &tmp))
77 #else
78         if (!isValidLength (data, &tmp))
79 #endif
80                 if (!isValidLength (convertOldRelLength(data), &tmp))
81                 return; // should raise an exception
82
83         val_  = tmp.val_;
84         unit_ = tmp.unit_;
85 }
86
87
88 string const LyXLength::asString() const
89 {
90         ostringstream buffer;
91         buffer << val_ << unit_name[unit_]; // setw?
92         return buffer.str().c_str();
93 }
94
95
96 string const LyXLength::asLatexString() const
97 {
98         ostringstream buffer;
99         switch (unit_) {
100         case PW:
101             buffer << abs(static_cast<int>(val_/100)) << "."
102                    << abs(static_cast<int>(val_)%100) << "\\textwidth";
103             break;
104         case PE:
105             buffer << abs(static_cast<int>(val_/100)) << "."
106                    << abs(static_cast<int>(val_)%100) << "\\columnwidth";
107             break;
108         case PP:
109             buffer << abs(static_cast<int>(val_/100)) << "."
110                    << abs(static_cast<int>(val_)%100) << "\\paperwidth";
111             break;
112         case PL:
113             buffer << abs(static_cast<int>(val_/100)) << "."
114                    << abs(static_cast<int>(val_)%100) << "\\linewidth";
115             break;
116         default:
117             buffer << val_ << unit_name[unit_]; // setw?
118             break;
119         }
120         return buffer.str().c_str();
121 }
122
123
124 double LyXLength::value() const
125 {
126         return val_;
127 }
128
129
130 LyXLength::UNIT LyXLength::unit() const
131 {
132         return unit_;
133 }
134
135
136 void LyXLength::value(double v)
137 {
138         val_ = v;
139 }
140
141
142 void LyXLength::unit(LyXLength::UNIT u)
143 {
144         unit_ = u;
145 }
146
147
148 bool LyXLength::zero() const
149 {
150         return val_ == 0.0;
151 }
152
153
154 int LyXLength::inPixels(int default_width, int default_height) const
155 {
156         // Zoom factor specified by user in percent
157         double const zoom = lyxrc.zoom / 100.0; // [percent]
158
159         // DPI setting for monitor: pixels/inch
160         double const dpi = lyxrc.dpi; // screen resolution [pixels/inch]
161
162         // Pixel values are scaled so that the ratio
163         // between lengths and font sizes on the screen
164         // is the same as on paper.
165
166         // we don't care about sign of value, we
167         // display negative space with text too
168 #ifdef WITH_WARNINGS
169 #warning if you don't care than either call this function differently or let it return negative values and call abs() explicitly when needed (Andre')
170 #endif
171
172         double result = 0.0;
173         int val_sign = val_ < 0.0 ? -1 : 1;
174
175         switch (unit_) {
176         case LyXLength::SP:
177                 // Scaled point: sp = 1/65536 pt
178                 result = zoom * dpi * val_
179                         / (72.27 * 65536); // 4736286.7
180                 break;
181         case LyXLength::PT:
182                 // Point: 1 pt = 1/72.27 inch
183                 result = zoom * dpi * val_
184                         / 72.27; // 72.27
185                 break;
186         case LyXLength::BP:
187                 // Big point: 1 bp = 1/72 inch
188                 result = zoom * dpi * val_
189                         / 72; // 72
190                 break;
191         case LyXLength::DD:
192                 // Didot: 1157dd = 1238 pt?
193                 result = zoom * dpi * val_
194                         / (72.27 / (0.376 * 2.845)); // 67.559735
195                 break;
196         case LyXLength::MM:
197                 // Millimeter: 1 mm = 1/25.4 inch
198                 result = zoom * dpi * val_
199                         / 25.4; // 25.4
200                 break;
201         case LyXLength::PC:
202                 // Pica: 1 pc = 12 pt
203                 result = zoom * dpi * val_
204                         / (72.27 / 12); // 6.0225
205                 break;
206         case LyXLength::CC:
207                 // Cicero: 1 cc = 12 dd
208                 result = zoom * dpi * val_
209                         / (72.27 / (12 * 0.376 * 2.845)); // 5.6299779
210                 break;
211         case LyXLength::CM:
212                 // Centimeter: 1 cm = 1/2.54 inch
213                 result = zoom * dpi * val_
214                         / 2.54; // 2.54
215                 break;
216         case LyXLength::IN:
217                 // Inch
218                 result = zoom * dpi * val_;
219                 break;
220         case LyXLength::EX:
221                 // Ex: The height of an "x"
222                 result = zoom * val_ * default_height / 2; // what to / width?
223                 break;
224         case LyXLength::EM: // what to / width?
225                 // Em: The width of an "m"
226                 result = zoom * val_ * default_height / 2; // Why 2?
227                 break;
228         case LyXLength::MU: // This is probably only allowed in
229                 // math mode
230                 result = zoom * val_ * default_height;
231                 break;
232         case LyXLength::PW: // Always % of workarea
233         case LyXLength::PE:
234         case LyXLength::PP:
235         case LyXLength::PL:
236                 result = val_ * default_width / 100;
237                 break;
238         case LyXLength::UNIT_NONE:
239                 result = 0;  // this cannot happen
240                 break;
241         }
242         return static_cast<int>(result * val_sign + 0.5);
243 }
244
245
246 int LyXLength::inBP() const
247 {
248         // return any LyXLength value as a one with
249         // the PostScript point, called bp (big points)
250         double result = 0.0;
251         switch (unit_) {
252         case LyXLength::CM:
253                 // 1bp = 0.2835cm
254                 result = val_ * 28.346;
255                 break;
256         case LyXLength::MM:
257                 // 1bp = 0.02835mm
258                 result = val_ * 2.8346;
259                 break;
260         case LyXLength::IN:
261                 // 1pt = 1/72in
262                 result = val_ * 72.0;
263                 break;
264         default:
265                 // no other than bp possible
266                 result = val_;
267                 break;
268         }
269         return static_cast<int>(result + 0.5);
270 }
271
272
273 bool operator==(LyXLength const & l1, LyXLength const & l2)
274 {
275         return l1.value() == l2.value() && l1.unit() == l2.unit();
276 }
277
278
279 bool operator!=(LyXLength const & l1, LyXLength const & l2)
280 {
281         return !(l1 == l2);
282 }