Back to index

texmacs  1.0.7.15
math_font.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : math_font.cpp
00004 * DESCRIPTION: the font used for mathematical typesetting is actually a list
00005 *              of several fonts, which may be specified by the user.
00006 *              If a symbol needs to printed, we search in the list
00007 *              for a font which is capable of printing it.
00008 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00009 *******************************************************************************
00010 * This software falls under the GNU general public license version 3 or later.
00011 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00012 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00013 ******************************************************************************/
00014 
00015 #include "font.hpp"
00016 #include "translator.hpp"
00017 #include "convert.hpp"
00018 
00019 typedef int SI;
00020 bool operator == (font fn1, font fn2) { return fn1.rep == fn2.rep; }
00021 bool operator != (font fn1, font fn2) { return fn1.rep == fn2.rep; }
00022 font find_font (tree t);
00023 
00024 /******************************************************************************
00025 * The compound font class
00026 ******************************************************************************/
00027 
00028 struct math_font_rep: font_rep {
00029   font         base_fn;
00030   font         error_fn;
00031   translator   math;
00032   translator   rubber;
00033   translator   italic;
00034   array<tree>  font_name;
00035   array<font>  font_table;
00036   array<tree>  rubber_name;
00037   array<font>  rubber_table;
00038 
00039   math_font_rep (string name, scheme_tree t, font base, font error);
00040   void init_font (int fn_nr, font& fn);
00041   void search_font (string& s, font& fn);
00042   void get_extents (string s, metric& ex);
00043   void get_xpositions (string s, SI* xpos);
00044   void draw (renderer ren, string s, SI x, SI y);
00045   glyph get_glyph (string s);
00046 
00047   double get_left_slope  (string s);
00048   double get_right_slope (string s);
00049   SI     get_left_correction  (string s);
00050   SI     get_right_correction (string s);
00051 };
00052 
00053 math_font_rep::math_font_rep (
00054   string name, scheme_tree t, font base, font error):
00055     font_rep (name, base), base_fn (base), error_fn (error),
00056     math (load_translator (as_string (t[1][0]))),
00057     rubber (load_translator (as_string (t[2][0]))),
00058     italic (load_translator ("italic")),
00059     font_name (N(t[1])-1), font_table (N(t[1])-1),
00060     rubber_name (N(t[2])-1), rubber_table (N(t[2])-1)
00061 {
00062   int i;
00063   for (i=1; i<N(t[1]); i++)
00064     font_name[i-1]= t[1][i];
00065   for (i=1; i<N(t[2]); i++)
00066     rubber_name[i-1]= t[2][i];
00067 }
00068 
00069 /******************************************************************************
00070 * Find the font and the corresponding character
00071 ******************************************************************************/
00072 
00073 void
00074 math_font_rep::init_font (int fn_nr, font& fn) {
00075   tree t= font_name [fn_nr];
00076   if (is_tuple (t, "virtual", 3))
00077     fn= virtual_font (this, as_string(t[1]), as_int(t[2]), as_int(t[3]));
00078   else {
00079     fn= find_font (t);
00080     ASSERT (!is_nil (fn), "font not found");
00081   }
00082   fn->copy_math_pars (base_fn);
00083   font_table [fn_nr]= fn;
00084 }
00085 
00086 void
00087 math_font_rep::search_font (string& s, font& fn) {
00088   if ((N(s)>=9) && (s[N(s)-2]>='0') && (s[N(s)-2]<='9')) {
00089     int i;
00090     for (i=N(s)-1; i>0; i--)
00091       if (s[i]=='-') break;
00092     if (i>0) {
00093       string root= s(0,i) * ">";
00094       int c= rubber->dict [root];
00095       if ((c!=-1) && (s (N(s)-3, N(s)) != "-0>")) {
00096        int fn_nr= c/256;
00097        if (is_nil (rubber_table [fn_nr])) {
00098          fn= find_font (rubber_name [fn_nr]);
00099          ASSERT (!is_nil (fn), "font not found");
00100          fn->yfrac= base_fn->yfrac;
00101          // fn->copy_math_pars (base_fn);
00102          rubber_table [fn_nr]= fn;
00103        }
00104        else fn= rubber_table [fn_nr];
00105        return;
00106       }
00107       c= math->dict [s(0,i) * "-#>"];
00108       if (c != -1) {
00109        int fn_nr= c/256;
00110        fn= font_table [fn_nr];
00111        if (is_nil (fn)) init_font (fn_nr, fn);
00112        s= string ((char) (c&255)) * s (i+1, N(s));
00113        return;
00114       }
00115     }
00116   }
00117 
00118   int c= math->dict [s];
00119   if (c != -1) { 
00120     int fn_nr= c/256;
00121     fn= font_table [fn_nr];
00122     if (is_nil (fn)) init_font (fn_nr, fn);
00123     s= string ((char) (c&255));
00124   }
00125   else {
00126     int i, n= N(s);
00127     for (i=0; i<n; i++)
00128       if (((s[i]<'0') || (s[i]>'9')) &&
00129          ((s[i]<'a') || (s[i]>'z')) &&
00130          ((s[i]<'A') || (s[i]>'Z')) &&
00131          (s[i] != '.') && (s[i] != '\\') && (s[i] != '_'))
00132        {
00133          fn= error_fn;
00134          return;
00135        }
00136     fn= base_fn;
00137   }
00138 }
00139 
00140 /******************************************************************************
00141 * Getting extents and drawing strings
00142 ******************************************************************************/
00143 
00144 void
00145 math_font_rep::get_extents (string s, metric& ex) {
00146   font fn;
00147   search_font (s, fn);
00148   fn->get_extents (s, ex);
00149 }
00150 
00151 void
00152 math_font_rep::get_xpositions (string s, SI* xpos) {
00153   if (s == "") return;
00154   font fn;
00155   string r= s;
00156   search_font (r, fn);
00157   if (r == s) fn->get_xpositions (s, xpos);
00158   else if (N(r) != 1) font_rep::get_xpositions (s, xpos);
00159   else {
00160     int i, n=N(s);
00161     for (i=1; i<n; i++) xpos[i]= 0;
00162     fn->get_xpositions (r, xpos+n-1);
00163   }
00164 }
00165 
00166 void
00167 math_font_rep::draw (renderer ren, string s, SI x, SI y) {
00168   font fn;
00169   search_font (s, fn);
00170   fn->draw (ren, s, x, y);
00171 }
00172 
00173 glyph
00174 math_font_rep::get_glyph (string s) {
00175   font fn;
00176   search_font (s, fn);
00177   return fn->get_glyph (s);
00178 }
00179 
00180 /******************************************************************************
00181 * Metric properties
00182 ******************************************************************************/
00183 
00184 double
00185 math_font_rep::get_left_slope  (string s) {
00186   if (italic->dict->contains (s) || ((N(s) >= 2) && (s[0] != '<'))) {
00187     font fn;
00188     search_font (s, fn);
00189     return fn->get_left_slope (s);
00190   }
00191   else return 0;
00192 }
00193 
00194 double
00195 math_font_rep::get_right_slope (string s) {
00196   if (italic->dict->contains (s) || ((N(s) >= 2) && (s[0] != '<'))) {
00197     font fn;
00198     search_font (s, fn);
00199     return fn->get_right_slope (s);
00200   }
00201   else return 0;
00202 }
00203 
00204 SI
00205 math_font_rep::get_left_correction  (string s) {
00206   font fn;
00207   search_font (s, fn);
00208   return fn->get_left_correction (s);
00209 }
00210 
00211 SI
00212 math_font_rep::get_right_correction (string s) {
00213   font fn;
00214   search_font (s, fn);
00215   return fn->get_right_correction (s);
00216 }
00217 
00218 /******************************************************************************
00219 * User interface
00220 ******************************************************************************/
00221 
00222 font
00223 math_font (scheme_tree t, font base_fn, font error_fn) {
00224   string full_name= "compound-" * scheme_tree_to_string (t);
00225   return make (font, full_name,
00226     tm_new<math_font_rep> (full_name, t, base_fn, error_fn));
00227 }