2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 1998--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
5 Jan Nieuwenhuizen <janneke@gnu.org>
7 LilyPond is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 LilyPond is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
21 #include "text-interface.hh"
24 #include "font-interface.hh"
28 #include "modified-font-metric.hh"
29 #include "output-def.hh"
30 #include "pango-font.hh"
34 replace_whitespace (string *str)
37 vsize n = str->size ();
43 // avoid the locale-dependent isspace
44 if (cur == '\n' || cur == '\t' || cur == '\v')
47 vsize char_len = utf8_char_len (cur);
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);
69 We want to use "glyph-string" in the SVG backend for all
70 music fonts (Emmentaler and Aybabtu) that pass through the
71 text interface. Here the font encoding is checked to see if
72 it matches one of the music font encodings. --pmccarty
74 SCM encoding = ly_chain_assoc_get (ly_symbol2scm ("font-encoding"),
77 SCM music_encodings = ly_lily_module_constant ("all-music-font-encodings");
79 if (scm_memq (encoding, music_encodings) != SCM_BOOL_F)
80 return fm->word_stencil (str, true).smobbed_copy ();
82 return fm->word_stencil (str, false).smobbed_copy ();
85 MAKE_SCHEME_CALLBACK_WITH_OPTARGS (Text_interface, interpret_markup, 3, 0,
86 "Convert a text markup into a stencil."
87 " Takes three arguments, @var{layout}, @var{props}, and @var{markup}.\n"
89 "@var{layout} is a @code{\\layout} block; it may be obtained from a grob with"
90 " @code{ly:grob-layout}. @var{props} is an alist chain, i.e. a list of"
91 " alists. This is typically obtained with"
92 " @code{(ly:grob-alist-chain grob (ly:output-def-lookup layout 'text-font-defaults))}."
93 " @var{markup} is the markup text to be processed.");
95 Text_interface::interpret_markup (SCM layout_smob, SCM props, SCM markup)
97 if (scm_is_string (markup))
98 return interpret_string (layout_smob, props, markup);
99 else if (scm_is_pair (markup))
101 SCM func = scm_car (markup);
102 SCM args = scm_cdr (markup);
103 if (!is_markup (markup))
104 programming_error ("markup head has no markup signature");
106 return scm_apply_2 (func, layout_smob, props, args);
110 programming_error ("Object is not a markup. ");
111 scm_puts ("This object should be a markup: ", scm_current_error_port ());
112 scm_display (markup, scm_current_error_port ());
113 scm_puts ("\n", scm_current_error_port ());
116 b[X_AXIS].set_empty ();
117 b[Y_AXIS].set_empty ();
119 Stencil s (b, SCM_EOL);
120 return s.smobbed_copy ();
124 MAKE_SCHEME_CALLBACK (Text_interface, print, 1);
126 Text_interface::print (SCM grob)
128 Grob *me = unsmob_grob (grob);
130 SCM t = me->get_property ("text");
131 SCM chain = Font_interface::text_font_alist_chain (me);
132 return interpret_markup (me->layout ()->self_scm (), chain, t);
135 /* Ugh. Duplicated from Scheme. */
137 Text_interface::is_markup (SCM x)
139 return (scm_is_string (x)
142 != scm_object_property (scm_car (x),
143 ly_symbol2scm ("markup-signature"))));
147 Text_interface::is_markup_list (SCM x)
149 SCM music_list_p = ly_lily_module_constant ("markup-list?");
150 return scm_is_true (scm_call_1 (music_list_p, x));
154 ADD_INTERFACE (Text_interface,
155 "A Scheme markup text, see @ruser{Formatting text} and"
156 " @rextend{New markup command definition}.\n"
158 "There are two important commands:"
159 " @code{ly:text-interface::print}, which is a"
160 " grob callback, and"
161 " @code{ly:text-interface::interpret-markup}.",