1
2 /******************************************************************************
3 * MODULE : evaluate_length.cpp
4 * DESCRIPTION: evaluation of lengths
5 * COPYRIGHT : (C) 2006 Joris van der Hoeven
6 *******************************************************************************
7 * This software falls under the GNU general public license version 3 or later.
8 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10 ******************************************************************************/
11
12 #include "evaluate_main.hpp"
13 #include "vars.hpp"
14 #include "analyze.hpp"
15 #include "font.hpp"
16 #include "gui.hpp"
17
18 /******************************************************************************
19 * Length arithmetic
20 ******************************************************************************/
21
22 bool
is_length(string s)23 is_length (string s) {
24 int i;
25 for (i=0; (i<N(s)) && ((s[i]<'a') || (s[i]>'z')); i++) {}
26 return is_double (s (0, i)) && is_locase_alpha (s (i, N(s)));
27 }
28
29 bool
is_length(tree t)30 is_length (tree t) {
31 return is_atomic (t) && is_length (t->label);
32 }
33
34 bool
is_anylen(tree t)35 is_anylen (tree t) {
36 return
37 (is_func (t, TMLEN) && ((N(t) == 1) || (N(t) == 3))) ||
38 (is_atomic (t) && is_length (t->label)) ||
39 is_func (t, MACRO, 1);
40 }
41
42 tree
tmlen_plus(tree t1,tree t2)43 tmlen_plus (tree t1, tree t2) {
44 if ((N(t1) == 1) && (N(t2) == 1))
45 return tree (TMLEN, as_string (as_double (t1[0]) + as_double (t2[0])));
46 if (N(t1) == 1) t1= tree (TMLEN, t1[0], t1[0], t1[0]);
47 if (N(t2) == 1) t2= tree (TMLEN, t2[0], t2[0], t2[0]);
48 tree _min= as_string (as_double (t1[0]) + as_double (t2[0]));
49 tree _def= as_string (as_double (t1[1]) + as_double (t2[1]));
50 tree _max= as_string (as_double (t1[2]) + as_double (t2[2]));
51 return tree (TMLEN, _min, _def, _max);
52 }
53
54 tree
tmlen_times(double sc,tree t)55 tmlen_times (double sc, tree t) {
56 if (N(t) == 1) return tree (TMLEN, as_string (sc * as_double (t[0])));
57 tree _min= as_string (sc * as_double (t[0]));
58 tree _def= as_string (sc * as_double (t[1]));
59 tree _max= as_string (sc * as_double (t[2]));
60 return tree (TMLEN, _min, _def, _max);
61 }
62
63 tree
tmlen_over(tree t1,tree t2)64 tmlen_over (tree t1, tree t2) {
65 t1= t1[N(t1)==1? 0: 1];
66 t2= t2[N(t2)==1? 0: 1];
67 return as_string (as_double (t1) / as_double (t2));
68 }
69
70 /******************************************************************************
71 * Decoding lengths
72 ******************************************************************************/
73
74 tree
as_tmlen(tree t)75 as_tmlen (tree t) {
76 if (is_func (t, TMLEN)) {
77 if (is_double (t[0])) return t;
78 if (N(t) < 3) return as_tmlen (t[0]);
79 tree _min= as_tmlen (t[0]);
80 tree _def= as_tmlen (t[1]);
81 tree _max= as_tmlen (t[2]);
82 _min= _min[N(_min) == 3? 1: 0];
83 _def= _def[N(_def) == 3? 1: 0];
84 _max= _max[N(_max) == 3? 1: 0];
85 return tree (TMLEN, _min, _def, _max);
86 }
87 else if (is_atomic (t)) {
88 string s= t->label;
89 int start= 0, i, n=N(s);
90 while ((start+1<n) && (s[start]=='-') && (s[start+1]=='-')) start += 2;
91 for (i=start; (i<n) && ((s[i]<'a') || (s[i]>'z')); i++) {}
92 string s1= s (start, i);
93 string s2= s (i, n);
94 if (!(is_double (s1) && is_locase_alpha (s2))) return tree (TMLEN, "0");
95 return tmlen_times (as_double (s1),
96 as_tmlen (evaluate (compound (s2 * "-length"))));
97 }
98 else if (is_func (t, MACRO, 1))
99 return as_tmlen (evaluate (t[0]));
100 else return tree (TMLEN, "0");
101 }
102
103 SI
as_length(string l)104 as_length (string l) {
105 tree r= as_tmlen (l);
106 string s= r[N(r)==1? 0: 1]->label;
107 return (SI) (as_double (s));
108 }
109
110 SI
as_length(tree t)111 as_length (tree t) {
112 tree r= as_tmlen (t);
113 string s= r[N(r)==1? 0: 1]->label;
114 return (SI) (as_double (s));
115 }
116
117 /******************************************************************************
118 * Get environment variables
119 ******************************************************************************/
120
std_inch()121 inline SI std_inch () {
122 return (SI) ((double) as_int (std_env [DPI]) * PIXEL); }
std_zoom()123 inline double std_zoom () {
124 return as_double (std_env [ZOOM_FACTOR]); }
std_dpi()125 inline int std_dpi () {
126 return as_int (std_env [DPI]); }
std_magnification()127 inline double std_magnification () {
128 return as_double (std_env [MAGNIFICATION]); }
std_font_base_size()129 inline int std_font_base_size () {
130 return as_int (std_env [FONT_BASE_SIZE]); }
std_font_size()131 inline double std_font_size () {
132 return as_double (std_env [FONT_SIZE]); }
std_math_level()133 inline int std_math_level () {
134 return as_int (std_env [MATH_LEVEL]); }
135
std_mode()136 inline int std_mode () {
137 string s= as_string (std_env [MODE]);
138 if (s == "text") return 1;
139 else if (s == "math") return 2;
140 else if (s == "prog") return 3;
141 else return 0; }
142
143 font
std_fn()144 std_fn () {
145 int fs= (int) ((std_font_base_size () + 0.5) * std_font_size ());
146 switch (std_mode ()) {
147 case 0:
148 case 1:
149 return smart_font (as_string (std_env [FONT]),
150 as_string (std_env [FONT_FAMILY]),
151 as_string (std_env [FONT_SERIES]),
152 as_string (std_env [FONT_SHAPE]),
153 script (fs, std_math_level ()),
154 (int) (std_magnification () * std_dpi ()));
155 case 2:
156 return smart_font (as_string (std_env [MATH_FONT]),
157 as_string (std_env [MATH_FONT_FAMILY]),
158 as_string (std_env [MATH_FONT_SERIES]),
159 as_string (std_env [MATH_FONT_SHAPE]),
160 as_string (std_env [FONT]),
161 as_string (std_env [FONT_FAMILY]),
162 as_string (std_env [FONT_SERIES]),
163 "mathitalic",
164 script (fs, std_math_level ()),
165 (int) (std_magnification () * std_dpi ()));
166 case 3:
167 return smart_font (as_string (std_env [PROG_FONT]),
168 as_string (std_env [PROG_FONT_FAMILY]),
169 as_string (std_env [PROG_FONT_SERIES]),
170 as_string (std_env [PROG_FONT_SHAPE]),
171 as_string (std_env [FONT]),
172 as_string (std_env [FONT_FAMILY]) * "-tt",
173 as_string (std_env [FONT_SERIES]),
174 as_string (std_env [FONT_SHAPE]),
175 script (fs, std_math_level ()),
176 (int) (std_magnification () * std_dpi ()));
177 default:
178 return get_default_font ();
179 }
180 }
181
182 /******************************************************************************
183 * Universal length units
184 ******************************************************************************/
185
evaluate_cm_length()186 tree evaluate_cm_length () {
187 return tree (TMLEN, as_string (std_inch() / 2.54)); }
evaluate_mm_length()188 tree evaluate_mm_length () {
189 return tree (TMLEN, as_string (std_inch() / 25.4)); }
evaluate_in_length()190 tree evaluate_in_length () {
191 return tree (TMLEN, as_string (std_inch())); }
evaluate_pt_length()192 tree evaluate_pt_length () {
193 return tree (TMLEN, as_string (std_inch() / 72.27)); }
evaluate_bp_length()194 tree evaluate_bp_length () {
195 return tree (TMLEN, as_string (std_inch() / 72.0)); }
evaluate_dd_length()196 tree evaluate_dd_length () {
197 return tree (TMLEN, as_string (0.376 * std_inch() / 25.4)); }
evaluate_pc_length()198 tree evaluate_pc_length () {
199 return tree (TMLEN, as_string (12.0 * std_inch() / 72.27)); }
evaluate_cc_length()200 tree evaluate_cc_length () {
201 return tree (TMLEN, as_string (4.531 * std_inch() / 25.4)); }
202
203 /******************************************************************************
204 * Environment-dependent length units
205 ******************************************************************************/
206
207 tree
evaluate_fs_length()208 evaluate_fs_length () {
209 double fs= (std_font_base_size () * std_magnification () *
210 std_inch () * std_font_size ()) / 72.0;
211 return tree (TMLEN, as_string (fs));
212 }
213
214 tree
evaluate_fbs_length()215 evaluate_fbs_length () {
216 double fbs= (std_font_base_size () * std_magnification () *
217 std_inch ()) / 72.0;
218 return tree (TMLEN, as_string (fbs));
219 }
220
evaluate_em_length()221 tree evaluate_em_length () {
222 return tree (TMLEN, as_string (std_fn()->wquad)); }
evaluate_ln_length()223 tree evaluate_ln_length () {
224 return tree (TMLEN, as_string (std_fn()->wline)); }
evaluate_sep_length()225 tree evaluate_sep_length () {
226 return tree (TMLEN, as_string (std_fn()->sep)); }
evaluate_yfrac_length()227 tree evaluate_yfrac_length () {
228 return tree (TMLEN, as_string (std_fn()->yfrac)); }
evaluate_ex_length()229 tree evaluate_ex_length () {
230 return tree (TMLEN, as_string (std_fn()->yx)); }
231
232 tree
evaluate_fn_length()233 evaluate_fn_length () {
234 double fs= (std_font_base_size () * std_magnification () *
235 std_inch () * std_font_size ()) / 72.0;
236 return tree (TMLEN, as_string (0.5*fs), as_string (fs), as_string (1.5*fs));
237 }
238
239 tree
evaluate_fns_length()240 evaluate_fns_length () {
241 double fs= (std_font_base_size () * std_magnification () *
242 std_inch () * std_font_size ()) / 72.0;
243 return tree (TMLEN, "0", "0", as_string (fs));
244 }
245
246 static space
as_vspace(tree t)247 as_vspace (tree t) {
248 tree r= as_tmlen (t);
249 if (N(r) == 1)
250 return space ((SI) (as_double (r[0]->label)));
251 else {
252 SI _min= (SI) as_double (r[0]->label);
253 SI _def= (SI) as_double (r[1]->label);
254 SI _max= (SI) as_double (r[2]->label);
255 double flexibility= as_double (std_env [PAGE_FLEXIBILITY]);
256 return space (_def + ((SI) (flexibility * (_min - _def))),
257 _def,
258 _def + ((SI) (flexibility * (_max - _def))));
259 }
260 }
261
262 tree
evaluate_bls_length()263 evaluate_bls_length () {
264 double fs= (std_font_base_size () * std_magnification () *
265 std_inch () * std_font_size ()) / 72.0;
266 return tmlen_plus (tree (TMLEN, as_string (fs)),
267 tree (as_vspace (std_env [PAR_SEP])));
268 }
269
270 tree
evaluate_fnbot_length()271 evaluate_fnbot_length () {
272 return tree (TMLEN, as_string (std_fn()->y1));
273 }
274
275 tree
evaluate_fntop_length()276 evaluate_fntop_length () {
277 return tree (TMLEN, as_string (std_fn()->y2));
278 }
279
280 tree
evaluate_spc_length()281 evaluate_spc_length () {
282 space spc= std_fn()->spc;
283 return tree (TMLEN,
284 as_string (spc->min),
285 as_string (spc->def),
286 as_string (spc->max));
287 }
288
289 tree
evaluate_xspc_length()290 evaluate_xspc_length () {
291 space spc= std_fn()->extra;
292 return tree (TMLEN,
293 as_string (spc->min),
294 as_string (spc->def),
295 as_string (spc->max));
296 }
297
298 tree
evaluate_par_length()299 evaluate_par_length () {
300 /*
301 SI width, d1, d2, d3, d4, d5, d6, d7;
302 get_page_pars (width, d1, d2, d3, d4, d5, d6, d7);
303 width -= (get_length (PAR_LEFT) + get_length (PAR_RIGHT));
304 return tree (TMLEN, as_string (width));
305 */
306 return tree (TMLEN, as_string (15 * std_inch() / 2.54)); // 15cm
307 }
308
309 tree
evaluate_pag_length()310 evaluate_pag_length () {
311 /*
312 SI d1, height, d2, d3, d4, d5, d6, d7;
313 get_page_pars (d1, height, d2, d3, d4, d5, d6, d7);
314 return tree (TMLEN, as_string (height));
315 */
316 return tree (TMLEN, as_string (23 * std_inch() / 2.54)); // 23cm
317 }
318
evaluate_tmpt_length()319 tree evaluate_tmpt_length () {
320 return tree (TMLEN, "1"); }
evaluate_px_length()321 tree evaluate_px_length () {
322 int px= (int) tm_round ((std_shrinkf * PIXEL) / std_zoom ());
323 return tree (TMLEN, as_string (px)); }
324
325 tree
evaluate_gw_length()326 evaluate_gw_length () {
327 //return tree (TMLEN, as_string (gw));
328 return tree (TMLEN, as_string (10 * std_inch() / 2.54)); // 10cm
329 }
330
331 tree
evaluate_gh_length()332 evaluate_gh_length () {
333 //return tree (TMLEN, as_string (gh));
334 return tree (TMLEN, as_string (6 * std_inch() / 2.54)); // 6cm
335 }
336
337 tree
evaluate_gu_length()338 evaluate_gu_length () {
339 // FIXME: not yet implemented
340 return evaluate_cm_length ();
341 //point p0= fr (point (0.0, 0.0));
342 //point p1= fr (point (1.0, 0.0));
343 //return tree (TMLEN, as_string (norm (p1 - p0)));
344 }
345
evaluate_msec_length()346 tree evaluate_msec_length () { return tree (TMLEN, "1"); }
evaluate_sec_length()347 tree evaluate_sec_length () { return tree (TMLEN, "1000"); }
evaluate_min_length()348 tree evaluate_min_length () { return tree (TMLEN, "60000"); }
evaluate_hr_length()349 tree evaluate_hr_length () { return tree (TMLEN, "3600000"); }
350