Back to index

texmacs  1.0.7.15
find_font.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : find_font.cpp
00004 * DESCRIPTION: decoding font names
00005 * COPYRIGHT  : (C) 1999  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 "analyze.hpp"
00013 #include "tree.hpp"
00014 #include "font.hpp"
00015 #include "hashmap.hpp"
00016 #include "timer.hpp"
00017 
00018 hashmap<string,tree> font_conversion ("rule");
00019 
00020 /******************************************************************************
00021 * Declare a new rule
00022 ******************************************************************************/
00023 
00024 void
00025 font_rule (tree which, tree by) {
00026   if ((arity (which) * arity (by) == 0) || is_compound (which[0])) return;
00027   if (!font_conversion->contains (which[0]->label))
00028     font_conversion (which[0]->label)=
00029       tree (TUPLE, tree (ASSOCIATE, which, by));
00030   else font_conversion (which[0]->label) << tree (ASSOCIATE, which, by);
00031 }
00032 
00033 /******************************************************************************
00034 * Find a font
00035 ******************************************************************************/
00036 
00037 static bool
00038 matches (tree t, tree which, hashmap<string,tree>& H) {
00039   int i, n= arity (which);
00040   if (arity (t) != n) return false;
00041   for (i=0; i<n; i++) {
00042     if (which[i]->label[0]=='$') H (which[i]->label)= t[i];
00043     else if (t[i]!=which[i]) return false;
00044   }
00045   return true;
00046 }
00047 
00048 static tree
00049 substitute (tree by, hashmap<string,tree>& H) {
00050   if (is_atomic (by)) return copy (by);
00051   else {
00052     int i, n= N(by);
00053     tree r (by, n);
00054     for (i=0; i<n; i++) {
00055       if (is_atomic (by[i]) && starts (by[i]->label, "$"))
00056        r[i]= H [by[i]->label];
00057       else r[i]= substitute (by[i], H);
00058     }
00059     return r;
00060   }
00061 }
00062 
00063 font
00064 find_font_bis (tree t) {
00065   // cout << "Find " << t << "\n";
00066 
00067   if ((arity (t)==0) || is_compound (t[0])) return font ();
00068 
00069   if (is_tuple (t, "compound"))
00070     return compound_font (t (1, N(t)));
00071 
00072   if (is_tuple (t, "truetype", 3))
00073     return tt_font (as_string (t[1]), as_int (t[2]), as_int (t[3]));
00074 
00075   if (is_tuple (t, "unicode", 3))
00076     return unicode_font (as_string (t[1]), as_int (t[2]), as_int (t[3]));
00077 
00078   if (is_tuple (t, "unimath", 5)) {
00079     font up= find_font (t[1]);
00080     font it= find_font (t[2]);
00081     font bup= find_font (t[3]);
00082     font bit= find_font (t[4]);
00083     font rb= find_font (t[5]);
00084     if (is_nil (up)) return up;
00085     if (is_nil (it)) return it;
00086     if (is_nil (bup)) return bup;
00087     if (is_nil (bit)) return bit;
00088     if (is_nil (rb)) return rb;
00089     return unicode_math_font (up, it, bup, bit, rb);
00090   }
00091 
00092   if (is_tuple (t, "x", 3))
00093     return x_font (as_string (t[1]), as_int (t[2]), as_int (t[3]));
00094 
00095   if (is_tuple (t, "tex", 3))
00096     return tex_font (as_string (t[1]), as_int (t[2]), as_int (t[3]));
00097 
00098   if (is_tuple (t, "tex", 4))
00099     return tex_font (as_string (t[1]), as_int (t[2]), as_int (t[3]),
00100                    as_int (t[4]));
00101 
00102   if (is_tuple (t, "cm", 3))
00103     return tex_cm_font (as_string (t[1]), as_int (t[2]), as_int (t[3]));
00104 
00105   if (is_tuple (t, "cm", 4))
00106     return tex_cm_font (as_string (t[1]), as_int (t[2]), as_int (t[3]),
00107                      as_int (t[4]));
00108 
00109   if (is_tuple (t, "ec", 3))
00110     return tex_ec_font (as_string (t[1]), as_int (t[2]), as_int (t[3]));
00111 
00112   if (is_tuple (t, "ec", 4))
00113     return tex_ec_font (as_string (t[1]), as_int (t[2]), as_int (t[3]),
00114                      as_int (t[4]));
00115   
00116   if (is_tuple (t, "la", 3))
00117     return tex_la_font (as_string (t[1]), as_int (t[2]) * 100,
00118                      as_int (t[3]), 1000);
00119 
00120   if (is_tuple (t, "la", 4))
00121     return tex_la_font (as_string (t[1]), as_int (t[2]) * 100,
00122                      as_int (t[3]), as_int (t[4]) * 100);
00123 
00124   if (is_tuple (t, "adobe", 3))
00125     return tex_adobe_font (as_string (t[1]), as_int (t[2]),
00126                         as_int (t[3]));
00127 
00128   if (is_tuple (t, "adobe", 4))
00129     return tex_adobe_font (as_string (t[1]), as_int (t[2]),
00130                         as_int (t[3]), as_int (t[4]));
00131 
00132   if (is_tuple (t, "tex-rubber", 4))
00133     return tex_rubber_font (as_string (t[1]), as_string (t[2]),
00134                          as_int (t[3]), as_int (t[4]));
00135 
00136   if (is_tuple (t, "tex-rubber", 5))
00137     return tex_rubber_font (as_string (t[1]), as_string (t[2]),
00138                          as_int (t[3]), as_int (t[4]), as_int (t[5]));
00139 
00140   if (is_tuple (t, "tex-dummy-rubber", 1)) {
00141     font fn= find_font (t[1]);
00142     if (is_nil (fn)) return fn;
00143     return tex_dummy_rubber_font (fn);
00144   }
00145   
00146   if (is_tuple (t, "error", 1)) {
00147     font fn= find_font (t[1]);
00148     if (is_nil (fn)) return fn;
00149     return error_font (fn);
00150   }
00151 
00152   if (is_tuple (t, "math", 4) && is_tuple (t[1]) && is_tuple (t[2])) {
00153     font fn= find_font (t[3]);
00154     if (is_nil (fn)) return fn;
00155     font error_fn= error_font (find_font (t[4]));
00156     if (is_nil (error_fn)) error_fn= error_font (fn);
00157     return math_font (t, fn, error_fn);
00158   }
00159 
00160   if (!font_conversion->contains (t[0]->label)) return font ();
00161 
00162   tree rule= font_conversion [t[0]->label];
00163   int i, n= N(rule);
00164   for (i=0; i<n; i++) {
00165     hashmap<string,tree> H ("?");
00166     if (matches (t, rule[i][0], H))
00167       return find_font (substitute (rule[i][1], H));
00168   }
00169 
00170   return font ();
00171 }
00172 
00173 font
00174 find_font (tree t) {
00175   bench_start ("find font");
00176   font fn= find_font_bis (t);
00177   bench_cumul ("find font");
00178   return fn;
00179 }
00180 
00181 /******************************************************************************
00182 * User interface
00183 ******************************************************************************/
00184 
00185 font
00186 find_font (string family, string fn_class,
00187           string series, string shape, int sz, int dpi)
00188 {
00189   string s=
00190     family * "-" * fn_class * "-" *
00191     series * "-" * shape * "-" *
00192     as_string (sz) * "-" * as_string (dpi);
00193   if (font::instances->contains (s)) return font (s);
00194 
00195   tree t1 (TUPLE, 6);
00196   t1[0]= family;
00197   t1[1]= fn_class;
00198   t1[2]= series; t1[3]= shape;
00199   t1[4]= as_string (sz); t1[5]= as_string (dpi);
00200   font fn= find_font (t1);
00201   if (!is_nil (fn)) {
00202     font::instances (s)= (pointer) fn.rep;
00203     return fn;
00204   }
00205 
00206   tree t2 (TUPLE, 5);
00207   t2[0]= family;
00208   t2[1]= fn_class; t2[2]= series;
00209   t2[3]= as_string (sz); t2[4]= as_string (dpi);
00210   fn= find_font (t2);
00211   if (!is_nil (fn)) {
00212     font::instances (s)= (pointer) fn.rep;
00213     return fn;
00214   }
00215 
00216   tree t3 (TUPLE, 4);
00217   t3[0]= family;
00218   t3[1]= fn_class; t3[2]= as_string (sz); t3[3]= as_string (dpi);
00219   fn= find_font (t3);
00220   if (!is_nil (fn)) {
00221     font::instances (s)= (pointer) fn.rep;
00222     return fn;
00223   }
00224 
00225   tree panic (TUPLE, "tex", "cmr", as_string (sz), as_string (dpi));
00226   fn= find_font (panic);
00227   font::instances (s)= (pointer) fn.rep;
00228   return fn;
00229 }