#include "Language.h"
#include "LaTeXFeatures.h"
#include "LaTeXFonts.h"
-#include "Length.h"
#include "ModuleList.h"
#include "Font.h"
#include "Lexer.h"
#include "support/FileName.h"
#include "support/filetools.h"
#include "support/gettext.h"
+#include "support/Length.h"
#include "support/Messages.h"
#include "support/mutex.h"
#include "support/Package.h"
#include "Language.h"
#include "LaTeXFeatures.h"
#include "LayoutFile.h"
-#include "Length.h"
#include "Lexer.h"
#include "LyX.h"
#include "LyXAction.h"
#include "support/filetools.h"
#include "support/gettext.h"
#include "support/lassert.h"
+#include "support/Length.h"
#include "support/lstrings.h"
#include "support/lyxlib.h"
#include "support/Package.h"
+++ /dev/null
-/**
- * \file Length.cpp
- * 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 <config.h>
-
-#include "Length.h"
-#include "LyXRC.h"
-
-#include "support/debug.h"
-#include "support/docstream.h"
-#include "support/lstrings.h"
-#include "support/lyxlib.h"
-
-#include <sstream>
-#include <iomanip>
-
-using namespace std;
-using namespace lyx::support;
-
-namespace lyx {
-
-
-/////////////////////////////////////////////////////////////////////
-//
-// Length
-//
-/////////////////////////////////////////////////////////////////////
-
-Length::Length()
- : val_(0), unit_(Length::UNIT_NONE)
-{}
-
-
-Length::Length(double v, Length::UNIT u)
- : val_(v), unit_(u)
-{}
-
-
-Length::Length(string const & data)
- : val_(0), unit_(Length::UNIT_NONE)
-{
- Length tmp;
-
- if (!isValidLength(data, &tmp))
- return; // should raise an exception
-
- val_ = tmp.val_;
- unit_ = tmp.unit_;
-}
-
-
-string const Length::asString() const
-{
- ostringstream os;
- if (unit_ != UNIT_NONE)
- os << formatFPNumber(val_) << unit_name[unit_]; // setw?
- return os.str();
-}
-
-
-docstring const Length::asDocstring() const
-{
- odocstringstream os;
- if (unit_ != UNIT_NONE)
- os << from_ascii(formatFPNumber(val_))
- << from_ascii(unit_name[unit_]); // setw?
- return os.str();
-}
-
-
-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 << formatFPNumber(val_ / 100.0) << "\\textwidth";
- break;
- case PCW:
- os << formatFPNumber(val_ / 100.0) << "\\columnwidth";
- break;
- case PPW:
- os << formatFPNumber(val_ / 100.0) << "\\paperwidth";
- break;
- case PLW:
- os << formatFPNumber(val_ / 100.0) << "\\linewidth";
- break;
- case PTH:
- os << formatFPNumber(val_ / 100.0) << "\\textheight";
- break;
- case PPH:
- os << formatFPNumber(val_ / 100.0) << "\\paperheight";
- break;
- case BLS:
- os << formatFPNumber(val_ / 100.0) << "\\baselineskip";
- break;
- case UNIT_NONE:
- break;
- default:
- os << formatFPNumber(val_) << unit_name[unit_];
- break;
- }
- return os.str();
-}
-
-
-string const Length::asHTMLString() const
-{
- ostringstream os;
- switch (unit_) {
- case PT:
- case BP:
- case DD:
- // close enough
- os << formatFPNumber(val_) << "pt";
- break;
- case MM:
- case CM:
- case PC:
- case IN:
- case EX:
- case EM:
- os << formatFPNumber(val_) << unit_name[unit_];
- break;
- case CC:
- os << formatFPNumber(val_ / 12.0) << "pt";
- break;
- case MU:
- os << formatFPNumber(val_ / 18.0) << "em";
- break;
- case PTW:
- case PPW:
- case PLW:
- 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 << formatFPNumber(val_) << '%';
- break;
- case SP:
- case UNIT_NONE:
- break;
- }
- return os.str();
-}
-
-
-double Length::value() const
-{
- return val_;
-}
-
-
-Length::UNIT Length::unit() const
-{
- return unit_;
-}
-
-
-void Length::value(double v)
-{
- val_ = v;
-}
-
-
-void Length::unit(Length::UNIT u)
-{
- unit_ = u;
-}
-
-
-bool Length::zero() const
-{
- return val_ == 0.0;
-}
-
-
-bool Length::empty() const
-{
- return unit_ == Length::UNIT_NONE;
-}
-
-
-int Length::inPixels(int text_width, int em_width_base) const
-{
- // Zoom factor specified by user in 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_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)).em()
- // 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 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 = val_ / (72.27 * 65536); // 4736286.7
- break;
- case Length::PT:
- // Point: 1 pt = 1/72.27 inch
- result = val_ / 72.27; // 72.27
- break;
- case Length::BP:
- // Big point: 1 bp = 1/72 inch
- result = val_ / 72; // 72
- break;
- case Length::DD:
- // Didot: 1157dd = 1238 pt?
- result = val_ / (72.27 / (0.376 * 2.845)); // 67.559735
- break;
- case Length::MM:
- // Millimeter: 1 mm = 1/25.4 inch
- result = val_ / 25.4; // 25.4
- break;
- case Length::PC:
- // Pica: 1 pc = 12 pt
- result = val_ / (72.27 / 12); // 6.0225
- break;
- case Length::CC:
- // Cicero: 1 cc = 12 dd
- result = val_
- / (72.27 / (12 * 0.376 * 2.845)); // 5.6299779
- break;
- case Length::CM:
- // Centimeter: 1 cm = 1/2.54 inch
- result = val_ / 2.54; // 2.54
- break;
- case Length::IN:
- // Inch
- result = val_;
- break;
- case Length::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 Length::EM:
- // Em: The width of an "m"
- result = val_ * em_width;
- break;
- case Length::MU:
- // math unit = 1/18em
- result = val_ * em_width / 18;
- break;
- case Length::PCW: // Always % of workarea
- case Length::PTW:
- case Length::PLW:
- result = val_ * text_width / 100;
- break;
- case Length::PPW:
- // paperwidth/textwidth is 1.7 for A4 paper with default margins
- result = val_ * text_width * 1.7 / 100;
- break;
- case Length::PTH:
- result = val_ * text_width * 1.787 / 100;
- break;
- 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 result;
-}
-
-
-int Length::inBP() const
-{
- // return any Length value as a one with
- // the PostScript point, called bp (big points)
-
- double const text_width_in = 210.0 / 2.54; // assume A4
- double const em_width_in = 10.0 / 72.27;
- double const result = 72.0 * inInch(text_width_in, em_width_in);
- return support::iround(result);
-}
-
-
-Length::UNIT Length::defaultUnit()
-{
- return lyxrc.default_length_unit;
-}
-
-
-
-bool operator==(Length const & l1, Length const & l2)
-{
- return l1.value() == l2.value() && l1.unit() == l2.unit();
-}
-
-
-bool operator!=(Length const & l1, Length const & l2)
-{
- return !(l1 == l2);
-}
-
-
-/////////////////////////////////////////////////////////////////////
-//
-// GlueLength
-//
-/////////////////////////////////////////////////////////////////////
-
-
-GlueLength::GlueLength(Length const & len)
- : len_(len)
-{}
-
-
-GlueLength::GlueLength(Length const & len, Length const & plus,
- Length const & minus)
- : len_(len), plus_(plus), minus_(minus)
-{}
-
-
-GlueLength::GlueLength(string const & data)
-{
- if (!isValidGlueLength(data, this))
- LYXERR0("Invalid glue length " + data);
-}
-
-
-string const GlueLength::asString() const
-{
- if (len_.empty())
- return string();
-
- ostringstream buffer;
-
- buffer << formatFPNumber(len_.value());
-
- if (plus_.zero() && minus_.zero()) {
- buffer << unit_name[len_.unit()];
- return buffer.str();
- }
-
- // just len and plus
- if (minus_.zero()) {
- if (len_.unit() != plus_.unit())
- buffer << unit_name[len_.unit()];
- buffer << '+' << formatFPNumber(plus_.value());
- buffer << unit_name[plus_.unit()];
- return buffer.str();
- }
-
- // just len and minus
- if (plus_.zero()) {
- if (len_.unit() != minus_.unit())
- buffer << unit_name[len_.unit()];
- buffer << '-' << formatFPNumber(minus_.value());
- buffer << unit_name[minus_.unit()];
- return buffer.str();
- }
-
- // ok, len, plus AND minus
-
- // len+-
- if (minus_ == plus_) {
- if (len_.unit() != minus_.unit())
- buffer << unit_name[len_.unit()];
- buffer << "+-" << formatFPNumber(minus_.value());
- buffer << unit_name[minus_.unit()];
- return buffer.str();
- }
-
- // this is so rare a case, why bother minimising units ?
-
- buffer << unit_name[len_.unit()];
- buffer << '+' << formatFPNumber(plus_.value()) << unit_name[plus_.unit()];
- buffer << '-' << formatFPNumber(minus_.value()) << unit_name[minus_.unit()];
-
- return buffer.str();
-}
-
-
-string const GlueLength::asLatexString() const
-{
- ostringstream buffer;
- // use Length::asLatexString() to handle also the percent lengths
- buffer << len_.Length::asLatexString();
- if (!plus_.zero())
- buffer << " plus " << plus_.Length::asLatexString();
- if (!minus_.zero())
- buffer << " minus " << minus_.Length::asLatexString();
- return buffer.str();
-}
-
-
-Length const & GlueLength::len() const
-{
- return len_;
-}
-
-
-Length const & GlueLength::plus() const
-{
- return plus_;
-}
-
-
-Length const & GlueLength::minus() const
-{
- return minus_;
-}
-
-
-bool operator==(GlueLength const & l1, GlueLength const & l2)
-{
- return l1.len() == l2.len()
- && l1.plus() == l2.plus()
- && l1.minus() == l2.minus();
-}
-
-
-bool operator!=(GlueLength const & l1, GlueLength const & l2)
-{
- return !(l1 == l2);
-}
-
-
-} // namespace lyx
+++ /dev/null
-// -*- C++ -*-
-/**
- * \file Length.h
- * 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 John Levon
- *
- * Full author contact details are available in file CREDITS.
- */
-
-#ifndef LENGTH_H
-#define LENGTH_H
-
-#include "support/strfwd.h"
-
-
-namespace lyx {
-
-// Solaris/x86 version 9 and earlier define these
-#undef PC
-#undef SP
-
-/////////////////////////////////////////////////////////////////////
-//
-// Length
-//
-/////////////////////////////////////////////////////////////////////
-
-
-/**
- * Length - Represents latex length measurement
- */
-class Length {
-public:
- /// length units
- enum UNIT {
- BP, ///< Big point (72bp = 1in), also PostScript point
- CC, ///< Cicero = 12dd = 4.531mm
- CM, ///< Centimeter = 10mm = 2.371pc
- DD, ///< Didot point = 1/72 of a French inch, = 0.376mm
- EM, ///< Width of capital "M" in current font.
- EX, ///< Height of a small "x" for the current font.
- IN, ///< Inch = 25.4mm = 72.27pt = 6.022pc
- MM, ///< Millimeter = 2.845pt
- MU, ///< Math unit (18mu = 1em) for positioning in math mode
- PC, ///< Pica = 12pt = 4.218mm
- PT, ///< Point = 1/72.27in = 0.351mm
- SP, ///< Scaled point (65536sp = 1pt) TeX's smallest unit.
- PTW, //< Percent of TextWidth
- PCW, //< Percent of ColumnWidth
- PPW, //< Percent of PageWidth
- PLW, //< Percent of LineWidth
- PTH, //< Percent of TextHeight // Herbert 2002-05-16
- PPH, //< Percent of PaperHeight // Herbert 2002-05-16
- BLS, //< Percent of BaselineSkip // uwestoehr 2017-04-01
- UNIT_NONE ///< no unit
- };
-
- ///
- Length();
- ///
- Length(double v, Length::UNIT u);
-
- /// "data" must be a decimal number, followed by a unit
- explicit Length(std::string const & data);
-
- ///
- double value() const;
- ///
- Length::UNIT unit() const;
- ///
- void value(double);
- ///
- void unit(Length::UNIT unit);
- ///
- bool zero() const;
- ///
- bool empty() const;
- /// return string representation
- std::string const asString() const;
- /// return string representation
- docstring const asDocstring() const;
- /// return string representation for LaTeX
- std::string const asLatexString() const;
- /// return string representation for HTML
- std::string const asHTMLString() const;
- /** return the on-screen size of this length.
- *
- * If the second argument is not provided, then the unit EM will
- * only be approximated. It is better if possible to use
- * FontMetrics::em() to get this value.
- */
- int inPixels(int text_width, int em_width = 0) const;
-
- /// return the value in Big Postscript points.
- /// Caution: Inaccurate for em, ex, mu and percent units.
- int inBP() const;
-
- /// return the default unit (centimeter or inch)
- static UNIT defaultUnit();
-
- friend bool isValidLength(std::string const & data, Length * result);
-
-private:
- /// Convert value to inch for text width and em width given in inch
- double inInch(double text_width, double em_width) const;
- ///
- double val_;
- ///
- Length::UNIT unit_;
-};
-
-///
-bool operator==(Length const & l1, Length const & l2);
-///
-bool operator!=(Length const & l1, Length const & l2);
-/** Test whether \p data represents a valid length.
- *
- * \returns whether \p data is a valid length
- * \param data Length in LyX format. Since the only difference between LyX
- * and LaTeX format is the representation of length variables as units (e.g.
- * \c text% vs. \c \\textwidth) you can actually use this function as well
- * for testing LaTeX lengths as long as they only contain real units like pt.
- * \param result Pointer to a Length variable. If \p result is not 0 and
- * \p data is valid, the length represented by it is stored into \p result.
- */
-bool isValidLength(std::string const & data, Length * result = 0);
-/// return the LyX name of the given unit number
-char const * stringFromUnit(int unit);
-
-
-/////////////////////////////////////////////////////////////////////
-//
-// GlueLength
-//
-/////////////////////////////////////////////////////////////////////
-
-class GlueLength {
-public:
- ///
- GlueLength() {}
- ///
- explicit GlueLength(Length const & len);
- ///
- GlueLength(Length const & len,
- Length const & plus,
- Length const & minus);
-
- /** "data" must be a decimal number, followed by a unit, and
- optional "glue" indicated by "+" and "-". You may abbreviate
- reasonably. Examples:
- 1.2 cm // 4mm +2pt // 2cm -4mm +2mm // 4+0.1-0.2cm
- The traditional Latex format is also accepted, like
- 4cm plus 10pt minus 10pt */
- explicit GlueLength(std::string const & data);
-
- ///
- Length const & len() const;
- ///
- Length const & plus() const;
- ///
- Length const & minus() const;
-
-
- /// conversion
- std::string const asString() const;
- ///
- std::string const asLatexString() const;
-
- friend bool isValidGlueLength(std::string const & data,
- GlueLength* result);
-
-private:
- /// the normal vlaue
- Length len_;
- /// extra stretch
- Length plus_;
- /// extra shrink
- Length minus_;
-};
-
-///
-bool operator==(GlueLength const & l1, GlueLength const & l2);
-///
-bool operator!=(GlueLength const & l1, GlueLength const & l2);
-/** If "data" is valid, the length represented by it is
- stored into "result", if that is not 0. */
-bool isValidGlueLength(std::string const & data, GlueLength * result = 0);
-
-/// the number of units possible
-extern int const num_units;
-
-/**
- * array of unit names
- *
- * FIXME: I am not sure if "mu" should be possible to select (Lgb)
- */
-extern char const * const unit_name[];
-extern char const * const unit_name_gui[];
-
-/// return the unit given a string representation such as "cm"
-Length::UNIT unitFromString(std::string const & data);
-
-
-} // namespace lyx
-
-#endif // LENGTH_H
#ifndef LYXRC_H
#define LYXRC_H
-#include "Length.h"
#include "LyX.h"
+#include "support/Length.h"
#include "support/strfwd.h"
#include "support/userinfo.h"
LaTeXPackages.cpp \
LayoutFile.cpp \
LayoutModuleList.cpp \
- Length.cpp \
- lengthcommon.cpp \
Lexer.cpp \
LyX.cpp \
LyXAction.cpp \
LayoutEnums.h \
LayoutFile.h \
LayoutModuleList.h \
- Length.h \
Lexer.h \
LyXAction.h \
lyxfind.h \
tests/boost.cpp
check_ExternalTransforms_LYX_OBJS = \
graphics/GraphicsParams.o \
- insets/ExternalTransforms.o \
- Length.o \
- lengthcommon.o
+ insets/ExternalTransforms.o
check_Length_CPPFLAGS = $(AM_CPPFLAGS)
-check_Length_LDADD = $(check_Length_LYX_OBJS) $(TESTS_LIBS)
+check_Length_LDADD = $(TESTS_LIBS)
check_Length_LDFLAGS = $(QT_LDFLAGS) $(ADD_FRAMEWORKS)
check_Length_SOURCES = \
tests/check_Length.cpp \
tests/dummy_functions.cpp \
tests/boost.cpp
-check_Length_LYX_OBJS = \
- Length.o \
- lengthcommon.o
check_ListingsCaption_CPPFLAGS = $(AM_CPPFLAGS)
check_ListingsCaption_LDADD = $(check_ListingsCaption_LYX_OBJS) $(TESTS_LIBS)
#include "Language.h"
#include "LaTeXFeatures.h"
#include "Layout.h"
-#include "Length.h"
#include "Font.h"
#include "FontList.h"
#include "LyXRC.h"
#include "support/ExceptionMessage.h"
#include "support/gettext.h"
#include "support/lassert.h"
+#include "support/Length.h"
#include "support/lstrings.h"
#include "support/textutils.h"
#include "output_docbook.h"
#define PARAGRAPHPARAMETERS_H
#include "LayoutEnums.h"
-#include "Length.h"
#include "Spacing.h"
#include "support/debug.h"
#include "support/types.h"
#include "support/docstring.h"
+#include "support/Length.h"
namespace lyx {
#include "InsetList.h"
#include "Language.h"
#include "Layout.h"
-#include "Length.h"
#include "Lexer.h"
#include "lyxfind.h"
#include "LyXRC.h"
#include "support/docstream.h"
#include "support/gettext.h"
#include "support/lassert.h"
+#include "support/Length.h"
#include "support/lstrings.h"
#include "support/lyxalgo.h"
#include "support/lyxtime.h"
#include "BufferParams.h"
#include "BufferView.h"
#include "support/gettext.h"
-#include "Length.h"
#include "Text.h"
#include "TextMetrics.h" // for defaultRowHeight()
#include "support/convert.h"
+#include "support/Length.h"
#include "support/lstrings.h"
#include "support/lassert.h"
#ifndef VSPACE_H
#define VSPACE_H
-#include "Length.h"
+#include "support/Length.h"
namespace lyx {
#include "ColorCache.h"
#include "ColorSet.h"
#include "LengthCombo.h"
-#include "Length.h"
#include "qt_helpers.h"
#include "Validator.h"
#include "insets/InsetBox.h"
#include "support/gettext.h"
+#include "support/Length.h"
#include "support/lstrings.h"
#include <QComboBox>
#include "Buffer.h"
#include "FuncRequest.h"
#include "support/gettext.h"
-#include "Length.h"
#include "LyXRC.h"
#include "insets/ExternalSupport.h"
#include "support/convert.h"
#include "support/filetools.h"
+#include "support/Length.h"
#include "support/lstrings.h"
#include "support/lyxlib.h"
#include "support/os.h"
#include "Buffer.h"
#include "FuncRequest.h"
#include "LengthCombo.h"
-#include "Length.h"
#include "LyXRC.h"
#include "graphics/epstools.h"
#include "support/debug.h"
#include "support/filetools.h"
#include "support/gettext.h"
+#include "support/Length.h"
#include "support/lstrings.h"
#include "support/os.h"
#include "support/Package.h"
#include <QComboBox>
-#include "Length.h"
+#include "support/Length.h"
namespace lyx {
#ifndef VALIDATOR_H
#define VALIDATOR_H
-#include "Length.h"
#include "Dialog.h" // KernelDocType
+#include "support/Length.h"
+
#include <QValidator>
class QWidget;
#include "BufferParams.h"
#include "FloatList.h"
#include "Language.h"
-#include "Length.h"
#include "TextClass.h"
#include "support/convert.h"
#include "support/debug.h"
#include "support/gettext.h"
+#include "support/Length.h"
#include "support/lstrings.h"
#include "support/lyxalgo.h"
#include "support/os.h"
#define QTHELPERS_H
#include "ColorSet.h"
-#include "Length.h"
+#include "support/Length.h"
#include "support/qstring_helpers.h"
#include "support/filetools.h"
#include "qt_i18n.h"
#ifndef GRAPHICSPARAMS_H
#define GRAPHICSPARAMS_H
-#include "Length.h"
-
#include "support/FileName.h"
+#include "support/Length.h"
#include <string>
#include <iosfwd>
#ifndef EXTERNALTRANSFORMS_H
#define EXTERNALTRANSFORMS_H
-#include "Length.h"
-
#include "graphics/GraphicsParams.h"
+#include "support/Length.h"
#include "support/unique_ptr.h"
#include <boost/any.hpp>
#define INSETBOX_H
#include "InsetCollapsible.h"
-#include "Length.h"
+
+#include "support/Length.h"
namespace lyx {
#include "FuncStatus.h"
#include "InsetIterator.h"
#include "LaTeXFeatures.h"
-#include "Length.h"
#include "Lexer.h"
#include "MetricsInfo.h"
#include "Mover.h"
#include "support/ExceptionMessage.h"
#include "support/filetools.h"
#include "support/gettext.h"
+#include "support/Length.h"
#include "support/lyxlib.h"
#include "support/lstrings.h"
#include "support/os.h"
#include "LaTeXFeatures.h"
#include "Language.h"
#include "LayoutFile.h"
-#include "Length.h"
#include "LyXAction.h"
#include "LyXRC.h"
#include "LyXVC.h"
#include "support/FileName.h"
#include "support/filetools.h"
#include "support/gettext.h"
+#include "support/Length.h"
#include "support/Messages.h"
#include "support/lstrings.h"
#include "support/qstring_helpers.h"
#include "FuncRequest.h"
#include "FuncStatus.h"
#include "LaTeXFeatures.h"
-#include "Length.h"
#include "MetricsInfo.h"
#include "OutputParams.h"
#include "output_docbook.h"
#include "support/debug.h"
#include "support/docstream.h"
#include "support/gettext.h"
+#include "support/Length.h"
#include "support/lstrings.h"
#include <cstdlib>
#include "InsetListingsParams.h"
-#include "Length.h"
+#include "support/Length.h"
#include "Lexer.h"
#include "support/convert.h"
#include "InsetList.h"
#include "Language.h"
#include "LaTeXFeatures.h"
-#include "Length.h"
#include "LyX.h"
#include "OutputParams.h"
#include "xml.h"
#include "support/debug.h"
#include "support/docstream.h"
#include "support/gettext.h"
+#include "support/Length.h"
#include "support/lstrings.h"
using namespace std;
#include "FuncStatus.h"
#include "Language.h"
#include "LaTeXFeatures.h"
-#include "Length.h"
#include "Lexer.h"
#include "MetricsInfo.h"
#include "OutputParams.h"
#include "support/docstream.h"
#include "support/gettext.h"
#include "support/lassert.h"
+#include "support/Length.h"
#include "support/lstrings.h"
#include "frontends/Application.h"
#define INSET_SPACE_H
#include "Inset.h"
-#include "Length.h"
+
+#include "support/Length.h"
namespace lyx {
#define INSET_TABULAR_H
#include "InsetText.h"
-#include "Length.h"
+
+#include "support/Length.h"
#include <climits>
#include <iosfwd>
#define INSETWRAP_H
#include "InsetCaptionable.h"
-#include "Length.h"
+
+#include "support/Length.h"
namespace lyx {
+++ /dev/null
-/**
- * \file lengthcommon.cpp
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author Lars Gullik Bjønnes
- * \author Matthias Ettrich
- * \author John Levon
- *
- * Full author contact details are available in file CREDITS.
- */
-
-#include <config.h>
-
-#include "Length.h"
-
-#include "support/convert.h"
-#include "support/gettext.h"
-#include "support/lassert.h"
-#include "support/lstrings.h"
-
-using namespace std;
-using namespace lyx::support;
-
-
-namespace lyx {
-
-// I am not sure if "mu" should be possible to select (Lgb)
-
-// the latex units
-char const * const unit_name[] = {
- "bp", "cc", "cm", "dd", "em", "ex", "in", "mm", "mu",
- "pc", "pt", "sp",
- "text%", "col%", "page%", "line%",
- "theight%", "pheight%", "baselineskip%", "" };
-
-int const num_units = int(sizeof(unit_name) / sizeof(unit_name[0]) - 1);
-
-// the LyX gui units
-char const * const unit_name_gui[] = {
- N_("bp"), N_("cc[[unit of measure]]"), N_("cm"), N_("dd"), N_("em"),
- N_("ex"), N_("in[[unit of measure]]"), N_("mm"), N_("mu[[unit of measure]]"), N_("pc"),
- N_("pt"), N_("sp"), N_("Text Width %"),
- N_("Column Width %"), N_("Page Width %"), N_("Line Width %"),
- N_("Text Height %"), N_("Page Height %"), N_("Line Distance %"), "" };
-
-
-Length::UNIT unitFromString(string const & data)
-{
- int i = 0;
- while (i < num_units && data != unit_name[i])
- ++i;
- return static_cast<Length::UNIT>(i);
-}
-
-
-namespace {
-
-/// skip n characters of input
-inline void lyx_advance(string & data, size_t n)
-{
- data.erase(0, n);
-}
-
-
-/// return true when the input is at the end
-inline bool isEndOfData(string const & data)
-{
- return ltrim(data).empty();
-}
-
-
-/**
- * nextToken - return the next token in the input
- * @param data input string
- * @param number_index the current position in the number array
- * @param unit_index the current position in the unit array
- * @return a char representing the type of token returned
- *
- * The possible return values are :
- * + stretch indicator for glue length
- * - shrink indicator for glue length
- * n a numeric value (stored in number array)
- * u a unit type (stored in unit array)
- * E parse error
- */
-char nextToken(string & data, double * number, int & number_index,
- Length::UNIT * unit, int & unit_index)
-{
- data = ltrim(data);
-
- if (data.empty())
- return '\0';
-
- if (data[0] == '+') {
- lyx_advance(data, 1);
- return '+';
- }
-
- if (prefixIs(data, "plus")) {
- lyx_advance(data, 4);
- return '+';
- }
-
- if (data[0] == '-') {
- lyx_advance(data, 1);
- return '-';
- }
-
- if (prefixIs(data, "minus")) {
- lyx_advance(data, 5);
- return '-';
- }
-
- size_t i = data.find_first_not_of("0123456789.");
-
- if (i != 0) {
- if (number_index > 3)
- return 'E';
-
- string buffer;
-
- // we have found some number
- if (i == string::npos) {
- buffer = data;
- i = data.size() + 1;
- } else {
- buffer = data.substr(0, i);
- }
-
- lyx_advance(data, i);
-
- if (isStrDbl(buffer)) {
- number[number_index] = convert<double>(buffer);
- ++number_index;
- return 'n';
- }
- return 'E';
- }
-
- i = data.find_first_not_of("abcdefghijklmnopqrstuvwxyz%");
- if (i != 0) {
- if (unit_index > 3)
- return 'E';
-
- string buffer;
-
- // we have found some alphabetical string
- if (i == string::npos) {
- buffer = data;
- i = data.size() + 1;
- } else {
- buffer = data.substr(0, i);
- }
-
- // possibly we have "mmplus" string or similar
- if (buffer.size() > 5 &&
- (buffer.substr(2, 4) == string("plus") ||
- buffer.substr(2, 5) == string("minus")))
- {
- lyx_advance(data, 2);
- unit[unit_index] = unitFromString(buffer.substr(0, 2));
- } else {
- lyx_advance(data, i);
- unit[unit_index] = unitFromString(buffer);
- }
-
- if (unit[unit_index] != Length::UNIT_NONE) {
- ++unit_index;
- return 'u';
- }
- return 'E'; // Error
- }
- return 'E'; // Error
-}
-
-
-/// latex representation of a vspace
-struct LaTeXLength {
- char const * pattern;
- int plus_val_index;
- int minus_val_index;
- int plus_uni_index;
- int minus_uni_index;
-};
-
-
-/// the possible formats for a vspace string
-LaTeXLength table[] = {
- { "nu", 0, 0, 0, 0 },
- { "nu+nu", 2, 0, 2, 0 },
- { "nu+nu-nu", 2, 3, 2, 3 },
- { "nu+-nu", 2, 2, 2, 2 },
- { "nu-nu", 0, 2, 0, 2 },
- { "nu-nu+nu", 3, 2, 3, 2 },
- { "nu-+nu", 2, 2, 2, 2 },
- { "n+nu", 2, 0, 1, 0 },
- { "n+n-nu", 2, 3, 1, 1 },
- { "n+-nu", 2, 2, 1, 1 },
- { "n-nu", 0, 2, 0, 1 },
- { "n-n+nu", 3, 2, 1, 1 },
- { "n-+nu", 2, 2, 1, 1 },
- { "", 0, 0, 0, 0 } // sentinel, must be empty
-};
-
-
-} // namespace
-
-
-const char * stringFromUnit(int unit)
-{
- if (unit < 0 || unit > num_units)
- return nullptr;
- return unit_name[unit];
-}
-
-
-bool isValidGlueLength(string const & data, GlueLength * result)
-{
- // This parser is table-driven. First, it constructs a "pattern"
- // that describes the sequence of tokens in "data". For example,
- // "n-nu" means: number, minus sign, number, unit. As we go along,
- // numbers and units are stored into static arrays. Then, "pattern"
- // is searched in the "table". If it is found, the associated
- // table entries tell us which number and unit should go where
- // in the Length structure. Example: if "data" has the "pattern"
- // "nu+nu-nu", the associated table entries are "2, 3, 2, 3".
- // That means, "plus_val" is the second number that was seen
- // in the input, "minus_val" is the third number, and "plus_uni"
- // and "minus_uni" are the second and third units, respectively.
- // ("val" and "uni" are always the first items seen in "data".)
- // This is the most elegant solution I could find -- a straight-
- // forward approach leads to very long, tedious code that would be
- // much harder to understand and maintain. (AS)
-
- if (data.empty()) {
- if (result)
- *result = GlueLength();
- return true;
- }
- string buffer = ltrim(data);
-
- // To make isValidGlueLength recognize negative values as
- // the first number this little hack is needed:
- int val_sign = 1; // positive as default
- switch (buffer[0]) {
- case '-':
- lyx_advance(buffer, 1);
- val_sign = -1;
- break;
- case '+':
- lyx_advance(buffer, 1);
- break;
- default:
- break;
- }
- // end of hack
-
- // used to return numeric values in parsing vspace
- double number[4] = { 0, 0, 0, 0 };
- // used to return unit types in parsing vspace
- Length::UNIT unit[4] = {Length::UNIT_NONE, Length::UNIT_NONE,
- Length::UNIT_NONE, Length::UNIT_NONE};
- int number_index = 1; // entries at index 0 are sentinels
- int unit_index = 1; // entries at index 0 are sentinels
-
- // construct "pattern" from "data"
- size_t const pattern_max_size = 20;
- string pattern;
- while (!isEndOfData(buffer)) {
- if (pattern.size() > pattern_max_size)
- return false;
- char const c = nextToken(buffer, number, number_index, unit,
- unit_index);
- if (c == 'E')
- return false;
- pattern.push_back(c);
- }
-
- // search "pattern" in "table"
- size_t table_index = 0;
- while (pattern != table[table_index].pattern) {
- ++table_index;
- if (!*table[table_index].pattern)
- return false;
- }
-
- // Get the values from the appropriate places. If an index
- // is zero, the corresponding array value is zero or UNIT_NONE,
- // so we needn't check this.
- if (result) {
- result->len_.value (number[1] * val_sign);
- result->len_.unit (unit[1]);
- result->plus_.value (number[table[table_index].plus_val_index]);
- result->plus_.unit (unit [table[table_index].plus_uni_index]);
- result->minus_.value(number[table[table_index].minus_val_index]);
- result->minus_.unit (unit [table[table_index].minus_uni_index]);
- }
- return true;
-}
-
-
-bool isValidLength(string const & data, Length * result)
-{
- // This is a trimmed down version of isValidGlueLength.
- // The parser may seem overkill for lengths without
- // glue, but since we already have it, using it is
- // easier than writing something from scratch.
- if (data.empty()) {
- if (result)
- *result = Length();
- return true;
- }
-
- string buffer = data;
-
- // To make isValidLength recognize negative values
- // this little hack is needed:
- int val_sign = 1; // positive as default
- switch (buffer[0]) {
- case '-':
- lyx_advance(buffer, 1);
- val_sign = -1;
- break;
- case '+':
- lyx_advance(buffer, 1);
- // fall through
- default:
- // no action
- break;
- }
- // end of hack
-
- // used to return numeric values in parsing vspace
- double number[4] = { 0, 0, 0, 0 };
- // used to return unit types in parsing vspace
- Length::UNIT unit[4] = {Length::UNIT_NONE, Length::UNIT_NONE,
- Length::UNIT_NONE, Length::UNIT_NONE};
- int number_index = 1; // entries at index 0 are sentinels
- int unit_index = 1; // entries at index 0 are sentinels
-
- // construct "pattern" from "data"
- string pattern;
- while (!isEndOfData(buffer)) {
- if (pattern.size() > 2)
- return false;
- char const token = nextToken(buffer, number,
- number_index, unit, unit_index);
- if (token == 'E')
- return false;
- pattern += token;
- }
-
- // only the most basic pattern is accepted here
- if (pattern != "nu")
- return false;
-
- // It _was_ a correct length string.
- // Store away the values we found.
- if (result) {
- result->val_ = number[1] * val_sign;
- result->unit_ = unit[1];
- }
- return true;
-}
-
-} // namespace lyx
#define MATH_GRID_H
#include "InsetMathNest.h"
-#include "Length.h"
+
+#include "support/Length.h"
#include <map>
#define MATH_CHEATINSET_H
#include "InsetMath.h"
-#include "Length.h"
+
+#include "support/Length.h"
namespace lyx {
#define MATH_SPACEINSET_H
#include "InsetMath.h"
-#include "Length.h"
+
+#include "support/Length.h"
namespace lyx {
#ifndef MATH_XYMATRIX_H
#define MATH_XYMATRIX_H
-#include "Length.h"
#include "InsetMathGrid.h"
+#include "support/Length.h"
+
namespace lyx {
#include "InsetMathFont.h"
#include "InsetMathSymbol.h"
-#include "Length.h"
#include "MathData.h"
#include "MathFactory.h"
#include "MathParser.h"
#include "support/debug.h"
#include "support/docstream.h"
#include "support/lassert.h"
+#include "support/Length.h"
#include "support/lyxlib.h"
#include <map>
--- /dev/null
+/**
+ * \file Length.cpp
+ * 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 <config.h>
+
+#include "LyXRC.h"
+
+#include "support/debug.h"
+#include "support/docstream.h"
+#include "support/Length.h"
+#include "support/lstrings.h"
+#include "support/lyxlib.h"
+
+#include <sstream>
+#include <iomanip>
+
+using namespace std;
+using namespace lyx::support;
+
+namespace lyx {
+
+
+/////////////////////////////////////////////////////////////////////
+//
+// Length
+//
+/////////////////////////////////////////////////////////////////////
+
+Length::Length()
+ : val_(0), unit_(Length::UNIT_NONE)
+{}
+
+
+Length::Length(double v, Length::UNIT u)
+ : val_(v), unit_(u)
+{}
+
+
+Length::Length(string const & data)
+ : val_(0), unit_(Length::UNIT_NONE)
+{
+ Length tmp;
+
+ if (!isValidLength(data, &tmp))
+ return; // should raise an exception
+
+ val_ = tmp.val_;
+ unit_ = tmp.unit_;
+}
+
+
+string const Length::asString() const
+{
+ ostringstream os;
+ if (unit_ != UNIT_NONE)
+ os << formatFPNumber(val_) << unit_name[unit_]; // setw?
+ return os.str();
+}
+
+
+docstring const Length::asDocstring() const
+{
+ odocstringstream os;
+ if (unit_ != UNIT_NONE)
+ os << from_ascii(formatFPNumber(val_))
+ << from_ascii(unit_name[unit_]); // setw?
+ return os.str();
+}
+
+
+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 << formatFPNumber(val_ / 100.0) << "\\textwidth";
+ break;
+ case PCW:
+ os << formatFPNumber(val_ / 100.0) << "\\columnwidth";
+ break;
+ case PPW:
+ os << formatFPNumber(val_ / 100.0) << "\\paperwidth";
+ break;
+ case PLW:
+ os << formatFPNumber(val_ / 100.0) << "\\linewidth";
+ break;
+ case PTH:
+ os << formatFPNumber(val_ / 100.0) << "\\textheight";
+ break;
+ case PPH:
+ os << formatFPNumber(val_ / 100.0) << "\\paperheight";
+ break;
+ case BLS:
+ os << formatFPNumber(val_ / 100.0) << "\\baselineskip";
+ break;
+ case UNIT_NONE:
+ break;
+ default:
+ os << formatFPNumber(val_) << unit_name[unit_];
+ break;
+ }
+ return os.str();
+}
+
+
+string const Length::asHTMLString() const
+{
+ ostringstream os;
+ switch (unit_) {
+ case PT:
+ case BP:
+ case DD:
+ // close enough
+ os << formatFPNumber(val_) << "pt";
+ break;
+ case MM:
+ case CM:
+ case PC:
+ case IN:
+ case EX:
+ case EM:
+ os << formatFPNumber(val_) << unit_name[unit_];
+ break;
+ case CC:
+ os << formatFPNumber(val_ / 12.0) << "pt";
+ break;
+ case MU:
+ os << formatFPNumber(val_ / 18.0) << "em";
+ break;
+ case PTW:
+ case PPW:
+ case PLW:
+ 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 << formatFPNumber(val_) << '%';
+ break;
+ case SP:
+ case UNIT_NONE:
+ break;
+ }
+ return os.str();
+}
+
+
+double Length::value() const
+{
+ return val_;
+}
+
+
+Length::UNIT Length::unit() const
+{
+ return unit_;
+}
+
+
+void Length::value(double v)
+{
+ val_ = v;
+}
+
+
+void Length::unit(Length::UNIT u)
+{
+ unit_ = u;
+}
+
+
+bool Length::zero() const
+{
+ return val_ == 0.0;
+}
+
+
+bool Length::empty() const
+{
+ return unit_ == Length::UNIT_NONE;
+}
+
+
+int Length::inPixels(int text_width, int em_width_base) const
+{
+ // Zoom factor specified by user in 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_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)).em()
+ // 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 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 = val_ / (72.27 * 65536); // 4736286.7
+ break;
+ case Length::PT:
+ // Point: 1 pt = 1/72.27 inch
+ result = val_ / 72.27; // 72.27
+ break;
+ case Length::BP:
+ // Big point: 1 bp = 1/72 inch
+ result = val_ / 72; // 72
+ break;
+ case Length::DD:
+ // Didot: 1157dd = 1238 pt?
+ result = val_ / (72.27 / (0.376 * 2.845)); // 67.559735
+ break;
+ case Length::MM:
+ // Millimeter: 1 mm = 1/25.4 inch
+ result = val_ / 25.4; // 25.4
+ break;
+ case Length::PC:
+ // Pica: 1 pc = 12 pt
+ result = val_ / (72.27 / 12); // 6.0225
+ break;
+ case Length::CC:
+ // Cicero: 1 cc = 12 dd
+ result = val_
+ / (72.27 / (12 * 0.376 * 2.845)); // 5.6299779
+ break;
+ case Length::CM:
+ // Centimeter: 1 cm = 1/2.54 inch
+ result = val_ / 2.54; // 2.54
+ break;
+ case Length::IN:
+ // Inch
+ result = val_;
+ break;
+ case Length::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 Length::EM:
+ // Em: The width of an "m"
+ result = val_ * em_width;
+ break;
+ case Length::MU:
+ // math unit = 1/18em
+ result = val_ * em_width / 18;
+ break;
+ case Length::PCW: // Always % of workarea
+ case Length::PTW:
+ case Length::PLW:
+ result = val_ * text_width / 100;
+ break;
+ case Length::PPW:
+ // paperwidth/textwidth is 1.7 for A4 paper with default margins
+ result = val_ * text_width * 1.7 / 100;
+ break;
+ case Length::PTH:
+ result = val_ * text_width * 1.787 / 100;
+ break;
+ 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 result;
+}
+
+
+int Length::inBP() const
+{
+ // return any Length value as a one with
+ // the PostScript point, called bp (big points)
+
+ double const text_width_in = 210.0 / 2.54; // assume A4
+ double const em_width_in = 10.0 / 72.27;
+ double const result = 72.0 * inInch(text_width_in, em_width_in);
+ return support::iround(result);
+}
+
+
+Length::UNIT Length::defaultUnit()
+{
+ return lyxrc.default_length_unit;
+}
+
+
+
+bool operator==(Length const & l1, Length const & l2)
+{
+ return l1.value() == l2.value() && l1.unit() == l2.unit();
+}
+
+
+bool operator!=(Length const & l1, Length const & l2)
+{
+ return !(l1 == l2);
+}
+
+
+/////////////////////////////////////////////////////////////////////
+//
+// GlueLength
+//
+/////////////////////////////////////////////////////////////////////
+
+
+GlueLength::GlueLength(Length const & len)
+ : len_(len)
+{}
+
+
+GlueLength::GlueLength(Length const & len, Length const & plus,
+ Length const & minus)
+ : len_(len), plus_(plus), minus_(minus)
+{}
+
+
+GlueLength::GlueLength(string const & data)
+{
+ if (!isValidGlueLength(data, this))
+ LYXERR0("Invalid glue length " + data);
+}
+
+
+string const GlueLength::asString() const
+{
+ if (len_.empty())
+ return string();
+
+ ostringstream buffer;
+
+ buffer << formatFPNumber(len_.value());
+
+ if (plus_.zero() && minus_.zero()) {
+ buffer << unit_name[len_.unit()];
+ return buffer.str();
+ }
+
+ // just len and plus
+ if (minus_.zero()) {
+ if (len_.unit() != plus_.unit())
+ buffer << unit_name[len_.unit()];
+ buffer << '+' << formatFPNumber(plus_.value());
+ buffer << unit_name[plus_.unit()];
+ return buffer.str();
+ }
+
+ // just len and minus
+ if (plus_.zero()) {
+ if (len_.unit() != minus_.unit())
+ buffer << unit_name[len_.unit()];
+ buffer << '-' << formatFPNumber(minus_.value());
+ buffer << unit_name[minus_.unit()];
+ return buffer.str();
+ }
+
+ // ok, len, plus AND minus
+
+ // len+-
+ if (minus_ == plus_) {
+ if (len_.unit() != minus_.unit())
+ buffer << unit_name[len_.unit()];
+ buffer << "+-" << formatFPNumber(minus_.value());
+ buffer << unit_name[minus_.unit()];
+ return buffer.str();
+ }
+
+ // this is so rare a case, why bother minimising units ?
+
+ buffer << unit_name[len_.unit()];
+ buffer << '+' << formatFPNumber(plus_.value()) << unit_name[plus_.unit()];
+ buffer << '-' << formatFPNumber(minus_.value()) << unit_name[minus_.unit()];
+
+ return buffer.str();
+}
+
+
+string const GlueLength::asLatexString() const
+{
+ ostringstream buffer;
+ // use Length::asLatexString() to handle also the percent lengths
+ buffer << len_.Length::asLatexString();
+ if (!plus_.zero())
+ buffer << " plus " << plus_.Length::asLatexString();
+ if (!minus_.zero())
+ buffer << " minus " << minus_.Length::asLatexString();
+ return buffer.str();
+}
+
+
+Length const & GlueLength::len() const
+{
+ return len_;
+}
+
+
+Length const & GlueLength::plus() const
+{
+ return plus_;
+}
+
+
+Length const & GlueLength::minus() const
+{
+ return minus_;
+}
+
+
+bool operator==(GlueLength const & l1, GlueLength const & l2)
+{
+ return l1.len() == l2.len()
+ && l1.plus() == l2.plus()
+ && l1.minus() == l2.minus();
+}
+
+
+bool operator!=(GlueLength const & l1, GlueLength const & l2)
+{
+ return !(l1 == l2);
+}
+
+
+} // namespace lyx
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file Length.h
+ * 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 John Levon
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef LENGTH_H
+#define LENGTH_H
+
+#include "support/strfwd.h"
+
+
+namespace lyx {
+
+// Solaris/x86 version 9 and earlier define these
+#undef PC
+#undef SP
+
+/////////////////////////////////////////////////////////////////////
+//
+// Length
+//
+/////////////////////////////////////////////////////////////////////
+
+
+/**
+ * Length - Represents latex length measurement
+ */
+class Length {
+public:
+ /// length units
+ enum UNIT {
+ BP, ///< Big point (72bp = 1in), also PostScript point
+ CC, ///< Cicero = 12dd = 4.531mm
+ CM, ///< Centimeter = 10mm = 2.371pc
+ DD, ///< Didot point = 1/72 of a French inch, = 0.376mm
+ EM, ///< Width of capital "M" in current font.
+ EX, ///< Height of a small "x" for the current font.
+ IN, ///< Inch = 25.4mm = 72.27pt = 6.022pc
+ MM, ///< Millimeter = 2.845pt
+ MU, ///< Math unit (18mu = 1em) for positioning in math mode
+ PC, ///< Pica = 12pt = 4.218mm
+ PT, ///< Point = 1/72.27in = 0.351mm
+ SP, ///< Scaled point (65536sp = 1pt) TeX's smallest unit.
+ PTW, //< Percent of TextWidth
+ PCW, //< Percent of ColumnWidth
+ PPW, //< Percent of PageWidth
+ PLW, //< Percent of LineWidth
+ PTH, //< Percent of TextHeight // Herbert 2002-05-16
+ PPH, //< Percent of PaperHeight // Herbert 2002-05-16
+ BLS, //< Percent of BaselineSkip // uwestoehr 2017-04-01
+ UNIT_NONE ///< no unit
+ };
+
+ ///
+ Length();
+ ///
+ Length(double v, Length::UNIT u);
+
+ /// "data" must be a decimal number, followed by a unit
+ explicit Length(std::string const & data);
+
+ ///
+ double value() const;
+ ///
+ Length::UNIT unit() const;
+ ///
+ void value(double);
+ ///
+ void unit(Length::UNIT unit);
+ ///
+ bool zero() const;
+ ///
+ bool empty() const;
+ /// return string representation
+ std::string const asString() const;
+ /// return string representation
+ docstring const asDocstring() const;
+ /// return string representation for LaTeX
+ std::string const asLatexString() const;
+ /// return string representation for HTML
+ std::string const asHTMLString() const;
+ /** return the on-screen size of this length.
+ *
+ * If the second argument is not provided, then the unit EM will
+ * only be approximated. It is better if possible to use
+ * FontMetrics::em() to get this value.
+ */
+ int inPixels(int text_width, int em_width = 0) const;
+
+ /// return the value in Big Postscript points.
+ /// Caution: Inaccurate for em, ex, mu and percent units.
+ int inBP() const;
+
+ /// return the default unit (centimeter or inch)
+ static UNIT defaultUnit();
+
+ friend bool isValidLength(std::string const & data, Length * result);
+
+private:
+ /// Convert value to inch for text width and em width given in inch
+ double inInch(double text_width, double em_width) const;
+ ///
+ double val_;
+ ///
+ Length::UNIT unit_;
+};
+
+///
+bool operator==(Length const & l1, Length const & l2);
+///
+bool operator!=(Length const & l1, Length const & l2);
+/** Test whether \p data represents a valid length.
+ *
+ * \returns whether \p data is a valid length
+ * \param data Length in LyX format. Since the only difference between LyX
+ * and LaTeX format is the representation of length variables as units (e.g.
+ * \c text% vs. \c \\textwidth) you can actually use this function as well
+ * for testing LaTeX lengths as long as they only contain real units like pt.
+ * \param result Pointer to a Length variable. If \p result is not 0 and
+ * \p data is valid, the length represented by it is stored into \p result.
+ */
+bool isValidLength(std::string const & data, Length * result = 0);
+/// return the LyX name of the given unit number
+char const * stringFromUnit(int unit);
+
+
+/////////////////////////////////////////////////////////////////////
+//
+// GlueLength
+//
+/////////////////////////////////////////////////////////////////////
+
+class GlueLength {
+public:
+ ///
+ GlueLength() {}
+ ///
+ explicit GlueLength(Length const & len);
+ ///
+ GlueLength(Length const & len,
+ Length const & plus,
+ Length const & minus);
+
+ /** "data" must be a decimal number, followed by a unit, and
+ optional "glue" indicated by "+" and "-". You may abbreviate
+ reasonably. Examples:
+ 1.2 cm // 4mm +2pt // 2cm -4mm +2mm // 4+0.1-0.2cm
+ The traditional Latex format is also accepted, like
+ 4cm plus 10pt minus 10pt */
+ explicit GlueLength(std::string const & data);
+
+ ///
+ Length const & len() const;
+ ///
+ Length const & plus() const;
+ ///
+ Length const & minus() const;
+
+
+ /// conversion
+ std::string const asString() const;
+ ///
+ std::string const asLatexString() const;
+
+ friend bool isValidGlueLength(std::string const & data,
+ GlueLength* result);
+
+private:
+ /// the normal vlaue
+ Length len_;
+ /// extra stretch
+ Length plus_;
+ /// extra shrink
+ Length minus_;
+};
+
+///
+bool operator==(GlueLength const & l1, GlueLength const & l2);
+///
+bool operator!=(GlueLength const & l1, GlueLength const & l2);
+/** If "data" is valid, the length represented by it is
+ stored into "result", if that is not 0. */
+bool isValidGlueLength(std::string const & data, GlueLength * result = 0);
+
+/// the number of units possible
+extern int const num_units;
+
+/**
+ * array of unit names
+ *
+ * FIXME: I am not sure if "mu" should be possible to select (Lgb)
+ */
+extern char const * const unit_name[];
+extern char const * const unit_name_gui[];
+
+/// return the unit given a string representation such as "cm"
+Length::UNIT unitFromString(std::string const & data);
+
+
+} // namespace lyx
+
+#endif // LENGTH_H
kill.cpp \
lassert.h \
lassert.cpp \
+ Length.cpp \
+ Length.h \
+ lengthcommon.cpp \
limited_stack.h \
lstrings.cpp \
lstrings.h \
--- /dev/null
+/**
+ * \file lengthcommon.cpp
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Lars Gullik Bjønnes
+ * \author Matthias Ettrich
+ * \author John Levon
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "support/convert.h"
+#include "support/gettext.h"
+#include "support/lassert.h"
+#include "support/Length.h"
+#include "support/lstrings.h"
+
+using namespace std;
+using namespace lyx::support;
+
+
+namespace lyx {
+
+// I am not sure if "mu" should be possible to select (Lgb)
+
+// the latex units
+char const * const unit_name[] = {
+ "bp", "cc", "cm", "dd", "em", "ex", "in", "mm", "mu",
+ "pc", "pt", "sp",
+ "text%", "col%", "page%", "line%",
+ "theight%", "pheight%", "baselineskip%", "" };
+
+int const num_units = int(sizeof(unit_name) / sizeof(unit_name[0]) - 1);
+
+// the LyX gui units
+char const * const unit_name_gui[] = {
+ N_("bp"), N_("cc[[unit of measure]]"), N_("cm"), N_("dd"), N_("em"),
+ N_("ex"), N_("in[[unit of measure]]"), N_("mm"), N_("mu[[unit of measure]]"), N_("pc"),
+ N_("pt"), N_("sp"), N_("Text Width %"),
+ N_("Column Width %"), N_("Page Width %"), N_("Line Width %"),
+ N_("Text Height %"), N_("Page Height %"), N_("Line Distance %"), "" };
+
+
+Length::UNIT unitFromString(string const & data)
+{
+ int i = 0;
+ while (i < num_units && data != unit_name[i])
+ ++i;
+ return static_cast<Length::UNIT>(i);
+}
+
+
+namespace {
+
+/// skip n characters of input
+inline void lyx_advance(string & data, size_t n)
+{
+ data.erase(0, n);
+}
+
+
+/// return true when the input is at the end
+inline bool isEndOfData(string const & data)
+{
+ return ltrim(data).empty();
+}
+
+
+/**
+ * nextToken - return the next token in the input
+ * @param data input string
+ * @param number_index the current position in the number array
+ * @param unit_index the current position in the unit array
+ * @return a char representing the type of token returned
+ *
+ * The possible return values are :
+ * + stretch indicator for glue length
+ * - shrink indicator for glue length
+ * n a numeric value (stored in number array)
+ * u a unit type (stored in unit array)
+ * E parse error
+ */
+char nextToken(string & data, double * number, int & number_index,
+ Length::UNIT * unit, int & unit_index)
+{
+ data = ltrim(data);
+
+ if (data.empty())
+ return '\0';
+
+ if (data[0] == '+') {
+ lyx_advance(data, 1);
+ return '+';
+ }
+
+ if (prefixIs(data, "plus")) {
+ lyx_advance(data, 4);
+ return '+';
+ }
+
+ if (data[0] == '-') {
+ lyx_advance(data, 1);
+ return '-';
+ }
+
+ if (prefixIs(data, "minus")) {
+ lyx_advance(data, 5);
+ return '-';
+ }
+
+ size_t i = data.find_first_not_of("0123456789.");
+
+ if (i != 0) {
+ if (number_index > 3)
+ return 'E';
+
+ string buffer;
+
+ // we have found some number
+ if (i == string::npos) {
+ buffer = data;
+ i = data.size() + 1;
+ } else {
+ buffer = data.substr(0, i);
+ }
+
+ lyx_advance(data, i);
+
+ if (isStrDbl(buffer)) {
+ number[number_index] = convert<double>(buffer);
+ ++number_index;
+ return 'n';
+ }
+ return 'E';
+ }
+
+ i = data.find_first_not_of("abcdefghijklmnopqrstuvwxyz%");
+ if (i != 0) {
+ if (unit_index > 3)
+ return 'E';
+
+ string buffer;
+
+ // we have found some alphabetical string
+ if (i == string::npos) {
+ buffer = data;
+ i = data.size() + 1;
+ } else {
+ buffer = data.substr(0, i);
+ }
+
+ // possibly we have "mmplus" string or similar
+ if (buffer.size() > 5 &&
+ (buffer.substr(2, 4) == string("plus") ||
+ buffer.substr(2, 5) == string("minus")))
+ {
+ lyx_advance(data, 2);
+ unit[unit_index] = unitFromString(buffer.substr(0, 2));
+ } else {
+ lyx_advance(data, i);
+ unit[unit_index] = unitFromString(buffer);
+ }
+
+ if (unit[unit_index] != Length::UNIT_NONE) {
+ ++unit_index;
+ return 'u';
+ }
+ return 'E'; // Error
+ }
+ return 'E'; // Error
+}
+
+
+/// latex representation of a vspace
+struct LaTeXLength {
+ char const * pattern;
+ int plus_val_index;
+ int minus_val_index;
+ int plus_uni_index;
+ int minus_uni_index;
+};
+
+
+/// the possible formats for a vspace string
+LaTeXLength table[] = {
+ { "nu", 0, 0, 0, 0 },
+ { "nu+nu", 2, 0, 2, 0 },
+ { "nu+nu-nu", 2, 3, 2, 3 },
+ { "nu+-nu", 2, 2, 2, 2 },
+ { "nu-nu", 0, 2, 0, 2 },
+ { "nu-nu+nu", 3, 2, 3, 2 },
+ { "nu-+nu", 2, 2, 2, 2 },
+ { "n+nu", 2, 0, 1, 0 },
+ { "n+n-nu", 2, 3, 1, 1 },
+ { "n+-nu", 2, 2, 1, 1 },
+ { "n-nu", 0, 2, 0, 1 },
+ { "n-n+nu", 3, 2, 1, 1 },
+ { "n-+nu", 2, 2, 1, 1 },
+ { "", 0, 0, 0, 0 } // sentinel, must be empty
+};
+
+
+} // namespace
+
+
+const char * stringFromUnit(int unit)
+{
+ if (unit < 0 || unit > num_units)
+ return nullptr;
+ return unit_name[unit];
+}
+
+
+bool isValidGlueLength(string const & data, GlueLength * result)
+{
+ // This parser is table-driven. First, it constructs a "pattern"
+ // that describes the sequence of tokens in "data". For example,
+ // "n-nu" means: number, minus sign, number, unit. As we go along,
+ // numbers and units are stored into static arrays. Then, "pattern"
+ // is searched in the "table". If it is found, the associated
+ // table entries tell us which number and unit should go where
+ // in the Length structure. Example: if "data" has the "pattern"
+ // "nu+nu-nu", the associated table entries are "2, 3, 2, 3".
+ // That means, "plus_val" is the second number that was seen
+ // in the input, "minus_val" is the third number, and "plus_uni"
+ // and "minus_uni" are the second and third units, respectively.
+ // ("val" and "uni" are always the first items seen in "data".)
+ // This is the most elegant solution I could find -- a straight-
+ // forward approach leads to very long, tedious code that would be
+ // much harder to understand and maintain. (AS)
+
+ if (data.empty()) {
+ if (result)
+ *result = GlueLength();
+ return true;
+ }
+ string buffer = ltrim(data);
+
+ // To make isValidGlueLength recognize negative values as
+ // the first number this little hack is needed:
+ int val_sign = 1; // positive as default
+ switch (buffer[0]) {
+ case '-':
+ lyx_advance(buffer, 1);
+ val_sign = -1;
+ break;
+ case '+':
+ lyx_advance(buffer, 1);
+ break;
+ default:
+ break;
+ }
+ // end of hack
+
+ // used to return numeric values in parsing vspace
+ double number[4] = { 0, 0, 0, 0 };
+ // used to return unit types in parsing vspace
+ Length::UNIT unit[4] = {Length::UNIT_NONE, Length::UNIT_NONE,
+ Length::UNIT_NONE, Length::UNIT_NONE};
+ int number_index = 1; // entries at index 0 are sentinels
+ int unit_index = 1; // entries at index 0 are sentinels
+
+ // construct "pattern" from "data"
+ size_t const pattern_max_size = 20;
+ string pattern;
+ while (!isEndOfData(buffer)) {
+ if (pattern.size() > pattern_max_size)
+ return false;
+ char const c = nextToken(buffer, number, number_index, unit,
+ unit_index);
+ if (c == 'E')
+ return false;
+ pattern.push_back(c);
+ }
+
+ // search "pattern" in "table"
+ size_t table_index = 0;
+ while (pattern != table[table_index].pattern) {
+ ++table_index;
+ if (!*table[table_index].pattern)
+ return false;
+ }
+
+ // Get the values from the appropriate places. If an index
+ // is zero, the corresponding array value is zero or UNIT_NONE,
+ // so we needn't check this.
+ if (result) {
+ result->len_.value (number[1] * val_sign);
+ result->len_.unit (unit[1]);
+ result->plus_.value (number[table[table_index].plus_val_index]);
+ result->plus_.unit (unit [table[table_index].plus_uni_index]);
+ result->minus_.value(number[table[table_index].minus_val_index]);
+ result->minus_.unit (unit [table[table_index].minus_uni_index]);
+ }
+ return true;
+}
+
+
+bool isValidLength(string const & data, Length * result)
+{
+ // This is a trimmed down version of isValidGlueLength.
+ // The parser may seem overkill for lengths without
+ // glue, but since we already have it, using it is
+ // easier than writing something from scratch.
+ if (data.empty()) {
+ if (result)
+ *result = Length();
+ return true;
+ }
+
+ string buffer = data;
+
+ // To make isValidLength recognize negative values
+ // this little hack is needed:
+ int val_sign = 1; // positive as default
+ switch (buffer[0]) {
+ case '-':
+ lyx_advance(buffer, 1);
+ val_sign = -1;
+ break;
+ case '+':
+ lyx_advance(buffer, 1);
+ // fall through
+ default:
+ // no action
+ break;
+ }
+ // end of hack
+
+ // used to return numeric values in parsing vspace
+ double number[4] = { 0, 0, 0, 0 };
+ // used to return unit types in parsing vspace
+ Length::UNIT unit[4] = {Length::UNIT_NONE, Length::UNIT_NONE,
+ Length::UNIT_NONE, Length::UNIT_NONE};
+ int number_index = 1; // entries at index 0 are sentinels
+ int unit_index = 1; // entries at index 0 are sentinels
+
+ // construct "pattern" from "data"
+ string pattern;
+ while (!isEndOfData(buffer)) {
+ if (pattern.size() > 2)
+ return false;
+ char const token = nextToken(buffer, number,
+ number_index, unit, unit_index);
+ if (token == 'E')
+ return false;
+ pattern += token;
+ }
+
+ // only the most basic pattern is accepted here
+ if (pattern != "nu")
+ return false;
+
+ // It _was_ a correct length string.
+ // Store away the values we found.
+ if (result) {
+ result->val_ = number[1] * val_sign;
+ result->unit_ = unit[1];
+ }
+ return true;
+}
+
+} // namespace lyx
set(check_ExternalTransforms_SOURCES)
foreach(_f graphics/GraphicsParams.cpp insets/ExternalTransforms.cpp
- Length.cpp lengthcommon.cpp tests/check_ExternalTransforms.cpp
+ tests/check_ExternalTransforms.cpp
tests/boost.cpp tests/dummy_functions.cpp)
list(APPEND check_ExternalTransforms_SOURCES ${TOP_SRC_DIR}/src/${_f})
endforeach()
add_dependencies(lyx_run_tests check_ExternalTransforms)
set(check_Length_SOURCES)
-foreach(_f Length.cpp lengthcommon.cpp tests/check_Length.cpp tests/boost.cpp tests/dummy_functions.cpp)
+foreach(_f tests/check_Length.cpp tests/boost.cpp tests/dummy_functions.cpp)
list(APPEND check_Length_SOURCES ${TOP_SRC_DIR}/src/${_f})
endforeach()
add_executable(check_Length ${check_Length_SOURCES})
project(${_tex2lyx})
-# There is no header file lengthcommon.h
-set(LINKED_sources ${TOP_SRC_DIR}/src/lengthcommon.cpp)
+set(LINKED_sources)
set(LINKED_headers)
foreach(_src graphics/GraphicsParams insets/ExternalTemplate
insets/ExternalTransforms insets/InsetLayout Author CiteEnginesList Color Counters
Encoding FloatList Floating FontInfo LaTeXPackages Layout
- LayoutFile LayoutModuleList Length Lexer ModuleList TextClass
+ LayoutFile LayoutModuleList Lexer ModuleList TextClass
Spacing version)
list(APPEND LINKED_sources ${TOP_SRC_DIR}/src/${_src}.cpp)
list(APPEND LINKED_headers ${TOP_SRC_DIR}/src/${_src}.h)
../Layout.o \
../LayoutFile.o \
../LayoutModuleList.o \
- ../Length.o \
- ../lengthcommon.o \
../Lexer.o \
../ModuleList.o \
../Spacing.o \
#include "FloatList.h"
#include "LaTeXPackages.h"
#include "Layout.h"
-#include "Length.h"
#include "Preamble.h"
#include "insets/ExternalTemplate.h"
#include "support/convert.h"
#include "support/FileName.h"
#include "support/filetools.h"
+#include "support/Length.h"
#include "support/lstrings.h"
#include "support/lyxtime.h"