/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}