Back to index

texmacs  1.0.7.15
compound_font.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : compound_font.cpp
00004 * DESCRIPTION: fonts which are agglomerated from several other fonts.
00005 * COPYRIGHT  : (C) 2005  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 "font.hpp"
00013 #include "charmap.hpp"
00014 #include "convert.hpp"
00015 
00016 /******************************************************************************
00017 * The compound font class
00018 ******************************************************************************/
00019 
00020 static tree
00021 map_car (tree t) {
00022   int i, n= N(t);
00023   tree r (TUPLE, n);
00024   for (i=0; i<n; i++)
00025     r[i]= t[i][0];
00026   return r;
00027 }
00028 
00029 struct compound_font_rep: font_rep {
00030   scheme_tree  def;
00031   array<font>  fn;
00032   charmap      cm;
00033 
00034   compound_font_rep (string name, scheme_tree def, array<font> fn);
00035   void   advance (string s, int& pos, string& r, int& ch);
00036   void   get_extents (string s, metric& ex);
00037   void   draw (renderer ren, string s, SI x, SI y);
00038   glyph  get_glyph (string s);
00039   double get_left_slope  (string s);
00040   double get_right_slope (string s);
00041   SI     get_left_correction  (string s);
00042   SI     get_right_correction (string s);
00043 };
00044 
00045 compound_font_rep::compound_font_rep (
00046   string name, scheme_tree def2, array<font> fn2):
00047     font_rep (name, fn2[0]),
00048     def (def2), fn (fn2), cm (load_charmap (map_car (def)))
00049 {}
00050 
00051 void
00052 compound_font_rep::advance (string s, int& pos, string& r, int& ch) {
00053   cm->advance (s, pos, r, ch);
00054   //cout << "(r,ch)= (" << r << "," << ch << ")\n";
00055   if (ch>0 && is_nil (fn[ch])) {
00056     tree t= def[ch][1];
00057     if (is_tuple (t, "virtual", 3))
00058       fn[ch]= virtual_font (this, as_string(t[1]), as_int(t[2]), as_int(t[3]));
00059     else fn[ch]= find_font (t);
00060     ASSERT (!is_nil (fn[ch]), "font not found");
00061     //fn[ch]->copy_math_pars (fn[0]);
00062   }
00063 }
00064 
00065 /******************************************************************************
00066 * Getting extents and drawing strings
00067 ******************************************************************************/
00068 
00069 static string empty_string ("");
00070 
00071 void
00072 compound_font_rep::get_extents (string s, metric& ex) {
00073   int i=0, n= N(s);
00074   fn[0]->get_extents (empty_string, ex);
00075   while (i < n) {
00076     int nr;
00077     string r= s;
00078     metric ey;
00079     advance (s, i, r, nr);
00080     if (nr >= 0) {
00081       fn[nr]->get_extents (r, ey);
00082       ex->y1= min (ex->y1, ey->y1);
00083       ex->y2= max (ex->y2, ey->y2);
00084       ex->x3= min (ex->x3, ex->x2 + ey->x3);
00085       ex->y3= min (ex->y3, ey->y3);
00086       ex->x4= max (ex->x4, ex->x2 + ey->x4);
00087       ex->y4= max (ex->y4, ey->y4);
00088       ex->x2 += ey->x2;
00089     }
00090   }
00091 }
00092 
00093 void
00094 compound_font_rep::draw (renderer ren, string s, SI x, SI y) {
00095   int i=0, n= N(s);
00096   while (i < n) {
00097     int nr;
00098     string r= s;
00099     metric ey;
00100     advance (s, i, r, nr);
00101     if (nr >= 0) {
00102       fn[nr]->draw (ren, r, x, y);
00103       if (i < n) {
00104        fn[nr]->get_extents (r, ey);
00105        x += ey->x2;
00106       }
00107     }
00108   }
00109 }
00110 
00111 /******************************************************************************
00112 * Other routines for fonts
00113 ******************************************************************************/
00114 
00115 glyph
00116 compound_font_rep::get_glyph (string s) {
00117   int i=0, n= N(s), nr;
00118   if (n == 0) return fn[0]->get_glyph (s);
00119   string r= s;
00120   advance (s, i, r, nr);
00121   if (nr<0) return glyph ();
00122   return fn[nr]->get_glyph (r);
00123 }
00124 
00125 double
00126 compound_font_rep::get_left_slope  (string s) {
00127   int i=0, n= N(s), nr;
00128   if (n == 0) return fn[0]->get_left_slope (s);
00129   string r= s;
00130   advance (s, i, r, nr);
00131   nr= max (nr, 0);
00132   return fn[nr]->get_left_slope (r);
00133 }
00134 
00135 double
00136 compound_font_rep::get_right_slope (string s) {
00137   int i=0, n= N(s), nr;
00138   if (n == 0) return fn[0]->get_right_slope (s);
00139   string r= s;
00140   while (i<n) advance (s, i, r, nr);
00141   nr= max (nr, 0);
00142   return fn[nr]->get_right_slope (r);
00143 }
00144 
00145 SI
00146 compound_font_rep::get_left_correction  (string s) {
00147   int i=0, n= N(s), nr;
00148   if (n == 0) return fn[0]->get_left_correction (s);
00149   string r= s;
00150   advance (s, i, r, nr);
00151   nr= max (nr, 0);
00152   return fn[nr]->get_left_correction (r);
00153 }
00154 
00155 SI
00156 compound_font_rep::get_right_correction (string s) {
00157   int i=0, n= N(s), nr;
00158   if (n == 0) return fn[0]->get_right_correction (s);
00159   string r= s;
00160   while (i<n) advance (s, i, r, nr);
00161   nr= max (nr, 0);
00162   return fn[nr]->get_right_correction (r);
00163 }
00164 
00165 /******************************************************************************
00166 * User interface
00167 ******************************************************************************/
00168 
00169 font
00170 compound_font (scheme_tree def) {
00171   string name= tree_to_scheme (def);
00172   if (font::instances->contains (name))
00173     return font (name);
00174   array<font> fn (N(def));
00175   fn[0]= find_font (def[0][1]);
00176   if (is_nil (fn[0])) return font ();
00177   return make (font, name, tm_new<compound_font_rep> (name, def, fn));
00178 }