]> git.donarmstrong.com Git - lilypond.git/blob - lily/font-metric.cc
* input/regression/new-markup-scheme.ly: oops. font-family=music
[lilypond.git] / lily / font-metric.cc
1 /*   
2   font-metric.cc -- implement Font_metric
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7
8     Mats Bengtsson <matsb@s3.kth.se> (the ugly TeX parsing in text_dimension)
9 */
10
11 #include "font-metric.hh"
12
13 #include <math.h>
14 #include <cctype>
15
16 #include "dimensions.hh"
17 #include "modified-font-metric.hh"
18 #include "open-type-font.hh"
19 #include "stencil.hh"
20 #include "virtual-methods.hh"
21 #include "warn.hh"
22
23 #include "ly-smobs.icc"
24
25 Real
26 Font_metric::design_size () const
27 {
28   return 1.0 * point_constant;
29 }
30
31
32 Stencil
33 Font_metric::find_by_name (String s) const
34 {
35   s.substitute_char ('-', "M");
36   int idx = name_to_index (s);
37   Box b;
38   
39   SCM expr = SCM_EOL;
40   if (idx >= 0)
41     {
42       expr = scm_list_3 (ly_symbol2scm ("named-glyph"),
43                          self_scm (),
44                          scm_makfrom0str (s.to_str0 ())
45                          );
46       b = get_indexed_char (idx);
47     }
48   
49   Stencil q (b, expr);
50   return q;
51 }
52
53 Font_metric::Font_metric ()
54 {
55   description_ = SCM_EOL;
56   self_scm_ = SCM_EOL;
57   smobify_self ();
58 }
59
60 Font_metric::Font_metric (Font_metric const &)
61 {
62 }
63
64
65 Font_metric::~Font_metric ()
66 {
67 }
68
69 int
70 Font_metric::count () const
71 {
72   return 0;
73 }
74
75 Box 
76 Font_metric::get_ascii_char (int) const
77 {
78   return Box (Interval (0, 0), Interval (0, 0));
79 }
80
81 Box 
82 Font_metric::get_indexed_char (int k) const
83 {
84   return get_ascii_char (k);
85 }
86
87 int
88 Font_metric::name_to_index (String) const
89 {
90   return -1;
91 }
92
93 Offset
94 Font_metric::get_indexed_wxwy (int) const
95 {
96   return Offset (0, 0);
97 }
98
99 void
100 Font_metric::derived_mark () const
101 {
102 }
103
104 SCM
105 Font_metric::mark_smob (SCM s)
106 {
107   Font_metric *m = (Font_metric*) SCM_CELL_WORD_1 (s);
108   m->derived_mark ();
109   return m->description_;
110 }
111
112 int
113 Font_metric::print_smob (SCM s, SCM port, scm_print_state *)
114 {
115   Font_metric *m = unsmob_metrics (s);
116   scm_puts ("#<", port);
117   scm_puts (classname (m), port);
118   scm_puts (" ", port);
119   scm_write (m->description_, port);
120   scm_puts (">", port);
121   return 1;
122 }
123
124
125
126 IMPLEMENT_SMOBS (Font_metric);
127 IMPLEMENT_DEFAULT_EQUAL_P (Font_metric);
128 IMPLEMENT_TYPE_P (Font_metric, "ly:font-metric?");
129
130
131 LY_DEFINE (ly_font_get_glyph, "ly:font-get-glyph",
132            2, 0, 0,
133           (SCM font, SCM name),
134            "Return a Stencil from @var{font} for the glyph named @var{name}.  "
135            "@var{font} must be available as an AFM file.  If the glyph "
136            "is not available, return @code{#f}.")
137 {
138   Font_metric *fm = unsmob_metrics (font);
139   SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
140   SCM_ASSERT_TYPE (scm_is_string (name), name, SCM_ARG2, __FUNCTION__, "string");
141
142   Stencil m = fm->find_by_name (ly_scm2string (name));
143
144   /* TODO: make optional argument for default if not found.  */
145   return m.smobbed_copy ();
146 }
147
148 LY_DEFINE (ly_get_glyph, "ly:get-glyph",
149            2, 0, 0,
150           (SCM font, SCM index),
151            "Retrieve a Stencil for the glyph numbered @var{index} "
152            "in @var{font}.")
153 {
154   Font_metric *fm = unsmob_metrics (font);
155   SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
156   SCM_ASSERT_TYPE (scm_is_number (index), index, SCM_ARG2, __FUNCTION__, "number");
157
158   return fm->get_ascii_char_stencil (scm_to_int (index)).smobbed_copy ();
159 }
160
161 LY_DEFINE (ly_font_glyph_name_to_index, "ly:font-glyph-name-to-index",
162            2, 0, 0,
163           (SCM font, SCM name),
164            "Return the index for @var{name} in @var{font}.")
165 {
166   Font_metric *fm = unsmob_metrics (font);
167   SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
168   SCM_ASSERT_TYPE (scm_is_string (name), name, SCM_ARG2, __FUNCTION__, "string");
169
170   return scm_from_int (fm->name_to_index (ly_scm2string (name)));
171 }
172
173 LY_DEFINE (ly_font_index_to_charcode, "ly:font-index-to-charcode",
174            2, 0, 0,
175           (SCM font, SCM index),
176            "Return the character code for @var{index} @var{font}.")
177 {
178   Font_metric *fm = unsmob_metrics (font);
179   SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
180   SCM_ASSERT_TYPE (scm_is_integer (index), index, SCM_ARG2, __FUNCTION__, "index");
181
182   return scm_from_unsigned_integer (fm->index_to_charcode (scm_to_int (index)));
183 }
184
185 LY_DEFINE (ly_font_glyph_name_to_charcode, "ly:font-glyph-name-to-charcode",
186            2, 0, 0,
187           (SCM font, SCM name),
188            "Return the character code for glyph @var{name} in @var{font}.")
189 {
190   Font_metric *fm = unsmob_metrics (font);
191   SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
192   SCM_ASSERT_TYPE (scm_is_string (name), name, SCM_ARG2, __FUNCTION__, "string");
193 #if 1
194   return scm_from_unsigned_integer (fm->index_to_charcode (fm->name_to_index (ly_scm2string (name))));
195 #else
196   return scm_from_unsigned_integer (fm->glyph_name_to_charcode (ly_scm2string (name)));
197 #endif
198 }
199
200 LY_DEFINE (ly_text_dimension, "ly:text-dimension",
201            2, 0, 0,
202           (SCM font, SCM text),
203           "Given the font metric in @var{font} and the string @var{text}, "
204            "compute the extents of that text in that font.  "
205            "The return value is a pair of number-pairs.")
206 {
207   Box b;
208   Modified_font_metric*fm = dynamic_cast<Modified_font_metric*>
209     (unsmob_metrics (font));
210   
211   SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "modified font metric");
212   SCM_ASSERT_TYPE (scm_is_string (text), text, SCM_ARG2, __FUNCTION__, "string");
213   Stencil stc (fm->text_stencil (ly_scm2string (text)));
214   return scm_cons (ly_interval2scm (stc.extent (X_AXIS)),
215                    ly_interval2scm (stc.extent (Y_AXIS)));
216 }
217
218 LY_DEFINE (ly_font_file_name, "ly:font-file-name",
219            1, 0, 0,
220            (SCM font),
221            "Given the font metric @var{font}, "
222            "return the corresponding file name.")
223 {
224   Font_metric *fm = unsmob_metrics (font);
225   SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
226   return fm->font_file_name();
227 }
228
229 SCM 
230 Font_metric::font_file_name () const
231 {
232   return scm_car (description_);
233 }
234
235 String
236 Font_metric::font_name () const
237 {
238   String s ("unknown");
239   return s;
240 }
241
242 #include "afm.hh"
243
244 LY_DEFINE (ly_font_name, "ly:font-name",
245            1, 0, 0,
246            (SCM font),
247            "Given the font metric @var{font}, "
248            "return the corresponding name.")
249 {
250   Font_metric *fm = unsmob_metrics (font);
251       
252   SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
253   return scm_makfrom0str (fm->font_name().to_str0 ());
254 }
255
256 LY_DEFINE (ly_font_magnification, "ly:font-magnification", 1, 0, 0,
257           (SCM font),
258            "Given the font metric @var{font}, return the "
259            "magnification, relative to the current outputscale.")
260 {
261   Font_metric *fm = unsmob_metrics (font);
262   SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
263   return scm_cdr (fm->description_);
264 }
265
266 LY_DEFINE (ly_font_design_size, "ly:font-design-size", 1, 0, 0,
267           (SCM font),
268            "Given the font metric @var{font}, return the "
269            "design size, relative to the current outputscale.")
270 {
271   Font_metric *fm = unsmob_metrics (font);
272   SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "font-metric");
273   return scm_make_real (fm->design_size ());
274 }
275
276
277
278 int
279 Font_metric::index_to_ascii (int i) const
280 {
281   return i;
282 }
283
284 unsigned
285 Font_metric::index_to_charcode (int i) const
286 {
287   return (unsigned) index_to_ascii (i);
288 }
289
290 Stencil
291 Font_metric::get_ascii_char_stencil (int code) const
292 {
293   SCM at = scm_list_3 (ly_symbol2scm ("char"), self_scm (),
294                        scm_int2num (code));
295   Box b = get_ascii_char (code);
296   return Stencil (b, at);
297 }
298
299 Stencil
300 Font_metric::get_indexed_char_stencil (int code) const
301 {
302   int idx = index_to_ascii (code);
303   SCM at = scm_list_3 (ly_symbol2scm ("char"), self_scm (), scm_int2num (idx));
304   Box b = get_indexed_char (code);
305   return Stencil (b, at);
306 }
307
308
309 Offset
310 Font_metric::attachment_point (String) const
311 {
312   return Offset (0, 0);
313 }
314
315 SCM
316 Font_metric::sub_fonts () const
317 {
318   return SCM_EOL;
319 }
320
321 Stencil
322 Font_metric::text_stencil (String str) const
323 {
324   SCM lst = scm_list_3 (ly_symbol2scm ("text"),
325                         this->self_scm (),
326                         scm_makfrom0str (str.to_str0 ()));
327   
328   Box b = text_dimension (str);
329   return Stencil (b, lst);
330 }
331
332 Box
333 Font_metric::text_dimension (String) const
334 {
335   return Box (Interval (0,0), Interval (0,0));
336 }