X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ftext-item.cc;h=b03027b965ea9304bdc755dc5468d2aa8eb539db;hb=2be67678488b5829a52acdf36ab4278477375b6d;hp=e1085702f950a8fc3e653eb43e2c9c4a2c9099a2;hpb=c5402461ab1d1cdbaa684b0e55d4851f0e28e37a;p=lilypond.git diff --git a/lily/text-item.cc b/lily/text-item.cc index e1085702f9..b03027b965 100644 --- a/lily/text-item.cc +++ b/lily/text-item.cc @@ -3,220 +3,99 @@ source file of the GNU LilyPond music typesetter - (c) 1998--2000 Han-Wen Nienhuys + (c) 1998--2004 Han-Wen Nienhuys Jan Nieuwenhuizen */ #include -#include "debug.hh" +#include "warn.hh" +#include "grob.hh" #include "text-item.hh" -#include "paper-def.hh" -#include "font-metric.hh" -#include "staff-symbol-referencer.hh" -#include "staff-symbol-referencer.hh" -#include "main.hh" -#include "all-font-metrics.hh" -#include "afm.hh" - - -/* - TEXT : STRING | (MARKUP SENTENCE) - MARKUP: PROPERTY | ABBREV - SENTENCE: TEXT | SENTENCE TEXT - PROPERTY: (key . value) - ABBREV: rows lines roman music bold italic named super sub text, or any font-style - */ - -/* - TODO: - - rewrite routines and syntax to be like - - TEXT: STRING - | (head-expression* TEXT*) - ; - - head-expression is a list, containing a tag and a variable number of - arguments. If necessary, the number of arguments can be stored in a alist, - - '( - (tag1 . argcount1) - (tag2 . argcount2) - - ... etc - - ) - - or even entries like - - (tag . (argcount function-to-handle-the-tag )) - - */ - -Molecule -Text_item::text2molecule (Score_element *me, SCM text, SCM alist_chain) -{ - if (gh_string_p (text)) - return string2molecule (me, text, alist_chain); - else if (gh_list_p (text)) - { - if (!gh_pair_p (gh_car (text)) && gh_string_p (gh_car (text))) - return string2molecule (me, gh_car (text), alist_chain); - else - return markup_sentence2molecule (me, text, alist_chain); - } - return Molecule (); -} +#include "font-interface.hh" +#include "virtual-font-metric.hh" +#include "output-def.hh" +#include "scaled-font-metric.hh" +MAKE_SCHEME_CALLBACK (Text_item, interpret_string, 4) SCM -ly_assoc_chain (SCM key, SCM achain) +Text_item::interpret_string (SCM paper, SCM props, SCM encoding, SCM markup) { - if (gh_pair_p (achain)) - { - SCM handle = scm_assoc (key, gh_car (achain)); - if (gh_pair_p (handle)) - return handle; - else - return ly_assoc_chain (key, gh_cdr (achain)); - } - else - return SCM_BOOL_F; -} - -Molecule -Text_item::string2molecule (Score_element *me, SCM text, SCM alist_chain) -{ - SCM style = ly_assoc_chain (ly_symbol2scm ("font-style"), - alist_chain); - if (gh_pair_p (style)) - style = gh_cdr (style); + Output_def *pap = unsmob_output_def (paper); - SCM sheet = me->paper_l ()->style_sheet_; + SCM_ASSERT_TYPE(pap, paper, SCM_ARG1, __FUNCTION__, "Paper definition"); + SCM_ASSERT_TYPE(ly_c_string_p (markup), markup, SCM_ARG3, __FUNCTION__, "string"); + SCM_ASSERT_TYPE(encoding == SCM_EOL + || ly_c_symbol_p (encoding), encoding, SCM_ARG2, __FUNCTION__, "symbol"); - if (gh_symbol_p (style)) + String str = ly_scm2string (markup); + Font_metric *fm = select_encoded_font (pap, props, encoding); + + SCM lst = SCM_EOL; + Box b; + if (Modified_font_metric* mf = dynamic_cast (fm)) { - SCM style_alist = gh_cdr (scm_assoc (ly_symbol2scm ("style-alist"), sheet)); - SCM entry = scm_assoc (style, style_alist); - entry = gh_pair_p (entry) ? gh_cdr (entry) : SCM_EOL; - alist_chain = gh_cons (entry, alist_chain); + lst = scm_list_3 (ly_symbol2scm ("text"), + mf->self_scm (), + markup); + + b = mf->text_dimension (str); } - - SCM fonts = gh_cdr (scm_assoc (ly_symbol2scm ("fonts"), sheet)); - SCM proc = gh_cdr (scm_assoc (ly_symbol2scm ("properties-to-font"), sheet)); - SCM font_name = gh_call2 (proc, fonts, alist_chain); - - SCM lookup = ly_assoc_chain (ly_symbol2scm ("lookup"), alist_chain); - - Molecule mol; - if (gh_pair_p (lookup) && ly_symbol2string (gh_cdr (lookup)) == "name") - mol = lookup_character (me, font_name, text); else - mol = lookup_text (me, font_name, text); - - return mol; -} - -Molecule -Text_item::lookup_character (Score_element *me, SCM font_name, SCM char_name) -{ - Adobe_font_metric *afm = all_fonts_global_p->find_afm (ly_scm2string (font_name)); - - if (!afm) { - warning (_f ("can't find font: `%s'", ly_scm2string (font_name))); - warning (_f ("(search path: `%s')", global_path.str ().ch_C())); - error (_ ("Aborting")); + /* ARGH. */ + programming_error ("Must have Modified_font_metric for text."); } - Font_metric * fm = afm; - - return fm->find_by_name (ly_scm2string (char_name)); + + return Stencil (b, lst).smobbed_copy (); } -Molecule -Text_item::lookup_text (Score_element *me, SCM font_name, SCM text) +MAKE_SCHEME_CALLBACK (Text_item, interpret_markup, 3) +SCM +Text_item::interpret_markup (SCM paper, SCM props, SCM markup) { - SCM magnification = me->get_elt_property ("font-magnification"); - Font_metric* metric = 0; - if (gh_number_p (magnification)) + if (ly_c_string_p (markup)) + return interpret_string (paper, props, SCM_EOL, markup); + else if (ly_c_pair_p (markup)) { - Real realmag = pow (1.2, gh_scm2int (magnification)); - metric = all_fonts_global_p->find_scaled (ly_scm2string (font_name), realmag); + SCM func = ly_car (markup); + SCM args = ly_cdr (markup); + if (!markup_p (markup)) + programming_error ("Markup head has no markup signature."); + + return scm_apply_2 (func, paper, props, args); } - else - metric = all_fonts_global_p->find_font (ly_scm2string (font_name)); - - SCM list = gh_list (ly_symbol2scm ("text"), text, SCM_UNDEFINED); - list = fontify_atom (metric, list); - - return Molecule (metric->text_dimension (ly_scm2string (text)), list); + return SCM_EOL; } -Molecule -Text_item::markup_sentence2molecule (Score_element *me, SCM markup_sentence, - SCM alist_chain) +MAKE_SCHEME_CALLBACK (Text_item,print,1); +SCM +Text_item::print (SCM grob) { - SCM sheet = me->paper_l ()->style_sheet_; - SCM f = gh_cdr (scm_assoc (ly_symbol2scm ("markup-to-properties"), sheet)); - SCM markup = gh_car (markup_sentence); - SCM sentence = gh_cdr (markup_sentence); + Grob *me = unsmob_grob (grob); - SCM p = gh_cons (gh_call2 (f, sheet, markup), alist_chain); - - Axis align = X_AXIS; - SCM a = ly_assoc_chain (ly_symbol2scm ("align"), p); - if (gh_pair_p (a) && gh_number_p (gh_cdr (a))) - align = (Axis)gh_scm2int (gh_cdr (a)); - - Real staff_space = Staff_symbol_referencer::staff_space (me); - Real kern = 0; - SCM k = ly_assoc_chain (ly_symbol2scm ("kern"), p); - if (gh_pair_p (k) && gh_number_p (gh_cdr (k))) - kern = gh_scm2double (gh_cdr (k)) * staff_space; - - Real raise = 0; - SCM r = ly_assoc_chain (ly_symbol2scm ("raise"), p); - if (gh_pair_p (r) && gh_number_p (gh_cdr (r))) - raise = gh_scm2double (gh_cdr (r)) * staff_space; + SCM t = me->get_property ("text"); + SCM chain = Font_interface::text_font_alist_chain (me); + return interpret_markup (me->get_paper ()->self_scm (), chain, t); +} - Offset o (align == X_AXIS ? kern : 0, - (align == Y_AXIS ? - kern : 0) + raise); - Molecule mol; - while (gh_pair_p (sentence)) - { - Molecule m = text2molecule (me, gh_car (sentence), p); - if (!m.empty_b ()) - { - m.translate (o); - mol.add_at_edge (align, align == X_AXIS ? RIGHT : DOWN, m, 0); - } - sentence = gh_cdr (sentence); - } - return mol; +/* + Ugh. Duplicated from Scheme. + */ +bool +Text_item::markup_p (SCM x) +{ + return + ly_c_string_p (x) || + (ly_c_pair_p (x) + && SCM_BOOL_F != scm_object_property (ly_car (x), ly_symbol2scm ("markup-signature"))); } -MAKE_SCHEME_CALLBACK (Text_item, brew_molecule, 1); -SCM -Text_item::brew_molecule (SCM smob) -{ - Score_element *me = unsmob_element (smob); - - SCM text = me->get_elt_property ("text"); +ADD_INTERFACE (Text_item,"text-interface", + "A scheme markup text, see @usermanref{Text-markup}.", + "text baseline-skip word-space"); - SCM properties = gh_list (me->immutable_property_alist_, - me->mutable_property_alist_, SCM_UNDEFINED); - Molecule mol = Text_item::text2molecule (me, text, properties); - SCM space = me->get_elt_property ("word-space"); - if (gh_number_p (space)) - { - Molecule m; - m.set_empty (false); - mol.add_at_edge (X_AXIS, RIGHT, m, gh_scm2double (space) - * Staff_symbol_referencer::staff_space (me)); - } - return mol.create_scheme (); -}