3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Matthias Ettrich
7 * \author Lars Gullik Bjønnes
8 * \author Jean-Marc Lasgouttes
9 * \author Angus Leeming
13 * Full author contact details are available in file CREDITS.
21 #include "support/docstream.h"
31 /////////////////////////////////////////////////////////////////////
35 /////////////////////////////////////////////////////////////////////
38 : val_(0), unit_(Length::UNIT_NONE)
42 Length::Length(double v, Length::UNIT u)
47 Length::Length(string const & data)
48 : val_(0), unit_(Length::PT)
52 if (!isValidLength(data, &tmp))
53 return; // should raise an exception
60 void Length::swap(Length & rhs)
62 std::swap(val_, rhs.val_);
63 std::swap(unit_, rhs.unit_);
67 string const Length::asString() const
70 os << val_ << unit_name[unit_]; // setw?
75 docstring const Length::asDocstring() const
78 os << val_ << unit_name[unit_]; // setw?
83 string const Length::asLatexString() const
88 os << val_ / 100.0 << "\\textwidth";
91 os << val_ / 100.0 << "\\columnwidth";
94 os << val_ / 100.0 << "\\paperwidth";
97 os << val_ / 100.0 << "\\linewidth";
100 os << val_ / 100.0 << "\\paperheight";
103 os << val_ / 100.0 << "\\textheight";
106 os << val_ << unit_name[unit_];
113 double Length::value() const
119 Length::UNIT Length::unit() const
125 void Length::value(double v)
131 void Length::unit(Length::UNIT u)
137 bool Length::zero() const
143 bool Length::empty() const
145 return unit_ == Length::UNIT_NONE;
149 int Length::inPixels(int text_width, int em_width_base) const
151 // Zoom factor specified by user in percent
152 double const zoom = lyxrc.zoom / 100.0; // [percent]
154 // DPI setting for monitor: pixels/inch
155 double const dpi = lyxrc.dpi; // screen resolution [pixels/inch]
157 double const em_width = (em_width_base > 0)
159 : 10*(dpi/72.27)*zoom;
160 // A different estimate for em_width is
161 // theFontMetrics(FontInfo(sane_font)).width('M')
162 // but this estimate might not be more accurate as the screen font
163 // is different then the latex font.
165 // Pixel values are scaled so that the ratio
166 // between lengths and font sizes on the screen
167 // is the same as on paper.
173 // Scaled point: sp = 1/65536 pt
174 result = zoom * dpi * val_
175 / (72.27 * 65536); // 4736286.7
178 // Point: 1 pt = 1/72.27 inch
179 result = zoom * dpi * val_
183 // Big point: 1 bp = 1/72 inch
184 result = zoom * dpi * val_
188 // Didot: 1157dd = 1238 pt?
189 result = zoom * dpi * val_
190 / (72.27 / (0.376 * 2.845)); // 67.559735
193 // Millimeter: 1 mm = 1/25.4 inch
194 result = zoom * dpi * val_
198 // Pica: 1 pc = 12 pt
199 result = zoom * dpi * val_
200 / (72.27 / 12); // 6.0225
203 // Cicero: 1 cc = 12 dd
204 result = zoom * dpi * val_
205 / (72.27 / (12 * 0.376 * 2.845)); // 5.6299779
208 // Centimeter: 1 cm = 1/2.54 inch
209 result = zoom * dpi * val_
214 result = zoom * dpi * val_;
217 // Ex: The height of an "x"
218 // 0.4305 is the ration between 1ex and 1em in cmr10
219 result = val_ * em_width * 0.4305;
222 // Em: The width of an "m"
223 result = val_ * em_width;
226 // math unit = 1/18em
227 result = val_ * em_width / 18;
229 case Length::PCW: // Always % of workarea
232 result = val_ * text_width / 100;
235 // paperwidth/textwidth is 1.7 for A4 paper with default margins
236 result = val_ * text_width * 1.7 / 100;
239 result = val_ * text_width * 1.787 / 100;
242 result = val_ * text_width * 2.2 / 100;
244 case Length::UNIT_NONE:
245 result = 0; // this cannot happen
248 return static_cast<int>(result + ((result >= 0) ? 0.5 : -0.5));
252 int Length::inBP() const
254 // return any Length value as a one with
255 // the PostScript point, called bp (big points)
260 result = val_ * 28.346;
264 result = val_ * 2.8346;
268 result = val_ * 72.0;
271 // no other than bp possible
275 return static_cast<int>(result + 0.5);
279 bool operator==(Length const & l1, Length const & l2)
281 return l1.value() == l2.value() && l1.unit() == l2.unit();
285 bool operator!=(Length const & l1, Length const & l2)
291 /////////////////////////////////////////////////////////////////////
295 /////////////////////////////////////////////////////////////////////
298 GlueLength::GlueLength(Length const & len)
303 GlueLength::GlueLength(Length const & len, Length const & plus,
304 Length const & minus)
305 : len_(len), plus_(plus), minus_(minus)
309 GlueLength::GlueLength(string const & data)
311 isValidGlueLength(data, this);
315 string const GlueLength::asString() const
317 ostringstream buffer;
319 buffer << len_.value();
321 if (plus_.zero() && minus_.zero()) {
322 buffer << unit_name[len_.unit()];
328 if (len_.unit() != plus_.unit())
329 buffer << unit_name[len_.unit()];
330 buffer << '+' << plus_.value();
331 buffer << unit_name[plus_.unit()];
335 // just len and minus
337 if (len_.unit() != minus_.unit())
338 buffer << unit_name[len_.unit()];
339 buffer << '-' << minus_.value();
340 buffer << unit_name[minus_.unit()];
344 // ok, len, plus AND minus
347 if (minus_ == plus_) {
348 if (len_.unit() != minus_.unit())
349 buffer << unit_name[len_.unit()];
350 buffer << "+-" << minus_.value();
351 buffer << unit_name[minus_.unit()];
355 // this is so rare a case, why bother minimising units ?
357 buffer << unit_name[len_.unit()];
358 buffer << '+' << plus_.value() << unit_name[plus_.unit()];
359 buffer << '-' << minus_.value() << unit_name[minus_.unit()];
365 string const GlueLength::asLatexString() const
367 ostringstream buffer;
369 buffer << len_.value() << unit_name[len_.unit()];
372 buffer << " plus " << plus_.value() << unit_name[plus_.unit()];
374 buffer << " minus " << minus_.value() << unit_name[minus_.unit()];
379 Length const & GlueLength::len() const
385 Length const & GlueLength::plus() const
391 Length const & GlueLength::minus() const
397 bool operator==(GlueLength const & l1, GlueLength const & l2)
399 return l1.len() == l2.len()
400 && l1.plus() == l2.plus()
401 && l1.minus() == l2.minus();
405 bool operator!=(GlueLength const & l1, GlueLength const & l2)