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