2 text-interface.cc -- implement Text_interface
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 Jan Nieuwenhuizen <janneke@gnu.org>
10 #include "text-interface.hh"
15 #include "pango-font.hh"
18 #include "font-interface.hh"
19 #include "output-def.hh"
20 #include "modified-font-metric.hh"
23 replace_whitespace (string
*str
)
26 vsize n
= str
->size ();
34 if ((cur
& 0x11110000) == 0x11110000)
37 else if ((cur
& 0x11100000) == 0x11100000)
40 else if ((cur
& 0x11000000) == 0x11000000)
42 else if (cur
& 0x10000000)
43 programming_error ("invalid utf-8 string");
45 // avoid the locale-dependent isspace
46 if (cur
== '\n' || cur
== '\t' || cur
== '\v')
53 MAKE_SCHEME_CALLBACK (Text_interface
, interpret_string
, 3);
55 Text_interface::interpret_string (SCM layout_smob
,
59 LY_ASSERT_SMOB (Output_def
, layout_smob
, 1);
60 LY_ASSERT_TYPE (scm_is_string
, markup
, 3);
62 string str
= ly_scm2string (markup
);
63 Output_def
*layout
= unsmob_output_def (layout_smob
);
64 Font_metric
*fm
= select_encoded_font (layout
, props
);
66 replace_whitespace (&str
);
67 return fm
->word_stencil (str
).smobbed_copy ();
70 MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Text_interface
, interpret_markup
, 3, 0,
71 "Convert a text markup into a stencil."
72 " Takes three arguments, @var{layout}, @var{props}, and @var{markup}.\n"
74 "@var{layout} is a @code{\\layout} block; it may be obtained from a grob with"
75 " @code{ly:grob-layout}. @var{props} is a alist chain, ie. a list of alists."
76 " This is typically obtained with"
77 " @code{(ly:grob-alist-chain (ly:layout-lookup layout 'text-font-defaults))}."
78 " @var{markup} is the markup text to be processed.");
80 Text_interface::interpret_markup (SCM layout_smob
, SCM props
, SCM markup
)
82 if (scm_is_string (markup
))
83 return interpret_string (layout_smob
, props
, markup
);
84 else if (scm_is_pair (markup
))
86 SCM func
= scm_car (markup
);
87 SCM args
= scm_cdr (markup
);
88 if (!is_markup (markup
))
89 programming_error ("markup head has no markup signature");
91 return scm_apply_2 (func
, layout_smob
, props
, args
);
95 programming_error ("Object is not a markup. ");
96 scm_puts ("This object should be a markup: ", scm_current_error_port ());
97 scm_display (markup
, scm_current_error_port ());
98 scm_puts ("\n", scm_current_error_port ());
101 b
[X_AXIS
].set_empty ();
102 b
[Y_AXIS
].set_empty ();
104 Stencil
s (b
, SCM_EOL
);
105 return s
.smobbed_copy ();
109 MAKE_SCHEME_CALLBACK (Text_interface
, print
, 1);
111 Text_interface::print (SCM grob
)
113 Grob
*me
= unsmob_grob (grob
);
115 SCM t
= me
->get_property ("text");
116 SCM chain
= Font_interface::text_font_alist_chain (me
);
117 return interpret_markup (me
->layout ()->self_scm (), chain
, t
);
120 /* Ugh. Duplicated from Scheme. */
122 Text_interface::is_markup (SCM x
)
124 return (scm_is_string (x
)
127 != scm_object_property (scm_car (x
),
128 ly_symbol2scm ("markup-signature"))));
132 Text_interface::is_markup_list (SCM x
)
134 SCM music_list_p
= ly_lily_module_constant ("markup-list?");
135 return scm_is_true (scm_call_1 (music_list_p
, x
));
139 ADD_INTERFACE (Text_interface
,
140 "A Scheme markup text, see @ruser{Formatting text} and"
141 " @ruser{New markup command definition}.\n"
143 "There are two important commands:"
144 " @code{ly:text-interface::print}, which is a"
145 " grob callback, and"
146 " @code{ly:text-interface::interpret-markup}.",