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>
13 #include "all-font-metrics.hh"
14 #include "output-def.hh"
15 #include "font-interface.hh"
18 LY_DEFINE (ly_paper_get_font
, "ly:paper-get-font", 2, 0, 0,
19 (SCM paper
, SCM chain
),
21 "Return a font metric satisfying the font-qualifiers "
22 "in the alist chain @var{chain}.\n"
23 "(An alist chain is a list of alists, containing grob properties).\n")
25 Output_def
*pap
= unsmob_output_def (paper
);
26 SCM_ASSERT_TYPE (pap
, paper
, SCM_ARG1
, __FUNCTION__
, "paper definition");
28 Font_metric
*fm
= select_font (pap
, chain
);
29 return fm
->self_scm ();
32 LY_DEFINE (ly_paper_get_number
, "ly:paper-get-number", 2, 0, 0,
33 (SCM paper
, SCM name
),
34 "Return the paper variable @var{name}.")
36 Output_def
*pap
= unsmob_output_def (paper
);
37 SCM_ASSERT_TYPE (pap
, paper
, SCM_ARG1
, __FUNCTION__
, "paper definition");
38 return scm_make_real (pap
->get_dimension (name
));
42 wild_compare (SCM field_val
, SCM val
)
44 return (val
== SCM_BOOL_F
|| field_val
== ly_symbol2scm ("*") || field_val
== val
);
49 TODO: this triggers a great number of font-loads (feta11 upto
50 parmesan23). We could make a Delayed_load_font_metric for which the
51 design size is specced in advance.
54 get_font_by_design_size (Output_def
* paper
, Real requested
,
55 SCM font_vector
, SCM input_encoding_name
)
57 int n
= SCM_VECTOR_LENGTH (font_vector
);
59 Real last_size
= -1e6
;
64 SCM entry
= SCM_VECTOR_REF (font_vector
, i
);
65 Font_metric
*fm
= unsmob_metrics (scm_force (entry
));
66 size
= fm
->design_size ();
79 if ((requested
/ last_size
) < (size
/ requested
))
86 Font_metric
*fm
= unsmob_metrics (scm_force (SCM_VECTOR_REF (font_vector
, i
)));
88 find_scaled_font (paper
, fm
, requested
/ size
, input_encoding_name
);
94 get_font_by_mag_step (Output_def
* paper
, Real requested_step
,
95 SCM font_vector
, Real default_size
, SCM input_encoding_name
)
97 return get_font_by_design_size (paper
,
98 default_size
* pow (2.0, requested_step
/ 6.0),
99 font_vector
, input_encoding_name
);
105 properties_to_font_size_family (SCM fonts
, SCM alist_chain
)
107 return scm_call_2 (ly_scheme_function ("lookup-font"), fonts
, alist_chain
);
112 select_encoded_font (Output_def
*paper
, SCM chain
, SCM encoding_name
)
114 SCM name
= ly_assoc_chain (ly_symbol2scm ("font-name"), chain
);
116 if (!ly_c_pair_p (name
) || !ly_c_string_p (ly_cdr (name
)))
118 SCM fonts
= paper
->lookup_variable (ly_symbol2scm ("fonts"));
119 name
= properties_to_font_size_family (fonts
, chain
);
122 name
= ly_cdr (name
);
124 if (ly_c_string_p (name
))
126 SCM mag
= ly_assoc_chain (ly_symbol2scm ("font-magnification"), chain
);
128 Real rmag
= ly_c_pair_p (mag
) ? robust_scm2double (ly_cdr (mag
), 1.0) : 1;
130 Font_metric
* fm
= all_fonts_global
->find_font (ly_scm2string (name
));
133 return find_scaled_font (paper
, fm
, rmag
, encoding_name
);
135 else if (scm_instance_p (name
))
137 SCM base_size
= scm_slot_ref (name
, ly_symbol2scm ("default-size"));
138 SCM vec
= scm_slot_ref (name
, ly_symbol2scm ("size-vector"));
140 SCM font_size
= ly_assoc_chain (ly_symbol2scm ("font-size"), chain
);
142 if (ly_c_pair_p (font_size
))
143 req
= ly_scm2double (ly_cdr (font_size
));
145 return get_font_by_mag_step (paper
, req
,
146 vec
, ly_scm2double (base_size
), encoding_name
);
155 select_font (Output_def
*paper
, SCM chain
)
157 return select_encoded_font (paper
, chain
, SCM_EOL
);