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.
23 #include "support/docstream.h"
31 using std::ostringstream;
34 // FIXME: I am not sure if "mu" should be possible to select (Lgb)
35 char const * const unit_name[] = {
36 "sp", "pt", "bp", "dd", "mm", "pc",
37 "cc", "cm", "in", "ex", "em", "mu",
38 "text%", "col%", "page%", "line%",
39 "theight%", "pheight%", "" };
42 int const num_units = int(sizeof(unit_name) / sizeof(unit_name[0]) - 1);
45 char const * const unit_name_gui[] = {
46 N_("sp"), N_("pt"), N_("bp"), N_("dd"), N_("mm"), N_("pc"),
47 N_("cc[[unit of measure]]"), N_("cm"), N_("in"), N_("ex"), N_("em"), N_("mu"),
48 N_("Text Width %"), N_("Column Width %"), N_("Page Width %"), N_("Line Width %"),
49 N_("Text Height %"), N_("Page Height %"), "" };
52 Length::UNIT unitFromString(string const & data)
55 while (i < num_units && data != unit_name[i])
57 return static_cast<Length::UNIT>(i);
61 /////////////////////////////////////////////////////////////////////
65 /////////////////////////////////////////////////////////////////////
68 : val_(0), unit_(Length::UNIT_NONE)
72 Length::Length(double v, Length::UNIT u)
77 Length::Length(string const & data)
78 : val_(0), unit_(Length::PT)
82 if (!isValidLength(data, &tmp))
83 return; // should raise an exception
90 void Length::swap(Length & rhs)
92 std::swap(val_, rhs.val_);
93 std::swap(unit_, rhs.unit_);
97 string const Length::asString() const
100 os << val_ << unit_name[unit_]; // setw?
105 docstring const Length::asDocstring() const
108 os << val_ << unit_name[unit_]; // setw?
113 string const Length::asLatexString() const
118 os << val_ / 100.0 << "\\textwidth";
121 os << val_ / 100.0 << "\\columnwidth";
124 os << val_ / 100.0 << "\\paperwidth";
127 os << val_ / 100.0 << "\\linewidth";
130 os << val_ / 100.0 << "\\paperheight";
133 os << val_ / 100.0 << "\\textheight";
136 os << val_ << unit_name[unit_];
143 double Length::value() const
149 Length::UNIT Length::unit() const
155 void Length::value(double v)
161 void Length::unit(Length::UNIT u)
167 bool Length::zero() const
173 bool Length::empty() const
175 return unit_ == Length::UNIT_NONE;
179 int Length::inPixels(int text_width, int em_width_base) const
181 // Zoom factor specified by user in percent
182 double const zoom = lyxrc.zoom / 100.0; // [percent]
184 // DPI setting for monitor: pixels/inch
185 double const dpi = lyxrc.dpi; // screen resolution [pixels/inch]
187 double const em_width = (em_width_base > 0)
189 : 10*(dpi/72.27)*zoom;
190 // A different estimate for em_width is
191 // theFontMetrics(FontInfo(sane_font)).width('M')
192 // but this estimate might not be more accurate as the screen font
193 // is different then the latex font.
195 // Pixel values are scaled so that the ratio
196 // between lengths and font sizes on the screen
197 // is the same as on paper.
203 // Scaled point: sp = 1/65536 pt
204 result = zoom * dpi * val_
205 / (72.27 * 65536); // 4736286.7
208 // Point: 1 pt = 1/72.27 inch
209 result = zoom * dpi * val_
213 // Big point: 1 bp = 1/72 inch
214 result = zoom * dpi * val_
218 // Didot: 1157dd = 1238 pt?
219 result = zoom * dpi * val_
220 / (72.27 / (0.376 * 2.845)); // 67.559735
223 // Millimeter: 1 mm = 1/25.4 inch
224 result = zoom * dpi * val_
228 // Pica: 1 pc = 12 pt
229 result = zoom * dpi * val_
230 / (72.27 / 12); // 6.0225
233 // Cicero: 1 cc = 12 dd
234 result = zoom * dpi * val_
235 / (72.27 / (12 * 0.376 * 2.845)); // 5.6299779
238 // Centimeter: 1 cm = 1/2.54 inch
239 result = zoom * dpi * val_
244 result = zoom * dpi * val_;
247 // Ex: The height of an "x"
248 // 0.4305 is the ration between 1ex and 1em in cmr10
249 result = val_ * em_width * 0.4305;
252 // Em: The width of an "m"
253 result = val_ * em_width;
256 // math unit = 1/18em
257 result = val_ * em_width / 18;
259 case Length::PCW: // Always % of workarea
262 result = val_ * text_width / 100;
265 // paperwidth/textwidth is 1.7 for A4 paper with default margins
266 result = val_ * text_width * 1.7 / 100;
269 result = val_ * text_width * 1.787 / 100;
272 result = val_ * text_width * 2.2 / 100;
274 case Length::UNIT_NONE:
275 result = 0; // this cannot happen
278 return static_cast<int>(result + ((result >= 0) ? 0.5 : -0.5));
282 int Length::inBP() const
284 // return any Length value as a one with
285 // the PostScript point, called bp (big points)
290 result = val_ * 28.346;
294 result = val_ * 2.8346;
298 result = val_ * 72.0;
301 // no other than bp possible
305 return static_cast<int>(result + 0.5);
309 bool operator==(Length const & l1, Length const & l2)
311 return l1.value() == l2.value() && l1.unit() == l2.unit();
315 bool operator!=(Length const & l1, Length const & l2)
321 /////////////////////////////////////////////////////////////////////
325 /////////////////////////////////////////////////////////////////////
328 GlueLength::GlueLength(Length const & len)
333 GlueLength::GlueLength(Length const & len, Length const & plus,
334 Length const & minus)
335 : len_(len), plus_(plus), minus_(minus)
339 GlueLength::GlueLength(string const & data)
341 isValidGlueLength(data, this);
345 string const GlueLength::asString() const
347 ostringstream buffer;
349 buffer << len_.value();
351 if (plus_.zero() && minus_.zero()) {
352 buffer << unit_name[len_.unit()];
358 if (len_.unit() != plus_.unit())
359 buffer << unit_name[len_.unit()];
360 buffer << '+' << plus_.value();
361 buffer << unit_name[plus_.unit()];
365 // just len and minus
367 if (len_.unit() != minus_.unit())
368 buffer << unit_name[len_.unit()];
369 buffer << '-' << minus_.value();
370 buffer << unit_name[minus_.unit()];
374 // ok, len, plus AND minus
377 if (minus_ == plus_) {
378 if (len_.unit() != minus_.unit())
379 buffer << unit_name[len_.unit()];
380 buffer << "+-" << minus_.value();
381 buffer << unit_name[minus_.unit()];
385 // this is so rare a case, why bother minimising units ?
387 buffer << unit_name[len_.unit()];
388 buffer << '+' << plus_.value() << unit_name[plus_.unit()];
389 buffer << '-' << minus_.value() << unit_name[minus_.unit()];
395 string const GlueLength::asLatexString() const
397 ostringstream buffer;
399 buffer << len_.value() << unit_name[len_.unit()];
402 buffer << " plus " << plus_.value() << unit_name[plus_.unit()];
404 buffer << " minus " << minus_.value() << unit_name[minus_.unit()];
409 Length const & GlueLength::len() const
415 Length const & GlueLength::plus() const
421 Length const & GlueLength::minus() const
427 bool operator==(GlueLength const & l1, GlueLength const & l2)
429 return l1.len() == l2.len()
430 && l1.plus() == l2.plus()
431 && l1.minus() == l2.minus();
435 bool operator!=(GlueLength const & l1, GlueLength const & l2)