2 font-select.cc -- implement property -> font_metric routines.
4 source file of the GNU LilyPond music typesetter
6 (c) 2003--2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
12 #include "paper-def.hh"
13 #include "font-interface.hh"
16 LY_DEFINE (ly_paper_get_font, "ly:paper-get-font", 2, 0, 0,
17 (SCM paper, SCM chain),
18 "Return a font metric satisfying the font-qualifiers in the alist chain @var{chain}.\n"
20 "The font object represents the metric information of a font. Every font\n"
21 "that is loaded into LilyPond can be accessed via Scheme. \n"
23 "LilyPond only needs to know the dimension of glyph to be able to process\n"
24 "them. This information is stored in font metric files. LilyPond can read\n"
25 "two types of font-metrics: @TeX{} Font Metric files (TFM files) and\n"
26 "Adobe Font Metric files (AFM files). LilyPond will always try to load\n"
27 "AFM files first since they are more versatile.\n"
29 "An alist chain is a list of alists, containing grob properties.\n")
31 Paper_def *pap = unsmob_paper (paper);
32 SCM_ASSERT_TYPE (pap, paper, SCM_ARG1, __FUNCTION__, "paper definition");
34 Font_metric *fm = select_font (pap, chain);
35 return fm->self_scm ();
38 LY_DEFINE (ly_paper_get_number, "ly:paper-get-number", 2, 0, 0,
39 (SCM paper, SCM name),
40 "Return the paper variable @var{name}.")
42 Paper_def *pap = unsmob_paper (paper);
43 SCM_ASSERT_TYPE (pap, paper, SCM_ARG1, __FUNCTION__, "paper definition");
44 return gh_double2scm (pap->get_realvar (name));
48 wild_compare (SCM field_val, SCM val)
50 return (val == SCM_BOOL_F || field_val == ly_symbol2scm ("*") || field_val == val);
53 get_font_by_design_size (Paper_def* paper, Real requested,
56 int n = SCM_VECTOR_LENGTH (font_vector);
58 Real last_size = -1e6;
63 size = gh_scm2double (gh_car (SCM_VECTOR_REF (font_vector, i)));
75 if ((requested / last_size) < (size / requested))
82 return paper->find_font (gh_cdr (SCM_VECTOR_REF (font_vector, i)),
88 get_font_by_mag_step (Paper_def* paper, Real requested_step,
89 SCM font_vector, Real default_size)
91 return get_font_by_design_size (paper,
92 default_size * pow (2.0, requested_step / 6.0),
99 We can probably get more efficiency points if we preprocess FONTS
100 to make lookup easier.
103 properties_to_font_size_family (SCM fonts, SCM alist_chain)
105 SCM shape = SCM_BOOL_F;
106 SCM family = SCM_BOOL_F;
107 SCM series = SCM_BOOL_F;
109 shape = ly_assoc_chain (ly_symbol2scm ("font-shape"), alist_chain);
110 family = ly_assoc_chain (ly_symbol2scm ("font-family"), alist_chain);
111 series = ly_assoc_chain (ly_symbol2scm ("font-series"), alist_chain);
113 if (gh_pair_p (shape))
114 shape = ly_cdr (shape);
115 if (gh_pair_p (family))
116 family = ly_cdr (family);
117 if (gh_pair_p (series))
118 series = ly_cdr (series);
121 for (SCM s = fonts ; gh_pair_p (s); s = ly_cdr (s))
123 SCM qlist = ly_caar (s);
125 if (!wild_compare (SCM_VECTOR_REF (qlist, 0), series))
127 if (!wild_compare (SCM_VECTOR_REF (qlist, 1), shape))
129 if (!wild_compare (SCM_VECTOR_REF (qlist, 2), family))
132 SCM qname = ly_cdar (s);
136 warning (_f ("cannot find font for: (%s %s %s)",
137 ly_symbol2string (series).to_str0 (),
138 ly_symbol2string (shape).to_str0 (),
139 ly_symbol2string (family).to_str0 ()));
141 scm_write (scm_list_n (shape, series , family,
142 SCM_UNDEFINED), scm_current_error_port ());
143 scm_flush (scm_current_error_port ());
145 return scm_makfrom0str ("cmr10");
150 select_font (Paper_def *paper, SCM chain)
152 SCM name = ly_assoc_chain (ly_symbol2scm ("font-name"), chain);
154 if (!gh_pair_p (name) || !gh_string_p (gh_cdr (name)))
156 SCM fonts = paper->lookup_variable (ly_symbol2scm ("fonts"));
157 name = properties_to_font_size_family (fonts, chain);
160 name = gh_cdr (name);
163 if (gh_string_p (name))
165 SCM mag = ly_assoc_chain (ly_symbol2scm ("font-magnification"), chain);
167 Real rmag = gh_pair_p (mag) ? robust_scm2double (gh_cdr (mag), 1.0) : 1;
169 return paper->find_font (name, rmag);
171 else if (gh_pair_p (name)) // (DEFAULT . FONT-VEC) pair
173 SCM vec = gh_cdr (name);
174 SCM base_size = gh_car (name);
176 SCM font_size = ly_assoc_chain (ly_symbol2scm ("font-size"), chain);
178 if (gh_pair_p (font_size))
179 req = gh_scm2double (ly_cdr (font_size));
181 return get_font_by_mag_step (paper, req,
182 vec, gh_scm2double (base_size));