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)
52 Grob * g = unsmob_grob (grob);
53 SCM_ASSERT_TYPE(g, grob, SCM_ARG1, __FUNCTION__, "grob");
54 return font_alist_chain (g);
58 todo: split up this func, reuse in text_item?
61 Font_interface::get_default_font (Grob*me)
63 Font_metric * fm = unsmob_metrics (me->get_grob_property ("font"));
67 fm = get_font (me, font_alist_chain (me));
68 me->set_grob_property ("font", fm->self_scm ());
73 LY_DEFINE(ly_font_interface_get_default_font,
74 "ly:get-default-font", 1 , 0, 0,
75 (SCM grob), "Return the default font for grob @var{gr}.")
77 Grob * gr = unsmob_grob (grob);
78 SCM_ASSERT_TYPE(gr, grob, SCM_ARG1, __FUNCTION__, "grob");
80 return Font_interface::get_default_font (gr)->self_scm ();
83 LY_DEFINE(ly_font_interface_get_font,"ly:get-font", 2, 0, 0,
84 (SCM grob, SCM chain),
85 "Return a font metric satisfying the font-qualifiers in the alist chain @var{chain}.\n"
87 "The font object represents the metric information of a font. Every font\n"
88 "that is loaded into LilyPond can be accessed via Scheme. \n"
90 "LilyPond only needs to know the dimension of glyph to be able to process\n"
91 "them. This information is stored in font metric files. LilyPond can read\n"
92 "two types of font-metrics: @TeX{} Font Metric files (TFM files) and\n"
93 "Adobe Font Metric files (AFM files). LilyPond will always try to load\n"
94 "AFM files first since they are more versatile.\n"
96 "An alist chain is a list of alists.\n")
98 Grob * gr = unsmob_grob (grob);
99 SCM_ASSERT_TYPE(gr, grob, SCM_ARG1, __FUNCTION__, "grob");
101 Font_metric*fm = Font_interface::get_font (gr, chain);
102 return fm->self_scm();
107 Font_interface::get_font (Grob *me, SCM chain)
109 SCM name = me->get_grob_property ("font-name");
111 if (!gh_string_p (name))
113 Paper_def * p = me->get_paper ();
115 SCM proc = p->lookup_variable (ly_symbol2scm ("properties-to-font"));
116 SCM fonts = p->lookup_variable (ly_symbol2scm ("fonts"));
118 assert (gh_procedure_p (proc));
119 name = gh_call2 (proc, fonts, chain);
122 SCM mag = me->get_grob_property ("font-magnification");
123 Real rmag = gh_number_p (mag) ? gh_scm2double (mag) : 1.0;
125 Font_metric *fm = me->get_paper ()->find_font (name, rmag);
130 Font_interface::add_style (Grob* me, SCM style, SCM chain)
132 assert (gh_symbol_p (style));
134 SCM style_alist = me->get_paper ()->lookup_variable (ly_symbol2scm ("style-alist"));
135 SCM entry = scm_assoc (style, style_alist);
136 if (gh_pair_p (entry))
138 chain = gh_cons (ly_cdr (entry), chain);
146 Interpreting music...
147 MIDI output to wtk1-fugue2.midi...
163 static SCM shape_sym, family_sym, series_sym, rel_str0_sym, design_str0_sym, wild_sym;
169 shape_sym = scm_permanent_object (ly_symbol2scm ("font-shape"));
170 family_sym = scm_permanent_object (ly_symbol2scm ("font-family"));
171 series_sym = scm_permanent_object (ly_symbol2scm ("font-series"));
172 rel_str0_sym = scm_permanent_object (ly_symbol2scm ("font-relative-size"));
173 design_str0_sym = scm_permanent_object (ly_symbol2scm ("font-design-size"));
174 wild_sym = scm_permanent_object (ly_symbol2scm ("*"));
177 ADD_SCM_INIT_FUNC(fi_init_syms, init_syms);
180 Font_interface::wild_compare (SCM field_val, SCM val)
182 return (val == SCM_BOOL_F || field_val == wild_sym || field_val == val);
186 MAKE_SCHEME_CALLBACK (Font_interface,properties_to_font_name,2);
188 Font_interface::properties_to_font_name (SCM fonts, SCM alist_chain)
190 SCM shape = SCM_BOOL_F;
191 SCM family = SCM_BOOL_F;
192 SCM series = SCM_BOOL_F;
195 SCM point_str0 = ly_assoc_chain (design_str0_sym, alist_chain);
196 SCM rel_str0 = SCM_BOOL_F;
198 shape = ly_assoc_chain (shape_sym, alist_chain);
199 family = ly_assoc_chain (family_sym, alist_chain);
200 series = ly_assoc_chain (series_sym, alist_chain);
202 if (gh_pair_p (shape))
203 shape = ly_cdr (shape);
204 if (gh_pair_p (family))
205 family = ly_cdr (family);
206 if (gh_pair_p (series))
207 series = ly_cdr (series);
210 if (gh_pair_p (point_str0))
211 point_str0 = ly_cdr (point_str0);
214 rel_str0 = ly_assoc_chain (rel_str0_sym, alist_chain);
215 if (gh_pair_p (rel_str0))
216 rel_str0 = ly_cdr (rel_str0);
219 for (SCM s = fonts ; gh_pair_p (s); s = ly_cdr (s))
221 SCM qlist = ly_caar (s);
223 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (1)), series))
225 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (2)), shape))
227 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (3)), family))
230 if (point_str0 == SCM_BOOL_F && !wild_compare (ly_car (qlist), rel_str0))
233 SCM qname = ly_cdar (s);
237 warning (_ ("couldn't find any font satisfying "));
238 scm_write (scm_list_n (point_str0, shape, series , family, rel_str0,
239 SCM_UNDEFINED), scm_current_error_port ());
240 scm_flush (scm_current_error_port ());
242 return scm_makfrom0str ("cmr10");
248 ADD_INTERFACE (Font_interface, "font-interface",
249 "Any symbol that is typeset through fixed sets of glyphs (ie. fonts)",
250 "font-magnification font-style font font-series font-shape font-family font-name font-design-size font-relative-size");