]> git.lyx.org Git - lyx.git/blob - src/lyxlength.C
Replace LString.h with support/std_string.h,
[lyx.git] / src / lyxlength.C
1 /**
2  * \file lyxlength.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Matthias Ettrich
7  * \author Lars Gullik Bjønnes
8  * \author Jean-Marc Lasgouttes
9  * \author Angus Leeming
10  * \author John Levon
11  * \author Dekel Tsur
12  *
13  * Full author contact details are available in file CREDITS.
14  */
15
16 #include <config.h>
17
18 #include "lyxlength.h"
19 #include "lengthcommon.h"
20 #include "lyxrc.h"
21
22
23 #include "support/std_sstream.h"
24
25
26 using std::abs;
27
28 LyXLength::LyXLength()
29         : val_(0), unit_(LyXLength::UNIT_NONE)
30 {}
31
32
33 LyXLength::LyXLength(double v, LyXLength::UNIT u)
34         : val_(v), unit_(u)
35 {}
36
37
38 LyXLength::LyXLength(string const & data)
39         : val_(0), unit_(LyXLength::PT)
40 {
41         LyXLength tmp;
42
43         if (!isValidLength(data, &tmp))
44                 return; // should raise an exception
45
46         val_  = tmp.val_;
47         unit_ = tmp.unit_;
48 }
49
50
51 string const LyXLength::asString() const
52 {
53         ostringstream buffer;
54         buffer << val_ << unit_name[unit_]; // setw?
55         return STRCONV(buffer.str());
56 }
57
58
59 string const LyXLength::asLatexString() const
60 {
61         ostringstream buffer;
62         switch (unit_) {
63         case PTW:
64             buffer << abs(static_cast<int>(val_/100)) << '.'
65                    << abs(static_cast<int>(val_)%100) << "\\textwidth";
66             break;
67         case PCW:
68             buffer << abs(static_cast<int>(val_/100)) << '.'
69                    << abs(static_cast<int>(val_)%100) << "\\columnwidth";
70             break;
71         case PPW:
72             buffer << abs(static_cast<int>(val_/100)) << '.'
73                    << abs(static_cast<int>(val_)%100) << "\\paperwidth";
74             break;
75         case PLW:
76             buffer << abs(static_cast<int>(val_/100)) << '.'
77                    << abs(static_cast<int>(val_)%100) << "\\linewidth";
78             break;
79         case PPH:
80             buffer << abs(static_cast<int>(val_/100)) << '.'
81                    << abs(static_cast<int>(val_)%100) << "\\paperheight";
82             break;
83         case PTH:
84             buffer << abs(static_cast<int>(val_/100)) << '.'
85                    << abs(static_cast<int>(val_)%100) << "\\textheight";
86             break;
87         default:
88             buffer << val_ << unit_name[unit_]; // setw?
89             break;
90         }
91         return STRCONV(buffer.str());
92 }
93
94
95 double LyXLength::value() const
96 {
97         return val_;
98 }
99
100
101 LyXLength::UNIT LyXLength::unit() const
102 {
103         return unit_;
104 }
105
106
107 void LyXLength::value(double v)
108 {
109         val_ = v;
110 }
111
112
113 void LyXLength::unit(LyXLength::UNIT u)
114 {
115         unit_ = u;
116 }
117
118
119 bool LyXLength::zero() const
120 {
121         return val_ == 0.0;
122 }
123
124
125 bool LyXLength::empty() const
126 {
127         return unit_ == LyXLength::UNIT_NONE;
128 }
129
130
131 int LyXLength::inPixels(int text_width, int em_width_base) const
132 {
133         // Zoom factor specified by user in percent
134         double const zoom = lyxrc.zoom / 100.0; // [percent]
135
136         // DPI setting for monitor: pixels/inch
137         double const dpi = lyxrc.dpi; // screen resolution [pixels/inch]
138
139         double const em_width = (em_width_base > 0)
140                 ? em_width_base
141                 : 10*(dpi/72.27)*zoom;
142         // A different estimate for em_width is
143         // font_metrics::width('M', LyXFont(LyXFont::ALL_SANE))
144         // but this estimate might not be more accurate as the screen font
145         // is different then the latex font.
146
147         // Pixel values are scaled so that the ratio
148         // between lengths and font sizes on the screen
149         // is the same as on paper.
150
151 #ifdef WITH_WARNINGS
152 #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')
153 #endif
154
155         double result = 0.0;
156
157         switch (unit_) {
158         case LyXLength::SP:
159                 // Scaled point: sp = 1/65536 pt
160                 result = zoom * dpi * val_
161                         / (72.27 * 65536); // 4736286.7
162                 break;
163         case LyXLength::PT:
164                 // Point: 1 pt = 1/72.27 inch
165                 result = zoom * dpi * val_
166                         / 72.27; // 72.27
167                 break;
168         case LyXLength::BP:
169                 // Big point: 1 bp = 1/72 inch
170                 result = zoom * dpi * val_
171                         / 72; // 72
172                 break;
173         case LyXLength::DD:
174                 // Didot: 1157dd = 1238 pt?
175                 result = zoom * dpi * val_
176                         / (72.27 / (0.376 * 2.845)); // 67.559735
177                 break;
178         case LyXLength::MM:
179                 // Millimeter: 1 mm = 1/25.4 inch
180                 result = zoom * dpi * val_
181                         / 25.4; // 25.4
182                 break;
183         case LyXLength::PC:
184                 // Pica: 1 pc = 12 pt
185                 result = zoom * dpi * val_
186                         / (72.27 / 12); // 6.0225
187                 break;
188         case LyXLength::CC:
189                 // Cicero: 1 cc = 12 dd
190                 result = zoom * dpi * val_
191                         / (72.27 / (12 * 0.376 * 2.845)); // 5.6299779
192                 break;
193         case LyXLength::CM:
194                 // Centimeter: 1 cm = 1/2.54 inch
195                 result = zoom * dpi * val_
196                         / 2.54; // 2.54
197                 break;
198         case LyXLength::IN:
199                 // Inch
200                 result = zoom * dpi * val_;
201                 break;
202         case LyXLength::EX:
203                 // Ex: The height of an "x"
204                 // 0.4305 is the ration between 1ex and 1em in cmr10
205                 result = val_ * em_width * 0.4305;
206                 break;
207         case LyXLength::EM:
208                 // Em: The width of an "m"
209                 result = val_ * em_width;
210                 break;
211         case LyXLength::MU:
212                 // math unit = 1/18em
213                 result = val_ * em_width / 18;
214                 break;
215         case LyXLength::PCW: // Always % of workarea
216         case LyXLength::PTW:
217         case LyXLength::PLW:
218                 result = val_ * text_width / 100;
219                 break;
220         case LyXLength::PPW:
221                 // paperwidth/textwidth is 1.7 for A4 paper with default margins
222                 result = val_ * text_width * 1.7 / 100;
223                 break;
224         case LyXLength::PTH:
225                 result = val_ * text_width * 1.787 / 100;
226                 break;
227         case LyXLength::PPH:
228                 result = val_ * text_width * 2.2 / 100;
229                 break;
230         case LyXLength::UNIT_NONE:
231                 result = 0;  // this cannot happen
232                 break;
233         }
234         return static_cast<int>(result + ((result >= 0) ? 0.5 : -0.5));
235 }
236
237
238 int LyXLength::inBP() const
239 {
240         // return any LyXLength value as a one with
241         // the PostScript point, called bp (big points)
242         double result = 0.0;
243         switch (unit_) {
244         case LyXLength::CM:
245                 // 1bp = 0.2835cm
246                 result = val_ * 28.346;
247                 break;
248         case LyXLength::MM:
249                 // 1bp = 0.02835mm
250                 result = val_ * 2.8346;
251                 break;
252         case LyXLength::IN:
253                 // 1pt = 1/72in
254                 result = val_ * 72.0;
255                 break;
256         default:
257                 // no other than bp possible
258                 result = val_;
259                 break;
260         }
261         return static_cast<int>(result + 0.5);
262 }
263
264
265 bool operator==(LyXLength const & l1, LyXLength const & l2)
266 {
267         return l1.value() == l2.value() && l1.unit() == l2.unit();
268 }
269
270
271 bool operator!=(LyXLength const & l1, LyXLength const & l2)
272 {
273         return !(l1 == l2);
274 }