2 font-interface.cc -- implement Font_interface
4 source file of the GNU LilyPond music typesetter
6 (c) 2000--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "all-font-metrics.hh"
11 #include "font-metric.hh"
12 #include "font-interface.hh"
14 #include "paper-def.hh"
19 TODO revise font handling.
22 * relative sizes should relate to staff-space, eg. font-staff-space
25 * If a relative size is given, lily should magnify the closest
26 design size font to match that. (ie. fonts should have variable
29 (this requires that fonts are stored as (filename , designsize))
36 Font_interface::font_alist_chain (Grob *me)
39 Ugh: why the defaults?
41 SCM defaults = me->get_paper ()->lookup_variable (ly_symbol2scm ("font-defaults"));
43 SCM ch = me->get_property_alist_chain (defaults);
48 MAKE_SCHEME_CALLBACK(Font_interface, get_property_alist_chain, 1);
50 Font_interface::get_property_alist_chain (SCM grob)
53 Grob * g = unsmob_grob (grob);
54 SCM_ASSERT_TYPE(g, grob, SCM_ARG1, __FUNCTION__, "grob");
55 return font_alist_chain (g);
63 todo: split up this func, reuse in text_item?
66 Font_interface::get_default_font (Grob*me)
68 Font_metric * fm = unsmob_metrics (me->get_grob_property ("font"));
72 fm = get_font (me, font_alist_chain (me));
73 me->set_grob_property ("font", fm->self_scm ());
78 LY_DEFINE(ly_font_interface_get_default_font,
79 "ly:get-default-font", 1 , 0, 0,
80 (SCM grob), "Return the default font for grob @var{gr}.")
82 Grob * gr = unsmob_grob (grob);
83 SCM_ASSERT_TYPE(gr, grob, SCM_ARG1, __FUNCTION__, "grob");
85 return Font_interface::get_default_font (gr)->self_scm ();
88 LY_DEFINE(ly_font_interface_get_font,"ly:get-font", 2, 0, 0,
89 (SCM grob, SCM alist),
90 "Return a font metric satisfying the font-qualifiers in @var{alist}.
93 The font object represents the metric information of a font. Every font
94 that is loaded into LilyPond can be accessed via Scheme.
96 LilyPond only needs to know the dimension of glyph to be able to process
97 them. This information is stored in font metric files. LilyPond can read
98 two types of font-metrics: @TeX{} Font Metric files (TFM files) and
99 Adobe Font Metric files (AFM files). LilyPond will always try to load
100 AFM files first since they are more versatile.
104 Grob * gr = unsmob_grob (grob);
105 SCM_ASSERT_TYPE(gr, grob, SCM_ARG1, __FUNCTION__, "grob");
108 Font_interface::get_font (gr, gh_cons (alist,
109 Font_interface::font_alist_chain (gr)));
111 return fm->self_scm();
117 Font_interface::get_font (Grob *me, SCM chain)
119 SCM name = me->get_grob_property ("font-name");
121 if (!gh_string_p (name))
123 Paper_def * p = me->get_paper ();
125 SCM proc = p->lookup_variable (ly_symbol2scm ("properties-to-font"));
126 SCM fonts = p->lookup_variable (ly_symbol2scm ("fonts"));
128 assert (gh_procedure_p (proc));
129 name = gh_call2 (proc, fonts, chain);
132 SCM mag = me->get_grob_property ("font-magnification");
133 Real rmag = gh_number_p (mag) ? gh_scm2double (mag) : 1.0;
135 Font_metric *fm = me->get_paper ()->find_font (name, rmag);
140 Font_interface::add_style (Grob* me, SCM style, SCM chain)
142 assert (gh_symbol_p (style));
144 SCM style_alist = me->get_paper ()->lookup_variable (ly_symbol2scm ("style-alist"));
145 SCM entry = scm_assoc (style, style_alist);
146 if (gh_pair_p (entry))
148 chain = gh_cons (ly_cdr (entry), chain);
156 Interpreting music...
157 MIDI output to wtk1-fugue2.midi...
173 static SCM shape_sym, family_sym, series_sym, rel_str0_sym, design_str0_sym, wild_sym;
179 shape_sym = scm_permanent_object (ly_symbol2scm ("font-shape"));
180 family_sym = scm_permanent_object (ly_symbol2scm ("font-family"));
181 series_sym = scm_permanent_object (ly_symbol2scm ("font-series"));
182 rel_str0_sym = scm_permanent_object (ly_symbol2scm ("font-relative-size"));
183 design_str0_sym = scm_permanent_object (ly_symbol2scm ("font-design-size"));
184 wild_sym = scm_permanent_object (ly_symbol2scm ("*"));
187 ADD_SCM_INIT_FUNC(fi_init_syms, init_syms);
190 Font_interface::wild_compare (SCM field_val, SCM val)
192 return (val == SCM_BOOL_F || field_val == wild_sym || field_val == val);
196 MAKE_SCHEME_CALLBACK (Font_interface,properties_to_font_name,2);
198 Font_interface::properties_to_font_name (SCM fonts, SCM alist_chain)
200 SCM shape = SCM_BOOL_F;
201 SCM family = SCM_BOOL_F;
202 SCM series = SCM_BOOL_F;
205 SCM point_str0 = ly_assoc_chain (design_str0_sym, alist_chain);
206 SCM rel_str0 = SCM_BOOL_F;
208 shape = ly_assoc_chain (shape_sym, alist_chain);
209 family = ly_assoc_chain (family_sym, alist_chain);
210 series = ly_assoc_chain (series_sym, alist_chain);
212 if (gh_pair_p (shape))
213 shape = ly_cdr (shape);
214 if (gh_pair_p (family))
215 family = ly_cdr (family);
216 if (gh_pair_p (series))
217 series = ly_cdr (series);
220 if (gh_pair_p (point_str0))
221 point_str0 = ly_cdr (point_str0);
224 rel_str0 = ly_assoc_chain (rel_str0_sym, alist_chain);
225 if (gh_pair_p (rel_str0))
226 rel_str0 = ly_cdr (rel_str0);
229 for (SCM s = fonts ; gh_pair_p (s); s = ly_cdr (s))
231 SCM qlist = ly_caar (s);
233 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (1)), series))
235 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (2)), shape))
237 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (3)), family))
240 if (point_str0 == SCM_BOOL_F && !wild_compare (ly_car (qlist), rel_str0))
243 SCM qname = ly_cdar (s);
247 warning (_ ("couldn't find any font satisfying "));
248 scm_write (scm_list_n (point_str0, shape, series , family, rel_str0,
249 SCM_UNDEFINED), scm_current_error_port ());
250 scm_flush (scm_current_error_port ());
252 return scm_makfrom0str ("cmr10");
258 ADD_INTERFACE (Font_interface, "font-interface",
259 "Any symbol that is typeset through fixed sets of glyphs (ie. fonts)",
260 "font-magnification font-style font font-series font-shape font-family font-name font-design-size font-relative-size");