Back to index

texmacs  1.0.7.15
evaluate_length.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : evaluate_length.cpp
00004 * DESCRIPTION: evaluation of lengths
00005 * COPYRIGHT  : (C) 2006  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "evaluate_main.hpp"
00013 #include "vars.hpp"
00014 #include "analyze.hpp"
00015 #include "font.hpp"
00016 #include "gui.hpp"
00017 
00018 /******************************************************************************
00019 * Length arithmetic
00020 ******************************************************************************/
00021 
00022 bool
00023 is_length (string s) {
00024   int i;
00025   for (i=0; (i<N(s)) && ((s[i]<'a') || (s[i]>'z')); i++) {}
00026   return is_double (s (0, i)) && is_locase_alpha (s (i, N(s)));
00027 }
00028 
00029 bool
00030 is_length (tree t) {
00031   return is_atomic (t) && is_length (t->label);
00032 }
00033 
00034 bool
00035 is_anylen (tree t) {
00036   return
00037     (is_func (t, TMLEN) && ((N(t) == 1) || (N(t) == 3))) ||
00038     (is_atomic (t) && is_length (t->label)) ||
00039     is_func (t, MACRO, 1);
00040 }
00041 
00042 tree
00043 tmlen_plus (tree t1, tree t2) {
00044   if ((N(t1) == 1) && (N(t2) == 1))
00045     return tree (TMLEN, as_string (as_double (t1[0]) + as_double (t2[0])));
00046   if (N(t1) == 1) t1= tree (TMLEN, t1[0], t1[0], t1[0]);
00047   if (N(t2) == 1) t2= tree (TMLEN, t2[0], t2[0], t2[0]);
00048   tree _min= as_string (as_double (t1[0]) + as_double (t2[0]));
00049   tree _def= as_string (as_double (t1[1]) + as_double (t2[1]));
00050   tree _max= as_string (as_double (t1[2]) + as_double (t2[2]));
00051   return tree (TMLEN, _min, _def, _max);
00052 }
00053 
00054 tree
00055 tmlen_times (double sc, tree t) {
00056   if (N(t) == 1) return tree (TMLEN, as_string (sc * as_double (t[0])));
00057   tree _min= as_string (sc * as_double (t[0]));
00058   tree _def= as_string (sc * as_double (t[1]));
00059   tree _max= as_string (sc * as_double (t[2]));
00060   return tree (TMLEN, _min, _def, _max);
00061 }
00062 
00063 tree
00064 tmlen_over (tree t1, tree t2) {
00065   t1= t1[N(t1)==1? 0: 1];
00066   t2= t2[N(t2)==1? 0: 1];
00067   return as_string (as_double (t1) / as_double (t2));
00068 }
00069 
00070 /******************************************************************************
00071 * Decoding lengths
00072 ******************************************************************************/
00073 
00074 tree
00075 as_tmlen (tree t) {
00076   if (is_func (t, TMLEN)) {
00077     if (is_double (t[0])) return t;
00078     if (N(t) < 3) return as_tmlen (t[0]);
00079     tree _min= as_tmlen (t[0]);
00080     tree _def= as_tmlen (t[1]);
00081     tree _max= as_tmlen (t[2]);
00082     _min= _min[N(_min) == 3? 1: 0];
00083     _def= _def[N(_def) == 3? 1: 0];
00084     _max= _max[N(_max) == 3? 1: 0];
00085     return tree (TMLEN, _min, _def, _max);
00086   }
00087   else if (is_atomic (t)) {
00088     string s= t->label;
00089     int start= 0, i, n=N(s);
00090     while ((start+1<n) && (s[start]=='-') && (s[start+1]=='-')) start += 2;
00091     for (i=start; (i<n) && ((s[i]<'a') || (s[i]>'z')); i++) {}
00092     string s1= s (start, i);
00093     string s2= s (i, n);
00094     if (!(is_double (s1) && is_locase_alpha (s2))) return tree (TMLEN, "0");
00095     return tmlen_times (as_double (s1),
00096                      as_tmlen (evaluate (compound (s2 * "-length"))));
00097   }
00098   else if (is_func (t, MACRO, 1))
00099     return as_tmlen (evaluate (t[0]));
00100   else return tree (TMLEN, "0");
00101 }
00102 
00103 SI
00104 as_length (string l) {
00105   tree r= as_tmlen (l);
00106   string s= r[N(r)==1? 0: 1]->label;
00107   return (SI) (as_double (s));
00108 }
00109 
00110 SI
00111 as_length (tree t) {
00112   tree r= as_tmlen (t);
00113   string s= r[N(r)==1? 0: 1]->label;
00114   return (SI) (as_double (s));
00115 }
00116 
00117 /******************************************************************************
00118 * Get environment variables
00119 ******************************************************************************/
00120 
00121 inline SI std_inch () {
00122   return (SI) ((double) as_int (std_env [DPI]) * PIXEL); }
00123 inline int std_sfactor () {
00124   return as_int (std_env [SFACTOR]); }
00125 inline int std_dpi () {
00126   return as_int (std_env [DPI]); }
00127 inline double std_magnification () {
00128   return as_double (std_env [MAGNIFICATION]); }
00129 inline int std_font_base_size () {
00130   return as_int (std_env [FONT_BASE_SIZE]); }
00131 inline double std_font_size () {
00132   return as_double (std_env [FONT_SIZE]); }
00133 inline int std_math_level () {
00134   return as_int (std_env [MATH_LEVEL]); }
00135 
00136 inline int std_mode () {
00137   string s= as_string (std_env [MODE]);
00138   if (s == "text") return 1;
00139   else if (s == "math") return 2;
00140   else if (s == "prog") return 3;
00141   else return 0; }
00142 
00143 font
00144 std_fn () {
00145   int fs= (int) ((std_font_base_size () + 0.5) * std_font_size ());
00146   switch (std_mode ()) {
00147   case 0:
00148   case 1:
00149     return find_font (as_string (std_env [FONT]),
00150                     as_string (std_env [FONT_FAMILY]),
00151                     as_string (std_env [FONT_SERIES]),
00152                     as_string (std_env [FONT_SHAPE]),
00153                     script (fs, std_math_level ()),
00154                     (int) (std_magnification () * std_dpi ()));
00155   case 2:
00156     return find_font (as_string (std_env [MATH_FONT]),
00157                     as_string (std_env [MATH_FONT_FAMILY]),
00158                     as_string (std_env [MATH_FONT_SERIES]),
00159                     as_string (std_env [MATH_FONT_SHAPE]),
00160                     script (fs, std_math_level ()),
00161                     (int) (std_magnification () * std_dpi ()));
00162   case 3:
00163     return find_font (as_string (std_env [PROG_FONT]),
00164                     as_string (std_env [PROG_FONT_FAMILY]),
00165                     as_string (std_env [PROG_FONT_SERIES]),
00166                     as_string (std_env [PROG_FONT_SHAPE]),
00167                     script (fs, std_math_level ()),
00168                     (int) (std_magnification () * std_dpi ()));
00169   default:
00170     return get_default_font ();
00171   }
00172 }
00173 
00174 /******************************************************************************
00175 * Universal length units
00176 ******************************************************************************/
00177 
00178 tree evaluate_cm_length () {
00179   return tree (TMLEN, as_string (std_inch() / 2.54)); }
00180 tree evaluate_mm_length () {
00181   return tree (TMLEN, as_string (std_inch() / 25.4)); }
00182 tree evaluate_in_length () {
00183   return tree (TMLEN, as_string (std_inch())); }
00184 tree evaluate_pt_length () {
00185   return tree (TMLEN, as_string (std_inch() / 72.27)); }
00186 tree evaluate_bp_length () {
00187   return tree (TMLEN, as_string (std_inch() / 72.0)); }
00188 tree evaluate_dd_length () {
00189   return tree (TMLEN, as_string (0.376 * std_inch() / 25.4)); }
00190 tree evaluate_pc_length () {
00191   return tree (TMLEN, as_string (12.0 * std_inch() / 72.27)); }
00192 tree evaluate_cc_length () {
00193   return tree (TMLEN, as_string (4.531 * std_inch() / 25.4)); }
00194 
00195 /******************************************************************************
00196 * Environment-dependent length units
00197 ******************************************************************************/
00198 
00199 tree
00200 evaluate_fs_length () {
00201   double fs= (std_font_base_size () * std_magnification () *
00202              std_inch () * std_font_size ()) / 72.0;
00203   return tree (TMLEN, as_string (fs));
00204 }
00205 
00206 tree
00207 evaluate_fbs_length () {
00208   double fbs= (std_font_base_size () * std_magnification () *
00209               std_inch ()) / 72.0;
00210   return tree (TMLEN, as_string (fbs));
00211 }
00212 
00213 tree evaluate_em_length () {
00214   return tree (TMLEN, as_string (std_fn()->wquad)); }
00215 tree evaluate_ln_length () {
00216   return tree (TMLEN, as_string (std_fn()->wline)); }
00217 tree evaluate_sep_length () {
00218   return tree (TMLEN, as_string (std_fn()->sep)); }
00219 tree evaluate_yfrac_length () {
00220   return tree (TMLEN, as_string (std_fn()->yfrac)); }
00221 tree evaluate_ex_length () {
00222   return tree (TMLEN, as_string (std_fn()->yx)); }
00223 
00224 tree
00225 evaluate_fn_length () {
00226   double fs= (std_font_base_size () * std_magnification () *
00227              std_inch () * std_font_size ()) / 72.0;
00228   return tree (TMLEN, as_string (0.5*fs), as_string (fs), as_string (1.5*fs));
00229 }
00230 
00231 tree
00232 evaluate_fns_length () {
00233   double fs= (std_font_base_size () * std_magnification () *
00234              std_inch () * std_font_size ()) / 72.0;
00235   return tree (TMLEN, "0", "0", as_string (fs));
00236 }
00237 
00238 static space
00239 as_vspace (tree t) {
00240   tree r= as_tmlen (t);
00241   if (N(r) == 1)
00242     return space ((SI) (as_double (r[0]->label)));
00243   else {
00244     SI _min= (SI) as_double (r[0]->label);
00245     SI _def= (SI) as_double (r[1]->label);
00246     SI _max= (SI) as_double (r[2]->label);
00247     double flexibility= as_double (std_env [PAGE_FLEXIBILITY]);
00248     return space (_def + ((SI) (flexibility * (_min - _def))),
00249                 _def,
00250                 _def + ((SI) (flexibility * (_max - _def))));
00251   }
00252 }
00253 
00254 tree
00255 evaluate_bls_length () {
00256   double fs= (std_font_base_size () * std_magnification () *
00257              std_inch () * std_font_size ()) / 72.0;
00258   return tmlen_plus (tree (TMLEN, as_string (fs)),
00259                    tree (as_vspace (std_env [PAR_SEP])));
00260 }
00261 
00262 tree
00263 evaluate_fnbot_length () {
00264   return tree (TMLEN, as_string (std_fn()->y1));
00265 }
00266 
00267 tree
00268 evaluate_fntop_length () {
00269   return tree (TMLEN, as_string (std_fn()->y2));
00270 }
00271 
00272 tree
00273 evaluate_spc_length () {
00274   space spc= std_fn()->spc;
00275   return tree (TMLEN,
00276               as_string (spc->min),
00277               as_string (spc->def),
00278               as_string (spc->max));
00279 }
00280 
00281 tree
00282 evaluate_xspc_length () {
00283   space spc= std_fn()->extra;
00284   return tree (TMLEN,
00285               as_string (spc->min),
00286               as_string (spc->def),
00287               as_string (spc->max));
00288 }
00289 
00290 tree
00291 evaluate_par_length () {
00292   /*
00293   SI width, d1, d2, d3, d4, d5, d6, d7;
00294   get_page_pars (width, d1, d2, d3, d4, d5, d6, d7);
00295   width -= (get_length (PAR_LEFT) + get_length (PAR_RIGHT));
00296   return tree (TMLEN, as_string (width));
00297   */
00298   return tree (TMLEN, as_string (15 * std_inch() / 2.54)); // 15cm
00299 }
00300 
00301 tree
00302 evaluate_pag_length () {
00303   /*
00304   SI d1, height, d2, d3, d4, d5, d6, d7;
00305   get_page_pars (d1, height, d2, d3, d4, d5, d6, d7);
00306   return tree (TMLEN, as_string (height));
00307   */
00308   return tree (TMLEN, as_string (23 * std_inch() / 2.54)); // 23cm
00309 }
00310 
00311 tree evaluate_tmpt_length () {
00312   return tree (TMLEN, "1"); }
00313 tree evaluate_px_length () {
00314   return tree (TMLEN, as_string (std_sfactor () * PIXEL)); }
00315 
00316 tree
00317 evaluate_gw_length () {
00318   //return tree (TMLEN, as_string (gw));
00319   return tree (TMLEN, as_string (10 * std_inch() / 2.54)); // 10cm
00320 }
00321 
00322 tree
00323 evaluate_gh_length () {
00324   //return tree (TMLEN, as_string (gh));
00325   return tree (TMLEN, as_string (6 * std_inch() / 2.54)); // 6cm
00326 }
00327 
00328 tree evaluate_msec_length () { return tree (TMLEN, "1"); }
00329 tree evaluate_sec_length () { return tree (TMLEN, "1000"); }
00330 tree evaluate_min_length () { return tree (TMLEN, "60000"); }
00331 tree evaluate_hr_length () { return tree (TMLEN, "3600000"); }