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 = ly_cdr (scm_assoc (ly_symbol2scm ("font-defaults"),
42 me->paper_l ()->style_sheet_));
44 SCM ch = scm_list_n (me->mutable_property_alist_,
45 me->immutable_property_alist_,
53 todo: split up this func, reuse in text_item?
56 Font_interface::get_default_font (Grob*me)
58 Font_metric * fm = unsmob_metrics (me->get_grob_property ("font"));
62 fm = get_font (me, font_alist_chain (me));
63 me->set_grob_property ("font", fm->self_scm ());
68 LY_DEFINE(ly_font_interface_get_default_font,
69 "ly-get-default-font", 1 , 0, 0,
70 (SCM grob), "Return the default font for grob @var{gr}.")
72 Grob * gr = unsmob_grob (grob);
73 SCM_ASSERT_TYPE(gr, grob, SCM_ARG1, __FUNCTION__, "grob");
75 return Font_interface::get_default_font (gr)->self_scm ();
78 LY_DEFINE(ly_font_interface_get_font,"ly-get-font", 2, 0, 0,
79 (SCM grob, SCM alist),
80 "Return a font metric satisfying the font-qualifiers in @var{alist}.
83 The font object represents the metric information of a font. Every font
84 that is loaded into LilyPond can be accessed via Scheme.
86 LilyPond only needs to know the dimension of glyph to be able to process
87 them. This information is stored in font metric files. LilyPond can read
88 two types of font-metrics: @TeX{} Font Metric files (TFM files) and
89 Adobe Font Metric files (AFM files). LilyPond will always try to load
90 AFM files first since they are more versatile.
94 Grob * gr = unsmob_grob (grob);
95 SCM_ASSERT_TYPE(gr, grob, SCM_ARG1, __FUNCTION__, "grob");
98 Font_interface::get_font (gr, gh_cons (alist,
99 Font_interface::font_alist_chain (gr)));
101 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 SCM ss = me->paper_l ()->style_sheet_;
115 SCM proc = ly_cdr (scm_assoc (ly_symbol2scm ("properties-to-font"),
118 SCM fonts = ly_cdr (scm_assoc (ly_symbol2scm ("fonts"), ss));
120 assert (gh_procedure_p (proc));
121 name = gh_call2 (proc, fonts, chain);
124 SCM mag = me->get_grob_property ("font-magnification");
125 Real rmag = gh_number_p (mag) ? gh_scm2double (mag) : 1.0;
127 Font_metric *fm = me->paper_l ()->find_font (name, rmag);
132 Font_interface::add_style (Grob* me, SCM style, SCM chain)
134 assert (gh_symbol_p (style));
136 SCM sheet = me->paper_l ()->style_sheet_;
138 SCM style_alist = ly_cdr (scm_assoc (ly_symbol2scm ("style-alist"), sheet));
139 SCM entry = scm_assoc (style, style_alist);
140 if (gh_pair_p (entry))
142 chain = gh_cons (ly_cdr (entry), chain);
150 Interpreting music...
151 MIDI output to wtk1-fugue2.midi...
167 static SCM shape_sym, family_sym, series_sym, rel_sz_sym, design_sz_sym, wild_sym;
173 shape_sym = scm_permanent_object (ly_symbol2scm ("font-shape"));
174 family_sym = scm_permanent_object (ly_symbol2scm ("font-family"));
175 series_sym = scm_permanent_object (ly_symbol2scm ("font-series"));
176 rel_sz_sym = scm_permanent_object (ly_symbol2scm ("font-relative-size"));
177 design_sz_sym = scm_permanent_object (ly_symbol2scm ("font-design-size"));
178 wild_sym = scm_permanent_object (ly_symbol2scm ("*"));
181 ADD_SCM_INIT_FUNC(fi_init_syms, init_syms);
184 Font_interface::wild_compare (SCM field_val, SCM val)
186 return (val == SCM_BOOL_F || field_val == wild_sym || field_val == val);
190 MAKE_SCHEME_CALLBACK (Font_interface,properties_to_font_name,2);
192 Font_interface::properties_to_font_name (SCM fonts, SCM alist_chain)
194 SCM shape = SCM_BOOL_F;
195 SCM family = SCM_BOOL_F;
196 SCM series = SCM_BOOL_F;
199 SCM point_sz = ly_assoc_chain (design_sz_sym, alist_chain);
200 SCM rel_sz = SCM_BOOL_F;
202 shape = ly_assoc_chain (shape_sym, alist_chain);
203 family = ly_assoc_chain (family_sym, alist_chain);
204 series = ly_assoc_chain (series_sym, alist_chain);
206 if (gh_pair_p (shape))
207 shape = ly_cdr (shape);
208 if (gh_pair_p (family))
209 family = ly_cdr (family);
210 if (gh_pair_p (series))
211 series = ly_cdr (series);
214 if (gh_pair_p (point_sz))
215 point_sz = ly_cdr (point_sz);
218 rel_sz = ly_assoc_chain (rel_sz_sym, alist_chain);
219 if (gh_pair_p (rel_sz))
220 rel_sz = ly_cdr (rel_sz);
223 for (SCM s = fonts ; gh_pair_p (s); s = ly_cdr (s))
225 SCM qlist = ly_caar (s);
227 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (1)), series))
229 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (2)), shape))
231 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (3)), family))
234 if (point_sz == SCM_BOOL_F && !wild_compare (ly_car (qlist), rel_sz))
237 SCM qname = ly_cdar (s);
241 warning (_ ("couldn't find any font satisfying "));
242 scm_write (scm_list_n (point_sz, shape, series , family, rel_sz, SCM_UNDEFINED), scm_current_error_port ());
243 scm_flush (scm_current_error_port ());
245 return ly_str02scm ("cmr10");
251 ADD_INTERFACE (Font_interface, "font-interface",
252 "Any symbol that is typeset through fixed sets of glyphs (ie. fonts)",
253 "font-magnification font-style font font-series font-shape font-family font-name font-design-size font-relative-size");