2
font-metric.cc -- implement Font_metric
2
font-metric.cc -- implement Font_metric
4
4
source file of the GNU LilyPond music typesetter
6
(c) 1999--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8
Mats Bengtsson <matsb@s3.kth.se> (the ugly TeX parsing in text_dimension)
6
(c) 1999--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
8
Mats Bengtsson <matsb@s3.kth.se> (the ugly TeX parsing in text_dimension)
11
#include "font-metric.hh"
17
#include "dimensions.hh"
18
#include "modified-font-metric.hh"
19
#include "open-type-font.hh"
14
21
#include "virtual-methods.hh"
17
24
#include "ly-smobs.icc"
18
#include "font-metric.hh"
22
Font_metric::text_dimension (String text) const
27
for (int i = 0; i < text.length (); i++)
27
Font_metric::design_size () const
29
return 1.0 * point_constant;
33
Font_metric::find_by_name (string s) const
35
replace_all (s, '-', 'M');
36
int idx = name_to_index (s);
33
// accent marks use width of base letter
34
if (i +1 < text.length ())
36
if (text[i+1]=='\'' || text[i+1]=='`' || text[i+1]=='"' ||
42
// for string width \\ is a \ and \_ is a _.
43
if (text[i+1]=='\\' || text[i+1]=='_')
49
for (i++; (i < text.length ()) && !isspace (text[i])
50
&& text[i]!='{' && text[i]!='}'; i++)
53
i--; // Compensate for the increment in the outer loop!
55
case '{': // Skip '{' and '}'
60
Box b = get_ascii_char ((unsigned char)text[i]);
62
// Ugh, use the width of 'x' for unknown characters
63
if (b[X_AXIS].length () == 0)
64
b = get_ascii_char ((unsigned char)'x');
66
w += b[X_AXIS].length ();
67
ydims.unite (b[Y_AXIS]);
42
expr = scm_list_3 (ly_symbol2scm ("named-glyph"),
44
scm_makfrom0str (s.c_str ()));
45
b = get_indexed_char (idx);
71
if (ydims.is_empty ())
72
ydims = Interval (0,0);
74
return Box (Interval (0, w), ydims);
79
Font_metric::~Font_metric ()
83
52
Font_metric::Font_metric ()
63
Font_metric::~Font_metric ()
95
68
Font_metric::count () const
101
Font_metric::get_ascii_char (int) const
74
Font_metric::get_ascii_char (size_t) const
103
return Box (Interval (0,0),Interval (0,0));
76
return Box (Interval (0, 0), Interval (0, 0));
107
Font_metric::get_indexed_char (int k) const
80
Font_metric::get_indexed_char (size_t k) const
109
82
return get_ascii_char (k);
114
Font_metric::name_to_index (String) const
86
Font_metric::name_to_index (string) const
120
Font_metric::get_indexed_wxwy (int )const
92
Font_metric::get_indexed_wxwy (size_t) const
126
Font_metric::derived_mark ()const
98
Font_metric::derived_mark () const
132
103
Font_metric::mark_smob (SCM s)
134
Font_metric * m = (Font_metric*) SCM_CELL_WORD_1 (s);
105
Font_metric *m = (Font_metric *) SCM_CELL_WORD_1 (s);
136
106
m->derived_mark ();
137
107
return m->description_;
143
113
Font_metric *m = unsmob_metrics (s);
144
114
scm_puts ("#<", port);
145
scm_puts (classname (m), port);
115
scm_puts (m->class_name (), port);
146
116
scm_puts (" ", port);
147
117
scm_write (m->description_, port);
148
118
scm_puts (">", port);
154
122
IMPLEMENT_SMOBS (Font_metric);
155
123
IMPLEMENT_DEFAULT_EQUAL_P (Font_metric);
156
124
IMPLEMENT_TYPE_P (Font_metric, "ly:font-metric?");
159
Font_metric::find_by_name (String) const
165
LY_DEFINE (ly_find_glyph_by_name, "ly:find-glyph-by-name", 2 , 0, 0,
166
(SCM font, SCM name),
167
"This function retrieves a Stencil for the glyph named @var{name} "
170
"The font must be available as an AFM file. If the glyph "
171
"is not found, @code{#f} is returned. ")
173
Font_metric *fm = unsmob_metrics (font);
174
SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
175
SCM_ASSERT_TYPE (gh_string_p (name), name, SCM_ARG2, __FUNCTION__, "string");
177
Stencil m = fm->find_by_name (ly_scm2string (name));
180
TODO: make optional argument for default if not found.
182
return m.smobbed_copy ();
185
LY_DEFINE (ly_get_glyph, "ly:get-glyph", 2 , 0, 0,
186
(SCM font, SCM index),
187
"This function retrieves a Stencil for the glyph numbered @var{index} in "
190
Font_metric *fm = unsmob_metrics (font);
191
SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
192
SCM_ASSERT_TYPE (gh_number_p (index), index, SCM_ARG2, __FUNCTION__, "number");
194
return fm->get_ascii_char_stencil (gh_scm2int (index)).smobbed_copy ();
197
LY_DEFINE (ly_text_dimension,"ly:text-dimension", 2 , 0, 0,
198
(SCM font, SCM text),
199
"Given the font metric in @var{font} and the string @var{text}, compute "
200
"the extents of that text in that font. The return value is a pair of "
204
Font_metric *fm = unsmob_metrics (font);
205
SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
206
SCM_ASSERT_TYPE (gh_string_p (text), text, SCM_ARG2, __FUNCTION__, "string");
208
b = fm->text_dimension (ly_scm2string (text));
210
return gh_cons (ly_interval2scm (b[X_AXIS]), ly_interval2scm (b[Y_AXIS]));
214
Font_metric::get_ascii_char_stencil (int code) const
216
SCM at = scm_list_n (ly_symbol2scm ("char"), gh_int2scm (code),
218
at = fontify_atom (this, at);
127
Font_metric::font_file_name () const
129
return scm_car (description_);
133
Font_metric::font_name () const
135
string s ("unknown");
140
Font_metric::index_to_ascii (size_t i) const
146
Font_metric::index_to_charcode (size_t i) const
148
return index_to_ascii (i);
152
Font_metric::get_ascii_char_stencil (size_t code) const
154
SCM at = scm_list_3 (ly_symbol2scm ("char"), self_scm (),
155
scm_from_unsigned (code));
219
156
Box b = get_ascii_char (code);
220
157
return Stencil (b, at);
224
Font_metric::get_indexed_char_stencil (int code) const
161
Font_metric::get_indexed_char_stencil (size_t code) const
226
SCM at = scm_list_n (ly_symbol2scm ("char"), gh_int2scm (code),
228
at = fontify_atom (this, at);
163
size_t idx = index_to_ascii (code);
164
SCM at = scm_list_3 (ly_symbol2scm ("char"), self_scm (),
165
scm_from_unsigned (idx));
229
166
Box b = get_indexed_char (code);
230
167
return Stencil (b, at);
171
Font_metric::attachment_point (string) const
173
return Offset (0, 0);
177
Font_metric::sub_fonts () const
183
Font_metric::text_stencil (string str) const
185
SCM lst = scm_list_3 (ly_symbol2scm ("text"),
187
scm_makfrom0str (str.c_str ()));
189
Box b = text_dimension (str);
190
return Stencil (b, lst);
194
Font_metric::text_dimension (string) const
196
return Box (Interval (0, 0), Interval (0, 0));