(process_acknowledged_grobs):
[lilypond.git] / lily / font-select.cc
blob2890b629dbe6de7a98011e6261df8b742b5cfdd5
1 #include "paper-def.hh"
2 #include "font-interface.hh"
3 #include "warn.hh"
6 /*
7 TODO revise font handling.
10 * relative sizes should relate to staff-space, eg. font-staff-space
11 = 1.2 ^ relative-size
13 * If a relative size is given, lily should magnify the closest
14 design size font to match that. (ie. fonts should have variable
15 scaling)
17 (this requires that fonts are stored as (filename , designsize))
26 LY_DEFINE(ly_paper_get_font,"ly:paper-get-font", 2, 0, 0,
27 (SCM paper, SCM chain),
28 "Return a font metric satisfying the font-qualifiers in the alist chain @var{chain}.\n"
29 "\n"
30 "The font object represents the metric information of a font. Every font\n"
31 "that is loaded into LilyPond can be accessed via Scheme. \n"
32 "\n"
33 "LilyPond only needs to know the dimension of glyph to be able to process\n"
34 "them. This information is stored in font metric files. LilyPond can read\n"
35 "two types of font-metrics: @TeX{} Font Metric files (TFM files) and\n"
36 "Adobe Font Metric files (AFM files). LilyPond will always try to load\n"
37 "AFM files first since they are more versatile.\n"
38 "\n"
39 "An alist chain is a list of alists, containing grob properties.\n")
41 Paper_def *pap = unsmob_paper (paper);
42 SCM_ASSERT_TYPE(pap, paper, SCM_ARG1, __FUNCTION__, "paper definition");
44 Font_metric*fm = select_font (pap, chain);
45 return fm->self_scm();
49 bool
50 wild_compare (SCM field_val, SCM val)
52 return (val == SCM_BOOL_F || field_val == ly_symbol2scm ("*") || field_val == val);
56 We can probably get more efficiency points if we preprocess FONTS
57 to make lookup easier.
59 SCM
60 properties_to_font_name (SCM fonts, SCM alist_chain)
62 SCM shape = SCM_BOOL_F;
63 SCM family = SCM_BOOL_F;
64 SCM series = SCM_BOOL_F;
67 SCM point_sz = ly_assoc_chain (ly_symbol2scm ("font-design-size"), alist_chain);
68 SCM rel_sz = SCM_BOOL_F;
70 shape = ly_assoc_chain (ly_symbol2scm ("font-shape"), alist_chain);
71 family = ly_assoc_chain (ly_symbol2scm ("font-family"), alist_chain);
72 series = ly_assoc_chain (ly_symbol2scm ("font-series"), alist_chain);
74 if (gh_pair_p (shape))
75 shape = ly_cdr (shape);
76 if (gh_pair_p (family))
77 family = ly_cdr (family);
78 if (gh_pair_p (series))
79 series = ly_cdr (series);
82 if (gh_pair_p (point_sz))
83 point_sz = ly_cdr (point_sz);
84 else
86 rel_sz = ly_assoc_chain (ly_symbol2scm ("font-relative-size"), alist_chain);
87 if (gh_pair_p (rel_sz))
88 rel_sz = ly_cdr (rel_sz);
91 for (SCM s = fonts ; gh_pair_p (s); s = ly_cdr (s))
93 SCM qlist = ly_caar (s);
95 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (1)), series))
96 continue;
97 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (2)), shape))
98 continue;
99 if (!wild_compare (scm_list_ref (qlist, gh_int2scm (3)), family))
100 continue;
102 if (point_sz == SCM_BOOL_F && !wild_compare (ly_car (qlist), rel_sz))
103 continue;
105 SCM qname = ly_cdar (s);
106 return qname;
109 warning (_ ("couldn't find any font satisfying "));
110 scm_write (scm_list_n (point_sz, shape, series , family, rel_sz,
111 SCM_UNDEFINED), scm_current_error_port ());
112 scm_flush (scm_current_error_port ());
114 return scm_makfrom0str ("cmr10");
119 Font_metric *
120 select_font (Paper_def *paper, SCM chain)
122 SCM name = ly_assoc_chain (ly_symbol2scm ("font-name"), chain);
124 if (!gh_pair_p (name) || !gh_string_p (gh_cdr (name)))
126 SCM fonts = paper->lookup_variable (ly_symbol2scm ("fonts"));
127 name = properties_to_font_name (fonts, chain);
129 else
130 name = gh_cdr (name);
132 SCM mag = ly_assoc_chain (ly_symbol2scm ("font-magnification"), chain);
134 Real rmag = gh_pair_p (mag) && gh_number_p (gh_cdr (mag))
135 ? gh_scm2double (gh_cdr (mag)) : 1.0;
137 Font_metric *fm = paper->find_font (name, rmag);
138 return fm;