2 font-select.cc -- implement property -> font_metric routines.
4 source file of the GNU LilyPond music typesetter
6 (c) 2003 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();
40 wild_compare (SCM field_val, SCM val)
42 return (val == SCM_BOOL_F || field_val == ly_symbol2scm ("*") || field_val == val);
45 get_font_by_design_size (Paper_def* paper, Real requested,
48 int n = SCM_VECTOR_LENGTH (font_vector);
50 Real last_size = -1e6;
55 size = gh_scm2double (gh_car (SCM_VECTOR_REF (font_vector, i)));
67 if ((requested / last_size) < (size / requested))
74 return paper->find_font (gh_cdr (SCM_VECTOR_REF (font_vector, i)),
80 get_font_by_mag_step (Paper_def* paper, Real requested_step,
81 SCM font_vector, Real default_size)
83 return get_font_by_design_size (paper,
84 default_size * pow (2.0, requested_step / 6.0),
91 We can probably get more efficiency points if we preprocess FONTS
92 to make lookup easier.
95 properties_to_font_size_family (SCM fonts, SCM alist_chain)
97 SCM shape = SCM_BOOL_F;
98 SCM family = SCM_BOOL_F;
99 SCM series = SCM_BOOL_F;
101 shape = ly_assoc_chain (ly_symbol2scm ("font-shape"), alist_chain);
102 family = ly_assoc_chain (ly_symbol2scm ("font-family"), alist_chain);
103 series = ly_assoc_chain (ly_symbol2scm ("font-series"), alist_chain);
105 if (gh_pair_p (shape))
106 shape = ly_cdr (shape);
107 if (gh_pair_p (family))
108 family = ly_cdr (family);
109 if (gh_pair_p (series))
110 series = ly_cdr (series);
113 for (SCM s = fonts ; gh_pair_p (s); s = ly_cdr (s))
115 SCM qlist = ly_caar (s);
117 if (!wild_compare (SCM_VECTOR_REF (qlist, 0), series))
119 if (!wild_compare (SCM_VECTOR_REF (qlist, 1), shape))
121 if (!wild_compare (SCM_VECTOR_REF (qlist, 2), family))
124 SCM qname = ly_cdar (s);
128 warning (_ ("couldn't find any font size family satisfying "));
130 scm_write (scm_list_n (shape, series , family,
131 SCM_UNDEFINED), scm_current_error_port ());
132 scm_flush (scm_current_error_port ());
134 return scm_makfrom0str ("cmr10");
139 select_font (Paper_def *paper, SCM chain)
141 SCM name = ly_assoc_chain (ly_symbol2scm ("font-name"), chain);
143 if (!gh_pair_p (name) || !gh_string_p (gh_cdr (name)))
145 SCM fonts = paper->lookup_variable (ly_symbol2scm ("fonts"));
146 name = properties_to_font_size_family (fonts, chain);
149 name = gh_cdr (name);
152 if (gh_string_p (name))
154 SCM mag = ly_assoc_chain (ly_symbol2scm ("font-magnification"), chain);
156 Real rmag = gh_pair_p (mag) && gh_number_p (gh_cdr (mag))
157 ? gh_scm2double (gh_cdr (mag)) : 1.0;
159 return paper->find_font (name, rmag);
161 else if (gh_pair_p (name)) // (DEFAULT . FONT-VEC) pair
163 SCM vec = gh_cdr (name);
164 SCM base_size = gh_car (name);
166 SCM font_size = ly_assoc_chain (ly_symbol2scm ("font-size"), chain);
168 if (gh_pair_p (font_size))
169 req = gh_scm2double (ly_cdr (font_size));
171 return get_font_by_mag_step (paper, req,
172 vec, gh_scm2double (base_size));