1 // -*- C++ -*-
2 /**
3  * \file Length.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Matthias Ettrich
8  * \author Lars Gullik Bjønnes
9  * \author Jean-Marc Lasgouttes
10  * \author John Levon
11  *
12  * Full author contact details are available in file CREDITS.
13  */
14 
15 #ifndef LENGTH_H
16 #define LENGTH_H
17 
18 #include "support/strfwd.h"
19 
20 
21 namespace lyx {
22 
23 class MetricsBase;
24 
25 // Solaris/x86 version 9 and earlier define these
26 #undef PC
27 #undef SP
28 
29 /////////////////////////////////////////////////////////////////////
30 //
31 // Length
32 //
33 /////////////////////////////////////////////////////////////////////
34 
35 
36 /**
37  * Length - Represents latex length measurement
38  */
39 class Length {
40 public:
41 	/// length units
42 	enum UNIT {
43 		BP, ///< Big point (72bp = 1in), also PostScript point
44 		CC, ///< Cicero = 12dd = 4.531mm
45 		CM, ///< Centimeter = 10mm = 2.371pc
46 		DD, ///< Didot point = 1/72 of a French inch, = 0.376mm
47 		EM, ///< Width of capital "M" in current font.
48 		EX, ///< Height of a small "x" for the current font.
49 		IN, ///< Inch = 25.4mm = 72.27pt = 6.022pc
50 		MM, ///< Millimeter = 2.845pt
51 		MU, ///< Math unit (18mu = 1em) for positioning in math mode
52 		PC, ///< Pica = 12pt = 4.218mm
53 		PT, ///< Point = 1/72.27in = 0.351mm
54 		SP, ///< Scaled point (65536sp = 1pt) TeX's smallest unit.
55 		PTW, //< Percent of TextWidth
56 		PCW, //< Percent of ColumnWidth
57 		PPW, //< Percent of PageWidth
58 		PLW, //< Percent of LineWidth
59 		PTH, //< Percent of TextHeight          // Herbert 2002-05-16
60 		PPH, //< Percent of PaperHeight         // Herbert 2002-05-16
61 		BLS, //< Percent of BaselineSkip        // uwestoehr 2017-04-01
62 		UNIT_NONE ///< no unit
63 	};
64 
65 	///
66 	Length();
67 	///
68 	Length(double v, Length::UNIT u);
69 
70 	/// "data" must be a decimal number, followed by a unit
71 	explicit Length(std::string const & data);
72 
73 	///
74 	double value() const;
75 	///
76 	Length::UNIT unit() const;
77 	///
78 	void value(double);
79 	///
80 	void unit(Length::UNIT unit);
81 	///
82 	bool zero() const;
83 	///
84 	bool empty() const;
85 	/// return string representation
86 	std::string const asString() const;
87 	/// return string representation
88 	docstring const asDocstring() const;
89 	/// return string representation for LaTeX
90 	std::string const asLatexString() const;
91 	/// return string representation for HTML
92 	std::string const asHTMLString() const;
93 	/** return the on-screen size of this length.
94 	 *
95 	 *	If the second argument is not provided, then the unit EM will
96 	 *	only be approximated. It is better if possible to use
97 	 *	FontMetrics::em() to get this value.
98 	 */
99 	int inPixels(int text_width, int em_width = 0) const;
100 
101 	/** return the on-screen size of this length
102 	 *
103 	 *  This version of the function uses the current inset width as
104 	 *  width and the EM value of the current font.
105 	 */
106 	int inPixels(MetricsBase const &) const;
107 	/// return the value in Big Postscript points.
108 	/// Caution: Inaccurate for em, ex, mu and percent units.
109 	int inBP() const;
110 
111 	/// return the default unit (centimeter or inch)
112 	static UNIT defaultUnit();
113 
114 	friend bool isValidLength(std::string const & data, Length * result);
115 
116 private:
117 	/// Convert value to inch for text width and em width given in inch
118 	double inInch(double text_width, double em_width) const;
119 	///
120 	double val_;
121 	///
122 	Length::UNIT unit_;
123 };
124 
125 ///
126 bool operator==(Length const & l1, Length const & l2);
127 ///
128 bool operator!=(Length const & l1, Length const & l2);
129 /** Test whether \p data represents a valid length.
130  *
131  * \returns whether \p data is a valid length
132  * \param data Length in LyX format. Since the only difference between LyX
133  * and LaTeX format is the representation of length variables as units (e.g.
134  * \c text% vs. \c \\textwidth) you can actually use this function as well
135  * for testing LaTeX lengths as long as they only contain real units like pt.
136  * \param result Pointer to a Length variable. If \p result is not 0 and
137  * \p data is valid, the length represented by it is stored into \p result.
138  */
139 bool isValidLength(std::string const & data, Length * result = 0);
140 /// return the LyX name of the given unit number
141 char const * stringFromUnit(int unit);
142 
143 
144 /////////////////////////////////////////////////////////////////////
145 //
146 // GlueLength
147 //
148 /////////////////////////////////////////////////////////////////////
149 
150 class GlueLength {
151 public:
152 	///
GlueLength()153 	GlueLength() {}
154 	///
155 	explicit GlueLength(Length const & len);
156 	///
157 	GlueLength(Length const & len,
158 		      Length const & plus,
159 		      Length const & minus);
160 
161 	/** "data" must be a decimal number, followed by a unit, and
162 	  optional "glue" indicated by "+" and "-".  You may abbreviate
163 	  reasonably.  Examples:
164 	  1.2 cm  //  4mm +2pt  //  2cm -4mm +2mm  //  4+0.1-0.2cm
165 	  The traditional Latex format is also accepted, like
166 	  4cm plus 10pt minus 10pt */
167 	explicit GlueLength(std::string const & data);
168 
169 	///
170 	Length const & len() const;
171 	///
172 	Length const & plus() const;
173 	///
174 	Length const & minus() const;
175 
176 
177 	/// conversion
178 	std::string const asString() const;
179 	///
180 	std::string const asLatexString() const;
181 
182 	friend bool isValidGlueLength(std::string const & data,
183 				      GlueLength* result);
184 
185 private:
186 	/// the normal vlaue
187 	Length len_;
188 	/// extra stretch
189 	Length plus_;
190 	/// extra shrink
191 	Length minus_;
192 };
193 
194 ///
195 bool operator==(GlueLength const & l1, GlueLength const & l2);
196 ///
197 bool operator!=(GlueLength const & l1, GlueLength const & l2);
198 /** If "data" is valid, the length represented by it is
199     stored into "result", if that is not 0. */
200 bool isValidGlueLength(std::string const & data, GlueLength * result = 0);
201 
202 /// the number of units possible
203 extern int const num_units;
204 
205 /**
206  * array of unit names
207  *
208  * FIXME: I am not sure if "mu" should be possible to select (Lgb)
209  */
210 extern char const * const unit_name[];
211 extern char const * const unit_name_gui[];
212 
213 /// return the unit given a string representation such as "cm"
214 Length::UNIT unitFromString(std::string const & data);
215 
216 
217 } // namespace lyx
218 
219 #endif // LENGTH_H
220