X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FLength.cpp;h=a4d77f34ed041cbb049a20c858e2cddde8c94f25;hb=38c2cde0d8695ac5287bae218c4a33a2acf18ef8;hp=288a54de6230ec3661b3dc00d661d5a553db4765;hpb=306ebdf80b77570bfd87be39cf3c638b1bf92bfb;p=lyx.git diff --git a/src/Length.cpp b/src/Length.cpp index 288a54de62..a4d77f34ed 100644 --- a/src/Length.cpp +++ b/src/Length.cpp @@ -18,12 +18,16 @@ #include "Length.h" #include "LyXRC.h" +#include "support/debug.h" #include "support/docstream.h" +#include "support/lstrings.h" +#include "support/lyxlib.h" #include #include using namespace std; +using namespace lyx::support; namespace lyx { @@ -45,7 +49,7 @@ Length::Length(double v, Length::UNIT u) Length::Length(string const & data) - : val_(0), unit_(Length::PT) + : val_(0), unit_(Length::UNIT_NONE) { Length tmp; @@ -57,17 +61,11 @@ Length::Length(string const & data) } -void Length::swap(Length & rhs) -{ - std::swap(val_, rhs.val_); - std::swap(unit_, rhs.unit_); -} - - string const Length::asString() const { ostringstream os; - os << val_ << unit_name[unit_]; // setw? + if (unit_ != UNIT_NONE) + os << formatFPNumber(val_) << unit_name[unit_]; // setw? return os.str(); } @@ -75,7 +73,9 @@ string const Length::asString() const docstring const Length::asDocstring() const { odocstringstream os; - os << val_ << unit_name[unit_]; // setw? + if (unit_ != UNIT_NONE) + os << from_ascii(formatFPNumber(val_)) + << from_ascii(unit_name[unit_]); // setw? return os.str(); } @@ -83,27 +83,34 @@ docstring const Length::asDocstring() const string const Length::asLatexString() const { ostringstream os; + // Do not allow scientific notation (e.g. 1.2e+03), since this is not valid + // LaTeX (bug 9416) switch (unit_) { case PTW: - os << val_ / 100.0 << "\\textwidth"; + os << formatFPNumber(val_ / 100.0) << "\\textwidth"; break; case PCW: - os << val_ / 100.0 << "\\columnwidth"; + os << formatFPNumber(val_ / 100.0) << "\\columnwidth"; break; case PPW: - os << val_ / 100.0 << "\\paperwidth"; + os << formatFPNumber(val_ / 100.0) << "\\paperwidth"; break; case PLW: - os << val_ / 100.0 << "\\linewidth"; + os << formatFPNumber(val_ / 100.0) << "\\linewidth"; break; case PTH: - os << val_ / 100.0 << "\\textheight"; + os << formatFPNumber(val_ / 100.0) << "\\textheight"; break; case PPH: - os << val_ / 100.0 << "\\paperheight"; + os << formatFPNumber(val_ / 100.0) << "\\paperheight"; + break; + case BLS: + os << formatFPNumber(val_ / 100.0) << "\\baselineskip"; + break; + case UNIT_NONE: break; default: - os << val_ << unit_name[unit_]; + os << formatFPNumber(val_) << unit_name[unit_]; break; } return os.str(); @@ -118,7 +125,7 @@ string const Length::asHTMLString() const case BP: case DD: // close enough - os << val_ << "pt"; + os << formatFPNumber(val_) << "pt"; break; case MM: case CM: @@ -126,13 +133,13 @@ string const Length::asHTMLString() const case IN: case EX: case EM: - os << val_ << unit_name[unit_]; + os << formatFPNumber(val_) << unit_name[unit_]; break; case CC: - os << val_/12.0 << "pt"; + os << formatFPNumber(val_ / 12.0) << "pt"; break; case MU: - os << val_/18.0 << "em"; + os << formatFPNumber(val_ / 18.0) << "em"; break; case PTW: case PPW: @@ -140,9 +147,10 @@ string const Length::asHTMLString() const case PCW: case PTH: case PPH: + case BLS: // what it's a percentage of probably won't make sense for HTML, // so we'll assume people have chosen these appropriately - os << val_ << '%'; + os << formatFPNumber(val_) << '%'; break; case SP: case UNIT_NONE: @@ -191,16 +199,16 @@ bool Length::empty() const int Length::inPixels(int text_width, int em_width_base) const { // Zoom factor specified by user in percent - double const zoom = lyxrc.zoom / 100.0; // [percent] + double const zoom = lyxrc.currentZoom / 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; + double const em_width_in = (em_width_base > 0) + ? em_width_base / (zoom * dpi) + : 10.0/72.27; // A different estimate for em_width is - // theFontMetrics(FontInfo(sane_font)).width('M') + // theFontMetrics(FontInfo(sane_font)).em() // but this estimate might not be more accurate as the screen font // is different then the latex font. @@ -208,52 +216,53 @@ int Length::inPixels(int text_width, int em_width_base) const // between lengths and font sizes on the screen // is the same as on paper. + double const text_width_in = text_width / (zoom * dpi); + double const result = zoom * dpi * inInch(text_width_in, em_width_in); + return support::iround(result); +} + + +double Length::inInch(double text_width, double em_width) const +{ double result = 0.0; switch (unit_) { case Length::SP: // Scaled point: sp = 1/65536 pt - result = zoom * dpi * val_ - / (72.27 * 65536); // 4736286.7 + result = val_ / (72.27 * 65536); // 4736286.7 break; case Length::PT: // Point: 1 pt = 1/72.27 inch - result = zoom * dpi * val_ - / 72.27; // 72.27 + result = val_ / 72.27; // 72.27 break; case Length::BP: // Big point: 1 bp = 1/72 inch - result = zoom * dpi * val_ - / 72; // 72 + result = val_ / 72; // 72 break; case Length::DD: // Didot: 1157dd = 1238 pt? - result = zoom * dpi * val_ - / (72.27 / (0.376 * 2.845)); // 67.559735 + result = val_ / (72.27 / (0.376 * 2.845)); // 67.559735 break; case Length::MM: // Millimeter: 1 mm = 1/25.4 inch - result = zoom * dpi * val_ - / 25.4; // 25.4 + result = val_ / 25.4; // 25.4 break; case Length::PC: // Pica: 1 pc = 12 pt - result = zoom * dpi * val_ - / (72.27 / 12); // 6.0225 + result = val_ / (72.27 / 12); // 6.0225 break; case Length::CC: // Cicero: 1 cc = 12 dd - result = zoom * dpi * val_ + result = val_ / (72.27 / (12 * 0.376 * 2.845)); // 5.6299779 break; case Length::CM: // Centimeter: 1 cm = 1/2.54 inch - result = zoom * dpi * val_ - / 2.54; // 2.54 + result = val_ / 2.54; // 2.54 break; case Length::IN: // Inch - result = zoom * dpi * val_; + result = val_; break; case Length::EX: // Ex: The height of an "x" @@ -283,11 +292,17 @@ int Length::inPixels(int text_width, int em_width_base) const case Length::PPH: result = val_ * text_width * 2.2 / 100; break; + case Length::BLS: + // baselineskip is approximately 1.2 times the font size for the cmr fonts + // The value actually depends on the current paragraph (see TextMetrics::setRowHeight), + // but we do not have this information here. + result = val_ * em_width * 1.2 / 100; + break; case Length::UNIT_NONE: result = 0; // this cannot happen break; } - return static_cast(result + ((result >= 0) ? 0.5 : -0.5)); + return result; } @@ -295,45 +310,17 @@ int Length::inBP() const { // return any Length value as a one with // the PostScript point, called bp (big points) - double result = 0.0; - switch (unit_) { - case Length::CM: - // 1bp = 0.2835cm - result = val_ * 28.346; - break; - case Length::MM: - // 1bp = 0.02835mm - result = val_ * 2.8346; - break; - case Length::IN: - // 1pt = 1/72in - result = val_ * 72.0; - break; - default: - // no other than bp possible - result = val_; - break; - } - return static_cast(result + 0.5); + + double const text_width_in = 210.0 / 2.54; // assume A4 + double const em_width_in = 10.0 / 72.27; + double result = 72.0 * inInch(text_width_in, em_width_in); + return support::iround(result); } Length::UNIT Length::defaultUnit() { - // FIXME user a proper pref, since we should get rid of - // default_papersize in lyxrc. - UNIT u = Length::CM; - switch (lyxrc.default_papersize) { - case PAPER_USLETTER: - case PAPER_USLEGAL: - case PAPER_USEXECUTIVE: - u = Length::IN; - break; - default: - break; - } - - return u; + return lyxrc.default_length_unit; } @@ -370,15 +357,19 @@ GlueLength::GlueLength(Length const & len, Length const & plus, GlueLength::GlueLength(string const & data) { - isValidGlueLength(data, this); + if (!isValidGlueLength(data, this)) + LYXERR0("Invalid glue length " + data); } string const GlueLength::asString() const { + if (len_.empty()) + return string(); + ostringstream buffer; - buffer << len_.value(); + buffer << formatFPNumber(len_.value()); if (plus_.zero() && minus_.zero()) { buffer << unit_name[len_.unit()]; @@ -389,7 +380,7 @@ string const GlueLength::asString() const if (minus_.zero()) { if (len_.unit() != plus_.unit()) buffer << unit_name[len_.unit()]; - buffer << '+' << plus_.value(); + buffer << '+' << formatFPNumber(plus_.value()); buffer << unit_name[plus_.unit()]; return buffer.str(); } @@ -398,7 +389,7 @@ string const GlueLength::asString() const if (plus_.zero()) { if (len_.unit() != minus_.unit()) buffer << unit_name[len_.unit()]; - buffer << '-' << minus_.value(); + buffer << '-' << formatFPNumber(minus_.value()); buffer << unit_name[minus_.unit()]; return buffer.str(); } @@ -409,7 +400,7 @@ string const GlueLength::asString() const if (minus_ == plus_) { if (len_.unit() != minus_.unit()) buffer << unit_name[len_.unit()]; - buffer << "+-" << minus_.value(); + buffer << "+-" << formatFPNumber(minus_.value()); buffer << unit_name[minus_.unit()]; return buffer.str(); } @@ -417,8 +408,8 @@ string const GlueLength::asString() const // this is so rare a case, why bother minimising units ? buffer << unit_name[len_.unit()]; - buffer << '+' << plus_.value() << unit_name[plus_.unit()]; - buffer << '-' << minus_.value() << unit_name[minus_.unit()]; + buffer << '+' << formatFPNumber(plus_.value()) << unit_name[plus_.unit()]; + buffer << '-' << formatFPNumber(minus_.value()) << unit_name[minus_.unit()]; return buffer.str(); }