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