PageRenderTime 41ms CodeModel.GetById 25ms app.highlight 15ms RepoModel.GetById 0ms app.codeStats 0ms

/TeXmacs-1.0.7.11-src/src/Graphics/Fonts/compound_font.cpp

#
C++ | 178 lines | 135 code | 20 blank | 23 comment | 25 complexity | 9d27b60d551a13609bc55fb563daf5ce MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, MPL-2.0-no-copyleft-exception
  1
  2/******************************************************************************
  3* MODULE     : compound_font.cpp
  4* DESCRIPTION: fonts which are agglomerated from several other fonts.
  5* COPYRIGHT  : (C) 2005  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 "font.hpp"
 13#include "charmap.hpp"
 14#include "convert.hpp"
 15
 16/******************************************************************************
 17* The compound font class
 18******************************************************************************/
 19
 20static tree
 21map_car (tree t) {
 22  int i, n= N(t);
 23  tree r (TUPLE, n);
 24  for (i=0; i<n; i++)
 25    r[i]= t[i][0];
 26  return r;
 27}
 28
 29struct compound_font_rep: font_rep {
 30  scheme_tree  def;
 31  array<font>  fn;
 32  charmap      cm;
 33
 34  compound_font_rep (string name, scheme_tree def, array<font> fn);
 35  void   advance (string s, int& pos, string& r, int& ch);
 36  void   get_extents (string s, metric& ex);
 37  void   draw (renderer ren, string s, SI x, SI y);
 38  glyph  get_glyph (string s);
 39  double get_left_slope  (string s);
 40  double get_right_slope (string s);
 41  SI     get_left_correction  (string s);
 42  SI     get_right_correction (string s);
 43};
 44
 45compound_font_rep::compound_font_rep (
 46  string name, scheme_tree def2, array<font> fn2):
 47    font_rep (name, fn2[0]),
 48    def (def2), fn (fn2), cm (load_charmap (map_car (def)))
 49{}
 50
 51void
 52compound_font_rep::advance (string s, int& pos, string& r, int& ch) {
 53  cm->advance (s, pos, r, ch);
 54  //cout << "(r,ch)= (" << r << "," << ch << ")\n";
 55  if (ch>0 && is_nil (fn[ch])) {
 56    tree t= def[ch][1];
 57    if (is_tuple (t, "virtual", 3))
 58      fn[ch]= virtual_font (this, as_string(t[1]), as_int(t[2]), as_int(t[3]));
 59    else fn[ch]= find_font (t);
 60    ASSERT (!is_nil (fn[ch]), "font not found");
 61    //fn[ch]->copy_math_pars (fn[0]);
 62  }
 63}
 64
 65/******************************************************************************
 66* Getting extents and drawing strings
 67******************************************************************************/
 68
 69static string empty_string ("");
 70
 71void
 72compound_font_rep::get_extents (string s, metric& ex) {
 73  int i=0, n= N(s);
 74  fn[0]->get_extents (empty_string, ex);
 75  while (i < n) {
 76    int nr;
 77    string r= s;
 78    metric ey;
 79    advance (s, i, r, nr);
 80    if (nr >= 0) {
 81      fn[nr]->get_extents (r, ey);
 82      ex->y1= min (ex->y1, ey->y1);
 83      ex->y2= max (ex->y2, ey->y2);
 84      ex->x3= min (ex->x3, ex->x2 + ey->x3);
 85      ex->y3= min (ex->y3, ey->y3);
 86      ex->x4= max (ex->x4, ex->x2 + ey->x4);
 87      ex->y4= max (ex->y4, ey->y4);
 88      ex->x2 += ey->x2;
 89    }
 90  }
 91}
 92
 93void
 94compound_font_rep::draw (renderer ren, string s, SI x, SI y) {
 95  int i=0, n= N(s);
 96  while (i < n) {
 97    int nr;
 98    string r= s;
 99    metric ey;
100    advance (s, i, r, nr);
101    if (nr >= 0) {
102      fn[nr]->draw (ren, r, x, y);
103      if (i < n) {
104	fn[nr]->get_extents (r, ey);
105	x += ey->x2;
106      }
107    }
108  }
109}
110
111/******************************************************************************
112* Other routines for fonts
113******************************************************************************/
114
115glyph
116compound_font_rep::get_glyph (string s) {
117  int i=0, n= N(s), nr;
118  if (n == 0) return fn[0]->get_glyph (s);
119  string r= s;
120  advance (s, i, r, nr);
121  if (nr<0) return glyph ();
122  return fn[nr]->get_glyph (r);
123}
124
125double
126compound_font_rep::get_left_slope  (string s) {
127  int i=0, n= N(s), nr;
128  if (n == 0) return fn[0]->get_left_slope (s);
129  string r= s;
130  advance (s, i, r, nr);
131  nr= max (nr, 0);
132  return fn[nr]->get_left_slope (r);
133}
134
135double
136compound_font_rep::get_right_slope (string s) {
137  int i=0, n= N(s), nr;
138  if (n == 0) return fn[0]->get_right_slope (s);
139  string r= s;
140  while (i<n) advance (s, i, r, nr);
141  nr= max (nr, 0);
142  return fn[nr]->get_right_slope (r);
143}
144
145SI
146compound_font_rep::get_left_correction  (string s) {
147  int i=0, n= N(s), nr;
148  if (n == 0) return fn[0]->get_left_correction (s);
149  string r= s;
150  advance (s, i, r, nr);
151  nr= max (nr, 0);
152  return fn[nr]->get_left_correction (r);
153}
154
155SI
156compound_font_rep::get_right_correction (string s) {
157  int i=0, n= N(s), nr;
158  if (n == 0) return fn[0]->get_right_correction (s);
159  string r= s;
160  while (i<n) advance (s, i, r, nr);
161  nr= max (nr, 0);
162  return fn[nr]->get_right_correction (r);
163}
164
165/******************************************************************************
166* User interface
167******************************************************************************/
168
169font
170compound_font (scheme_tree def) {
171  string name= tree_to_scheme (def);
172  if (font::instances->contains (name))
173    return font (name);
174  array<font> fn (N(def));
175  fn[0]= find_font (def[0][1]);
176  if (is_nil (fn[0])) return font ();
177  return make (font, name, tm_new<compound_font_rep> (name, def, fn));
178}