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