]> git.donarmstrong.com Git - lilypond.git/blob - lily/font-interface.cc
* mf/parmesan-clefs.mf: use # quantities for char_box
[lilypond.git] / lily / font-interface.cc
1 /*   
2   font-interface.cc --  implement Font_interface
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 2000--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
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"
16
17
18 /*
19   TODO revise font handling.
20
21
22 * relative sizes should relate to staff-space, eg.  font-staff-space
23 = 1.2 ^ relative-size
24
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)
28
29 (this requires that fonts are stored as (filename , designsize))
30
31
32   
33  */
34
35 SCM
36 Font_interface::font_alist_chain (Grob *me)
37 {
38   /*
39     Ugh: why the defaults?
40    */
41   SCM defaults = me->get_paper ()->lookup_variable (ly_symbol2scm ("font-defaults"));
42
43   SCM ch = me->get_property_alist_chain (defaults);
44   return ch;
45 }
46
47
48 MAKE_SCHEME_CALLBACK(Font_interface, get_property_alist_chain, 1);
49 SCM
50 Font_interface::get_property_alist_chain (SCM grob)
51 {
52   Grob * g = unsmob_grob (grob);
53   SCM_ASSERT_TYPE(g, grob, SCM_ARG1, __FUNCTION__, "grob");
54   return  font_alist_chain (g);
55 }
56
57 /*
58   todo: split up this func, reuse in text_item? 
59  */
60 Font_metric *
61 Font_interface::get_default_font (Grob*me)
62 {
63   Font_metric * fm =  unsmob_metrics (me->get_grob_property ("font"));
64   if (fm)
65     return fm;
66
67   fm = get_font (me->get_paper (),  font_alist_chain (me));
68   me->set_grob_property ("font", fm->self_scm ());
69   return fm;
70 }
71
72
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}.")
76 {
77   Grob * gr  = unsmob_grob (grob);
78   SCM_ASSERT_TYPE(gr, grob, SCM_ARG1, __FUNCTION__, "grob");
79
80   return Font_interface::get_default_font (gr)->self_scm ();
81 }
82
83
84 Font_metric *
85 Font_interface::get_font (Paper_def *paper, SCM chain)
86 {
87   SCM name = ly_assoc_chain (ly_symbol2scm  ("font-name"), chain);
88   
89   if (!gh_pair_p (name) || !gh_string_p (gh_cdr (name)))
90     {
91       SCM proc = paper->lookup_variable (ly_symbol2scm ("properties-to-font"));
92       SCM fonts = paper->lookup_variable (ly_symbol2scm ("fonts"));
93
94       assert (gh_procedure_p (proc));
95       name = gh_call2 (proc, fonts, chain);
96     }
97   else
98     name  = gh_cdr (name);
99   
100   SCM mag = ly_assoc_chain (ly_symbol2scm ("font-magnification"), chain);
101   
102   Real rmag = gh_pair_p (mag) && gh_number_p (gh_cdr (mag))
103     ? gh_scm2double (gh_cdr (mag)) : 1.0;
104   
105   Font_metric *fm = paper->find_font (name, rmag);
106   return fm;
107 }
108
109 /*
110 SCM routines for looking up fonts.
111
112 wtk-fugue2, SCM:
113
114 real    0m31.862s
115 user    0m29.110s
116 sys     0m0.260s
117
118 wtk-fugue2, C++:
119
120 real    0m26.964s
121 user    0m24.850s
122 sys     0m0.280s
123
124
125 so a 14% speedup.
126
127 */
128
129 static SCM shape_sym, family_sym, series_sym, rel_str0_sym, design_str0_sym, wild_sym;
130
131
132 static void
133 init_syms ()
134 {
135   shape_sym  = scm_permanent_object (ly_symbol2scm ("font-shape"));
136   family_sym = scm_permanent_object (ly_symbol2scm ("font-family"));
137   series_sym = scm_permanent_object (ly_symbol2scm ("font-series"));
138   rel_str0_sym = scm_permanent_object (ly_symbol2scm ("font-relative-size"));
139   design_str0_sym = scm_permanent_object (ly_symbol2scm ("font-design-size"));
140   wild_sym = scm_permanent_object (ly_symbol2scm ("*"));
141 }
142
143 ADD_SCM_INIT_FUNC(fi_init_syms, init_syms);
144
145 bool
146 Font_interface::wild_compare (SCM field_val, SCM val)
147 {
148   return (val == SCM_BOOL_F || field_val == wild_sym || field_val == val);
149 }
150
151
152 MAKE_SCHEME_CALLBACK (Font_interface,properties_to_font_name,2);
153 SCM
154 Font_interface::properties_to_font_name (SCM fonts, SCM alist_chain)
155 {
156   SCM shape = SCM_BOOL_F;
157   SCM family = SCM_BOOL_F;
158   SCM series = SCM_BOOL_F;
159
160   
161   SCM point_str0 = ly_assoc_chain (design_str0_sym, alist_chain);
162   SCM rel_str0 = SCM_BOOL_F;
163
164   shape = ly_assoc_chain (shape_sym, alist_chain);
165   family = ly_assoc_chain (family_sym, alist_chain);
166   series = ly_assoc_chain (series_sym, alist_chain);
167
168   if (gh_pair_p (shape))
169     shape = ly_cdr (shape);
170   if (gh_pair_p (family))
171     family = ly_cdr (family);
172   if (gh_pair_p (series))
173     series = ly_cdr (series);
174
175
176   if (gh_pair_p (point_str0))
177     point_str0 = ly_cdr (point_str0);
178   else
179     {
180       rel_str0 = ly_assoc_chain (rel_str0_sym, alist_chain);
181       if (gh_pair_p (rel_str0))
182         rel_str0 = ly_cdr (rel_str0);
183     }
184
185   for (SCM s = fonts ; gh_pair_p (s); s = ly_cdr (s))
186     {
187       SCM qlist = ly_caar (s);
188
189       if (!wild_compare (scm_list_ref (qlist, gh_int2scm (1)), series))
190         continue;
191       if (!wild_compare (scm_list_ref (qlist, gh_int2scm (2)), shape))
192         continue;
193       if (!wild_compare (scm_list_ref (qlist, gh_int2scm (3)), family))
194         continue;
195   
196       if (point_str0 == SCM_BOOL_F && !wild_compare (ly_car (qlist), rel_str0))
197         continue;
198           
199       SCM qname = ly_cdar (s);
200       return qname;
201     }
202
203   warning (_ ("couldn't find any font satisfying "));
204   scm_write (scm_list_n (point_str0, shape, series , family, rel_str0,
205                          SCM_UNDEFINED), scm_current_error_port ());
206   scm_flush (scm_current_error_port ());
207  
208   return scm_makfrom0str ("cmr10");
209   
210 }
211
212
213
214 ADD_INTERFACE (Font_interface, "font-interface",
215   "Any symbol that is typeset through fixed sets of glyphs (ie. fonts)",
216   "font-magnification font font-series font-shape font-family font-name font-design-size font-relative-size");