lilypond-1.5.10
[lilypond.git] / lily / font-interface.cc
blob0ea3bf7675d25375b7fff9a8e0c4b39ba7fef038
1 /*
2 font-interface.cc -- implement Font_interface
4 source file of the GNU LilyPond music typesetter
6 (c) 2000--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 */
10 #include "all-font-metrics.hh"
11 #include "font-metric.hh"
12 #include "font-interface.hh"
13 #include "grob.hh"
14 #include "paper-def.hh"
15 #include "warn.hh"
19 TODO revise font handling.
22 * relative sizes should relate to staff-space, eg. font-staff-space
23 = 1.2 ^ relative-size
25 * If a relative size is given, lily should magnify the closest
26 design size font to match that. (ie. fonts should have variable
27 scaling)
29 (this requires that fonts are stored as (filename , designsize))
35 SCM
36 Font_interface::font_alist_chain (Grob *me)
38 SCM defaults = gh_cdr (scm_assoc (ly_symbol2scm ("font-defaults"),
39 me->paper_l ()->style_sheet_));
41 SCM ch = gh_list (me->mutable_property_alist_,
42 me->immutable_property_alist_,
43 defaults,
44 SCM_UNDEFINED);
46 return ch;
50 todo: split up this func, reuse in text_item?
52 Font_metric *
53 Font_interface::get_default_font (Grob*me)
55 Font_metric * fm = unsmob_metrics (me->get_grob_property ("font"));
56 if (fm)
57 return fm;
59 fm = get_font (me, font_alist_chain (me));
60 me->set_grob_property ("font", fm->self_scm ());
61 return fm;
65 SCM
66 ly_font_interface_get_default_font (SCM grob)
68 Grob * gr = unsmob_grob (grob);
70 if (!gr)
72 warning ("ly_font_interface_get_default_font (): invalid argument");
73 return SCM_UNDEFINED;
76 return Font_interface::get_default_font (gr)->self_scm ();
79 Font_metric *
80 Font_interface::get_font (Grob *me, SCM chain)
83 SCM ss = me->paper_l ()->style_sheet_;
85 SCM proc = gh_cdr (scm_assoc (ly_symbol2scm ("properties-to-font"),
86 ss));
88 SCM fonts = gh_cdr (scm_assoc (ly_symbol2scm ("fonts"), ss));
90 assert (gh_procedure_p (proc));
91 SCM font_name = gh_call2 (proc, fonts, chain);
93 Font_metric *fm = me->paper_l ()->find_font (font_name, 1.0);
94 return fm;
97 SCM
98 Font_interface::add_style (Grob* me, SCM style, SCM chain)
100 assert (gh_symbol_p (style));
102 SCM sheet = me->paper_l ()->style_sheet_;
104 SCM style_alist = gh_cdr (scm_assoc (ly_symbol2scm ("style-alist"), sheet));
105 SCM entry = scm_assoc (style, style_alist);
106 if (gh_pair_p (entry))
108 chain = gh_cons (gh_cdr (entry), chain);
110 return chain;
114 SCM routines:
116 Interpreting music...
117 MIDI output to wtk1-fugue2.midi...
118 Track ...
120 real 0m31.862s
121 user 0m29.110s
122 sys 0m0.260s
124 real 0m26.964s
125 user 0m24.850s
126 sys 0m0.280s
129 so a 14% speedup.
133 static SCM name_sym, shape_sym, family_sym, series_sym, rel_sz_sym, design_sz_sym, wild_sym;
136 static void
137 init_syms ()
139 name_sym = scm_permanent_object (ly_symbol2scm ("font-name"));
140 shape_sym = scm_permanent_object (ly_symbol2scm ("font-shape"));
141 family_sym = scm_permanent_object (ly_symbol2scm ("font-family"));
142 series_sym = scm_permanent_object (ly_symbol2scm ("font-series"));
143 rel_sz_sym = scm_permanent_object (ly_symbol2scm ("font-relative-size"));
144 design_sz_sym = scm_permanent_object (ly_symbol2scm ("font-design-size"));
145 wild_sym = scm_permanent_object (ly_symbol2scm ("*"));
147 scm_c_define_gsubr ("ly-get-default-font", 1 , 0, 0,
148 (Scheme_function_unknown) ly_font_interface_get_default_font);
152 bool
153 Font_interface::wild_compare (SCM field_val, SCM val)
155 return (val == SCM_BOOL_F || field_val == wild_sym || field_val == val);
158 ADD_SCM_INIT_FUNC (Font_interface_syms,init_syms);
161 MAKE_SCHEME_CALLBACK (Font_interface,properties_to_font_name,2);
163 Font_interface::properties_to_font_name (SCM fonts, SCM alist_chain)
165 SCM name = ly_assoc_chain (name_sym, alist_chain);
167 SCM shape = SCM_BOOL_F;
168 SCM family = SCM_BOOL_F;
169 SCM series = SCM_BOOL_F;
172 SCM point_sz = ly_assoc_chain (design_sz_sym, alist_chain);
173 SCM rel_sz = SCM_BOOL_F;
175 if (!gh_pair_p (name))
177 shape = ly_assoc_chain (shape_sym, alist_chain);
178 family = ly_assoc_chain (family_sym, alist_chain);
179 series = ly_assoc_chain (series_sym, alist_chain);
181 if (gh_pair_p (shape))
182 shape = gh_cdr (shape);
183 if (gh_pair_p (family))
184 family = gh_cdr (family);
185 if (gh_pair_p (series))
186 series = gh_cdr (series);
188 else
189 name = gh_cdr (name);
192 if (gh_pair_p (point_sz))
193 point_sz = gh_cdr (point_sz);
194 else
196 rel_sz = ly_assoc_chain (rel_sz_sym, alist_chain);
197 if (gh_pair_p (rel_sz))
198 rel_sz = gh_cdr (rel_sz);
201 for (SCM s = fonts ; gh_pair_p (s); s = gh_cdr (s))
203 SCM qlist = gh_caar (s);
205 if (name != SCM_BOOL_F)
207 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (4)), name))
208 continue;
210 else
212 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (1)), series))
213 continue;
214 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (2)), shape))
215 continue;
216 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (3)), family))
217 continue;
220 if (point_sz != SCM_BOOL_F)
222 // This if statement will always be true since name must
223 // be SCM_BOOL_F here, right? /MB
224 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (4)), name))
225 continue;
227 else
229 if (!wild_compare (gh_car (qlist), rel_sz))
230 continue;
234 SCM qname = gh_cdar (s);
235 return qname;
238 warning (_ ("couldn't find any font satisfying "));
239 scm_write (gh_list (name, point_sz, shape, series , family, rel_sz, SCM_UNDEFINED), scm_current_error_port ());
240 scm_flush (scm_current_error_port ());
242 return ly_str02scm ("cmr10");