2 text-item.cc -- implement Text_item
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 Jan Nieuwenhuizen <janneke@gnu.org>
12 #include "text-item.hh"
13 #include "paper-def.hh"
14 #include "font-interface.hh"
15 #include "staff-symbol-referencer.hh"
16 #include "staff-symbol-referencer.hh"
18 #include "all-font-metrics.hh"
23 TEXT : STRING | (MARKUP SENTENCE)
24 MARKUP: PROPERTY | ABBREV
25 SENTENCE: TEXT | SENTENCE TEXT
26 PROPERTY: (key . value)
27 ABBREV: rows lines roman music bold italic named super sub text, or any font-style
33 rewrite routines and syntax to be like
36 | (head-expression* TEXT*)
39 head-expression is a list, containing a tag and a variable number of
40 arguments. If necessary, the number of arguments can be stored in a alist,
52 (tag . (argcount function-to-handle-the-tag ))
57 Text_item::text2molecule (Score_element
*me
, SCM text
, SCM alist_chain
)
59 if (gh_string_p (text
))
60 return string2molecule (me
, text
, alist_chain
);
61 else if (gh_list_p (text
))
63 if (!gh_pair_p (gh_car (text
)) && gh_string_p (gh_car (text
)))
64 return string2molecule (me
, gh_car (text
), alist_chain
);
66 return markup_sentence2molecule (me
, text
, alist_chain
);
72 ly_assoc_chain (SCM key
, SCM achain
)
74 if (gh_pair_p (achain
))
76 SCM handle
= scm_assoc (key
, gh_car (achain
));
77 if (gh_pair_p (handle
))
80 return ly_assoc_chain (key
, gh_cdr (achain
));
87 Text_item::string2molecule (Score_element
*me
, SCM text
, SCM alist_chain
)
89 SCM style
= ly_assoc_chain (ly_symbol2scm ("font-style"),
91 if (gh_pair_p (style
))
92 style
= gh_cdr (style
);
94 SCM sheet
= me
->paper_l ()->style_sheet_
;
96 if (gh_symbol_p (style
))
98 SCM style_alist
= gh_cdr (scm_assoc (ly_symbol2scm ("style-alist"), sheet
));
99 SCM entry
= scm_assoc (style
, style_alist
);
100 entry
= gh_pair_p (entry
) ? gh_cdr (entry
) : SCM_EOL
;
101 alist_chain
= gh_cons (entry
, alist_chain
);
104 SCM fonts
= gh_cdr (scm_assoc (ly_symbol2scm ("fonts"), sheet
));
105 SCM proc
= gh_cdr (scm_assoc (ly_symbol2scm ("properties-to-font"), sheet
));
106 SCM font_name
= gh_call2 (proc
, fonts
, alist_chain
);
109 SCM lookup
= scm_assoc (ly_symbol2scm ("lookup"), properties
);
112 if (gh_pair_p (lookup
) && ly_symbol2string (gh_cdr (lookup
)) == "name")
113 mol
= lookup_character (me
, font_name
, text
);
116 Molecule mol
= lookup_text (me
, font_name
, text
);
122 Text_item::lookup_character (Score_element
*, SCM font_name
, SCM char_name
)
124 Adobe_font_metric
*afm
= all_fonts_global_p
->find_afm (ly_scm2string (font_name
));
128 warning (_f ("can't find font: `%s'", ly_scm2string (font_name
)));
129 warning (_f ("(search path: `%s')", global_path
.str ().ch_C()));
130 error (_ ("Aborting"));
132 Font_metric
* fm
= afm
;
134 return fm
->find_by_name (ly_scm2string (char_name
));
139 Text_item::lookup_text (Score_element
*me
, SCM font_name
, SCM text
)
141 SCM magnification
= me
->get_elt_property ("font-magnification");
142 Font_metric
* metric
= 0;
143 if (gh_number_p (magnification
))
146 Real realmag
= pow (1.2, gh_scm2int (magnification
));
147 metric
= all_fonts_global_p
->find_scaled (ly_scm2string (font_name
), realmag
);
152 metric
= me
->paper_l ()->find_font (font_name
, 1.0);
154 SCM list
= gh_list (ly_symbol2scm ("text"), text
, SCM_UNDEFINED
);
155 list
= fontify_atom (metric
, list
);
157 return Molecule (metric
->text_dimension (ly_scm2string (text
)), list
);
161 Text_item::markup_sentence2molecule (Score_element
*me
, SCM markup_sentence
,
169 SCM sheet
= me
->paper_l ()->style_sheet_
;
170 SCM f
= gh_cdr (scm_assoc (ly_symbol2scm ("markup-abbrev-to-properties-alist"), sheet
));
172 SCM markup
= gh_car (markup_sentence
);
173 SCM sentence
= gh_cdr (markup_sentence
);
175 SCM p
= gh_cons (gh_call1 (f
, markup
), alist_chain
);
178 SCM a
= scm_assoc (ly_symbol2scm ("align"), p
);
179 if (gh_pair_p (a
) && gh_number_p (gh_cdr (a
)))
180 align
= (Axis
)gh_scm2int (gh_cdr (a
));
182 Real staff_space
= Staff_symbol_referencer::staff_space (me
);
184 SCM k
= scm_assoc (ly_symbol2scm ("kern"), p
);
185 if (gh_pair_p (k
) && gh_number_p (gh_cdr (k
)))
186 kern
= gh_scm2double (gh_cdr (k
)) * staff_space
;
189 SCM r
= scm_assoc (ly_symbol2scm ("raise"), p
);
190 if (gh_pair_p (r
) && gh_number_p (gh_cdr (r
)))
191 raise
= gh_scm2double (gh_cdr (r
)) * staff_space
;
193 Offset
o (align
== X_AXIS
? kern
: 0,
194 (align
== Y_AXIS
? - kern
: 0) + raise
);
197 while (gh_pair_p (sentence
))
199 Molecule m
= text2molecule (me
, gh_car (sentence
), p
);
203 mol
.add_at_edge (align
, align
== X_AXIS
? RIGHT
: DOWN
, m
, 0);
205 sentence
= gh_cdr (sentence
);
210 MAKE_SCHEME_CALLBACK (Text_item
, brew_molecule
, 1);
212 Text_item::brew_molecule (SCM smob
)
214 Score_element
*me
= unsmob_element (smob
);
216 SCM text
= me
->get_elt_property ("text");
218 SCM properties
= gh_list (me
->immutable_property_alist_
,
219 me
->mutable_property_alist_
, SCM_UNDEFINED
);
221 Molecule mol
= Text_item::text2molecule (me
, text
, properties
);
223 SCM space
= me
->get_elt_property ("word-space");
224 if (gh_number_p (space
))
228 mol
.add_at_edge (X_AXIS
, RIGHT
, m
, gh_scm2double (space
)
229 * Staff_symbol_referencer::staff_space (me
));
231 return mol
.create_scheme ();