/** * \file lyxlength.C * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * * \author Matthias Ettrich * \author Lars Gullik Bjønnes * \author Jean-Marc Lasgouttes * \author Angus Leeming * \author John Levon * \author Dekel Tsur * * Full author contact details are available in file CREDITS. */ #include #include "lyxlength.h" #include "lengthcommon.h" #include "lyxrc.h" #include #include using std::ostringstream; using std::string; LyXLength::LyXLength() : val_(0), unit_(LyXLength::UNIT_NONE) {} LyXLength::LyXLength(double v, LyXLength::UNIT u) : val_(v), unit_(u) {} LyXLength::LyXLength(string const & data) : val_(0), unit_(LyXLength::PT) { LyXLength tmp; if (!isValidLength(data, &tmp)) return; // should raise an exception val_ = tmp.val_; unit_ = tmp.unit_; } string const LyXLength::asString() const { ostringstream os; os << val_ << unit_name[unit_]; // setw? return os.str(); } string const LyXLength::asLatexString() const { ostringstream os; switch (unit_) { case PTW: os << val_ / 100.0 << "\\textwidth"; break; case PCW: os << val_ / 100.0 << "\\columnwidth"; break; case PPW: os << val_ / 100.0 << "\\paperwidth"; break; case PLW: os << val_ / 100.0 << "\\linewidth"; break; case PPH: os << val_ / 100.0 << "\\paperheight"; break; case PTH: os << val_ / 100.0 << "\\textheight"; break; default: os << val_ << unit_name[unit_]; break; } return os.str(); } double LyXLength::value() const { return val_; } LyXLength::UNIT LyXLength::unit() const { return unit_; } void LyXLength::value(double v) { val_ = v; } void LyXLength::unit(LyXLength::UNIT u) { unit_ = u; } bool LyXLength::zero() const { return val_ == 0.0; } bool LyXLength::empty() const { return unit_ == LyXLength::UNIT_NONE; } int LyXLength::inPixels(int text_width, int em_width_base) const { // Zoom factor specified by user in percent double const zoom = lyxrc.zoom / 100.0; // [percent] // DPI setting for monitor: pixels/inch double const dpi = lyxrc.dpi; // screen resolution [pixels/inch] double const em_width = (em_width_base > 0) ? em_width_base : 10*(dpi/72.27)*zoom; // A different estimate for em_width is // font_metrics::width('M', LyXFont(LyXFont::ALL_SANE)) // but this estimate might not be more accurate as the screen font // is different then the latex font. // Pixel values are scaled so that the ratio // between lengths and font sizes on the screen // is the same as on paper. double result = 0.0; switch (unit_) { case LyXLength::SP: // Scaled point: sp = 1/65536 pt result = zoom * dpi * val_ / (72.27 * 65536); // 4736286.7 break; case LyXLength::PT: // Point: 1 pt = 1/72.27 inch result = zoom * dpi * val_ / 72.27; // 72.27 break; case LyXLength::BP: // Big point: 1 bp = 1/72 inch result = zoom * dpi * val_ / 72; // 72 break; case LyXLength::DD: // Didot: 1157dd = 1238 pt? result = zoom * dpi * val_ / (72.27 / (0.376 * 2.845)); // 67.559735 break; case LyXLength::MM: // Millimeter: 1 mm = 1/25.4 inch result = zoom * dpi * val_ / 25.4; // 25.4 break; case LyXLength::PC: // Pica: 1 pc = 12 pt result = zoom * dpi * val_ / (72.27 / 12); // 6.0225 break; case LyXLength::CC: // Cicero: 1 cc = 12 dd result = zoom * dpi * val_ / (72.27 / (12 * 0.376 * 2.845)); // 5.6299779 break; case LyXLength::CM: // Centimeter: 1 cm = 1/2.54 inch result = zoom * dpi * val_ / 2.54; // 2.54 break; case LyXLength::IN: // Inch result = zoom * dpi * val_; break; case LyXLength::EX: // Ex: The height of an "x" // 0.4305 is the ration between 1ex and 1em in cmr10 result = val_ * em_width * 0.4305; break; case LyXLength::EM: // Em: The width of an "m" result = val_ * em_width; break; case LyXLength::MU: // math unit = 1/18em result = val_ * em_width / 18; break; case LyXLength::PCW: // Always % of workarea case LyXLength::PTW: case LyXLength::PLW: result = val_ * text_width / 100; break; case LyXLength::PPW: // paperwidth/textwidth is 1.7 for A4 paper with default margins result = val_ * text_width * 1.7 / 100; break; case LyXLength::PTH: result = val_ * text_width * 1.787 / 100; break; case LyXLength::PPH: result = val_ * text_width * 2.2 / 100; break; case LyXLength::UNIT_NONE: result = 0; // this cannot happen break; } return static_cast(result + ((result >= 0) ? 0.5 : -0.5)); } int LyXLength::inBP() const { // return any LyXLength value as a one with // the PostScript point, called bp (big points) double result = 0.0; switch (unit_) { case LyXLength::CM: // 1bp = 0.2835cm result = val_ * 28.346; break; case LyXLength::MM: // 1bp = 0.02835mm result = val_ * 2.8346; break; case LyXLength::IN: // 1pt = 1/72in result = val_ * 72.0; break; default: // no other than bp possible result = val_; break; } return static_cast(result + 0.5); } bool operator==(LyXLength const & l1, LyXLength const & l2) { return l1.value() == l2.value() && l1.unit() == l2.unit(); } bool operator!=(LyXLength const & l1, LyXLength const & l2) { return !(l1 == l2); }