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 todo: split up this func, reuse in text_item?
51 Font_interface::get_default_font (Grob*me)
53 Font_metric * fm = unsmob_metrics (me->get_grob_property ("font"));
57 fm = get_font (me, font_alist_chain (me));
58 me->set_grob_property ("font", fm->self_scm ());
63 LY_DEFINE(ly_font_interface_get_default_font,
64 "ly:get-default-font", 1 , 0, 0,
65 (SCM grob), "Return the default font for grob @var{gr}.")
67 Grob * gr = unsmob_grob (grob);
68 SCM_ASSERT_TYPE(gr, grob, SCM_ARG1, __FUNCTION__, "grob");
70 return Font_interface::get_default_font (gr)->self_scm ();
73 LY_DEFINE(ly_font_interface_get_font,"ly:get-font", 2, 0, 0,
74 (SCM grob, SCM alist),
75 "Return a font metric satisfying the font-qualifiers in @var{alist}.
78 The font object represents the metric information of a font. Every font
79 that is loaded into LilyPond can be accessed via Scheme.
81 LilyPond only needs to know the dimension of glyph to be able to process
82 them. This information is stored in font metric files. LilyPond can read
83 two types of font-metrics: @TeX{} Font Metric files (TFM files) and
84 Adobe Font Metric files (AFM files). LilyPond will always try to load
85 AFM files first since they are more versatile.
89 Grob * gr = unsmob_grob (grob);
90 SCM_ASSERT_TYPE(gr, grob, SCM_ARG1, __FUNCTION__, "grob");
93 Font_interface::get_font (gr, gh_cons (alist,
94 Font_interface::font_alist_chain (gr)));
96 return fm->self_scm();
102 Font_interface::get_font (Grob *me, SCM chain)
104 SCM name = me->get_grob_property ("font-name");
106 if (!gh_string_p (name))
108 Paper_def * p = me->get_paper ();
110 SCM proc = p->lookup_variable (ly_symbol2scm ("properties-to-font"));
111 SCM fonts = p->lookup_variable (ly_symbol2scm ("fonts"));
113 assert (gh_procedure_p (proc));
114 name = gh_call2 (proc, fonts, chain);
117 SCM mag = me->get_grob_property ("font-magnification");
118 Real rmag = gh_number_p (mag) ? gh_scm2double (mag) : 1.0;
120 Font_metric *fm = me->get_paper ()->find_font (name, rmag);
125 Font_interface::add_style (Grob* me, SCM style, SCM chain)
127 assert (gh_symbol_p (style));
129 SCM style_alist = me->get_paper ()->lookup_variable (ly_symbol2scm ("style-alist"));
130 SCM entry = scm_assoc (style, style_alist);
131 if (gh_pair_p (entry))
133 chain = gh_cons (ly_cdr (entry), chain);
141 Interpreting music...
142 MIDI output to wtk1-fugue2.midi...
158 static SCM shape_sym, family_sym, series_sym, rel_str0_sym, design_str0_sym, wild_sym;
164 shape_sym = scm_permanent_object (ly_symbol2scm ("font-shape"));
165 family_sym = scm_permanent_object (ly_symbol2scm ("font-family"));
166 series_sym = scm_permanent_object (ly_symbol2scm ("font-series"));
167 rel_str0_sym = scm_permanent_object (ly_symbol2scm ("font-relative-size"));
168 design_str0_sym = scm_permanent_object (ly_symbol2scm ("font-design-size"));
169 wild_sym = scm_permanent_object (ly_symbol2scm ("*"));
172 ADD_SCM_INIT_FUNC(fi_init_syms, init_syms);
175 Font_interface::wild_compare (SCM field_val, SCM val)
177 return (val == SCM_BOOL_F || field_val == wild_sym || field_val == val);
181 MAKE_SCHEME_CALLBACK (Font_interface,properties_to_font_name,2);
183 Font_interface::properties_to_font_name (SCM fonts, SCM alist_chain)
185 SCM shape = SCM_BOOL_F;
186 SCM family = SCM_BOOL_F;
187 SCM series = SCM_BOOL_F;
190 SCM point_str0 = ly_assoc_chain (design_str0_sym, alist_chain);
191 SCM rel_str0 = SCM_BOOL_F;
193 shape = ly_assoc_chain (shape_sym, alist_chain);
194 family = ly_assoc_chain (family_sym, alist_chain);
195 series = ly_assoc_chain (series_sym, alist_chain);
197 if (gh_pair_p (shape))
198 shape = ly_cdr (shape);
199 if (gh_pair_p (family))
200 family = ly_cdr (family);
201 if (gh_pair_p (series))
202 series = ly_cdr (series);
205 if (gh_pair_p (point_str0))
206 point_str0 = ly_cdr (point_str0);
209 rel_str0 = ly_assoc_chain (rel_str0_sym, alist_chain);
210 if (gh_pair_p (rel_str0))
211 rel_str0 = ly_cdr (rel_str0);
214 for (SCM s = fonts ; gh_pair_p (s); s = ly_cdr (s))
216 SCM qlist = ly_caar (s);
218 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (1)), series))
220 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (2)), shape))
222 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (3)), family))
225 if (point_str0 == SCM_BOOL_F && !wild_compare (ly_car (qlist), rel_str0))
228 SCM qname = ly_cdar (s);
232 warning (_ ("couldn't find any font satisfying "));
233 scm_write (scm_list_n (point_str0, shape, series , family, rel_str0,
234 SCM_UNDEFINED), scm_current_error_port ());
235 scm_flush (scm_current_error_port ());
237 return scm_makfrom0str ("cmr10");
243 ADD_INTERFACE (Font_interface, "font-interface",
244 "Any symbol that is typeset through fixed sets of glyphs (ie. fonts)",
245 "font-magnification font-style font font-series font-shape font-family font-name font-design-size font-relative-size");