]> git.lyx.org Git - lyx.git/blob - src/lyxlength.C
2cc2e853b2cc3b5720e74a9b23518849a79c23e7
[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 #include "BufferView.h"
21 #include "lyxtext.h"
22
23 #include "Lsstream.h"
24
25 #include <cstdlib>
26
27
28 LyXLength::LyXLength()
29         : val_(0), unit_(LyXLength::PT)
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 buffer.str().c_str();
56 }
57
58
59 string const LyXLength::asLatexString() const
60 {
61         ostringstream buffer;
62         switch(unit_) {
63         case PW:
64         case PE:
65             buffer << abs(static_cast<int>(val_/100)) << "."
66                    << abs(static_cast<int>(val_)%100) << "\\columnwidth";
67             break;
68         case PP:
69             buffer << abs(static_cast<int>(val_/100)) << "."
70                    << abs(static_cast<int>(val_)%100) << "\\pagewidth";
71             break;
72         case PL:
73             buffer << abs(static_cast<int>(val_/100)) << "."
74                    << abs(static_cast<int>(val_)%100) << "\\linewidth";
75             break;
76         default:
77             buffer << val_ << unit_name[unit_]; // setw?
78             break;
79         }
80         return buffer.str().c_str();
81 }
82
83
84 double LyXLength::value() const
85 {
86         return val_;
87 }
88
89
90 LyXLength::UNIT LyXLength::unit() const
91 {
92         return unit_;
93 }
94
95
96 void LyXLength::value(double v)
97 {
98         val_ = v;
99 }
100
101
102 void LyXLength::unit(LyXLength::UNIT u)
103 {
104         unit_ = u;
105 }
106
107
108 bool LyXLength::zero() const 
109 {
110         return val_ == 0.0;
111 }
112
113
114 int LyXLength::inPixels(BufferView const * bv) const
115 {
116         // Height of a normal line in pixels (zoom factor considered)
117         int height = bv->text->defaultHeight(); // [pixels]
118         int default_width  = bv->workWidth();
119
120         // Zoom factor specified by user in percent
121         double const zoom = lyxrc.zoom / 100.0; // [percent]
122
123         // DPI setting for monitor: pixels/inch
124         double const dpi = lyxrc.dpi; // screen resolution [pixels/inch]
125
126         // Pixel values are scaled so that the ratio
127         // between lengths and font sizes on the screen
128         // is the same as on paper.
129
130         // we don't care about sign of value, we
131         // display negative space with text too
132         double result = 0.0;
133         int val_sign = val_ < 0.0 ? -1 : 1;
134                 
135         switch (unit_) {
136         case LyXLength::SP:
137                 // Scaled point: sp = 1/65536 pt
138                 result = zoom * dpi * val_
139                         / (72.27 * 65536); // 4736286.7
140                 break;
141         case LyXLength::PT:
142                 // Point: 1 pt = 1/72.27 inch
143                 result = zoom * dpi * val_
144                         / 72.27; // 72.27
145                 break;
146         case LyXLength::BP:
147                 // Big point: 1 bp = 1/72 inch
148                 result = zoom * dpi * val_
149                         / 72; // 72
150                 break;
151         case LyXLength::DD:
152                 // Didot: 1157dd = 1238 pt?
153                 result = zoom * dpi * val_
154                         / (72.27 / (0.376 * 2.845)); // 67.559735
155                 break;
156         case LyXLength::MM:
157                 // Millimeter: 1 mm = 1/25.4 inch
158                 result = zoom * dpi * val_
159                         / 25.4; // 25.4
160                 break;
161         case LyXLength::PC:
162                 // Pica: 1 pc = 12 pt
163                 result = zoom * dpi * val_
164                         / (72.27 / 12); // 6.0225
165                 break;
166         case LyXLength::CC:
167                 // Cicero: 1 cc = 12 dd
168                 result = zoom * dpi * val_
169                         / (72.27 / (12 * 0.376 * 2.845)); // 5.6299779
170                 break;
171         case LyXLength::CM:
172                 // Centimeter: 1 cm = 1/2.54 inch
173                 result = zoom * dpi * val_
174                         / 2.54; // 2.54
175                 break;
176         case LyXLength::IN:
177                 // Inch
178                 result = zoom * dpi * val_;
179                 break;
180         case LyXLength::EX:
181                 // Ex: The height of an "x"
182                 result = zoom * val_ * height / 2; // what to / width?
183                 break;
184         case LyXLength::EM: // what to / width?
185                 // Em: The width of an "m"
186                 result = zoom * val_ * height / 2; // Why 2?
187                 break;
188         case LyXLength::MU: // This is probably only allowed in
189                 // math mode
190                 result = zoom * val_ * height;
191                 break;
192         case LyXLength::PW: // Always % of workarea
193         case LyXLength::PE:
194         case LyXLength::PP:
195         case LyXLength::PL:
196                 result = val_ * default_width / 100;
197                 break;
198         case LyXLength::UNIT_NONE:
199                 result = 0;  // this cannot happen
200                 break;
201         }
202         return static_cast<int>(result * val_sign + 0.5);
203 }
204
205
206 bool operator==(LyXLength const & l1, LyXLength const & l2)
207 {
208         return l1.value() == l2.value() && l1.unit() == l2.unit();
209 }
210
211
212 bool operator!=(LyXLength const & l1, LyXLength const & l2)
213 {
214         return !(l1 == l2);
215 }
216