2 modified-font-metric.cc -- declare Modified_font_metric
4 source file of the GNU LilyPond music typesetter
6 (c) 1999--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include "modified-font-metric.hh"
10 #include "pango-font.hh"
17 Modified_font_metric::Modified_font_metric (Font_metric *fm,
20 String input_encoding)
22 input_encoding_ = input_encoding;
23 coding_vector_ = SCM_EOL;
24 coding_mapping_ = SCM_EOL;
25 coding_table_ = SCM_EOL;
26 coding_description_ = SCM_EOL;
27 magnification_ = magnification;
29 SCM desc = fm->description_;
31 Real total_mag = magnification * scm_to_double (scm_cdr (desc));
34 description_ = scm_cons (scm_car (desc), scm_make_real (total_mag));
37 String metric_coding = orig_->coding_scheme ();
38 if (metric_coding != "FontSpecific"
39 && metric_coding != font_encoding)
40 warning (_f ("conflicting metric coding (%s) and font_encoding (%s)",
41 metric_coding, font_encoding));
43 if (input_encoding_ != ""
44 && input_encoding_ != "TeX"
45 && input_encoding_ != "ASCII"
46 && input_encoding_ != font_encoding)
48 coding_vector_ = scm_call_1 (ly_scheme_function ("get-coding-vector"),
49 scm_makfrom0str (font_encoding.to_str0 ()));
51 if (!ly_c_vector_p (coding_vector_))
53 programming_error ("get-coding-vector should return vector");
54 coding_vector_ = scm_c_make_vector (256, ly_symbol2scm (".notdef"));
57 coding_table_ = scm_call_1 (ly_scheme_function ("get-coding-table"),
58 scm_makfrom0str (font_encoding.to_str0 ()));
61 = scm_call_2 (ly_scheme_function ("make-encoding-mapping"),
65 coding_description_ = SCM_EOL;
67 = scm_acons (ly_symbol2scm ("input-name"),
68 scm_makfrom0str (input_encoding_.to_str0 ()),
71 = scm_acons (ly_symbol2scm ("input-vector"),
72 coding_vector_, coding_description_);
74 = scm_acons (ly_symbol2scm ("output-name"),
75 scm_makfrom0str (orig_->coding_scheme ().to_str0 ()),
78 = scm_acons (ly_symbol2scm ("output-table"),
82 = scm_acons (ly_symbol2scm ("char-mapping"),
89 Modified_font_metric::make_scaled_font_metric (Font_metric *fm, Real scaling,
96 if (scm_is_symbol (input_encoding))
97 input_encoding = scm_symbol_to_string (input_encoding);
99 String font_encoding_str = ly_symbol2string (font_encoding);
100 String input_encoding_str
101 = scm_is_string (input_encoding) ? ly_scm2string (input_encoding) : "";
103 Modified_font_metric *sfm = new Modified_font_metric (fm, scaling,
106 return sfm->self_scm ();
110 Modified_font_metric::design_size () const
112 return orig_->design_size ();
117 Modified_font_metric::get_indexed_char (int i) const
119 Box b = orig_->get_indexed_char (i);
120 b.scale (magnification_);
125 Modified_font_metric::get_ascii_char (int i) const
127 Box b = orig_->get_ascii_char (i);
128 b.scale (magnification_);
133 Modified_font_metric::count () const
135 return orig_->count ();
139 Modified_font_metric::attachment_point (String s) const
141 Offset o = orig_->attachment_point (s);
142 return o * magnification_;
146 Modified_font_metric::get_indexed_wxwy (int k) const
148 Offset o = orig_->get_indexed_wxwy (k);
149 return o * magnification_;
153 Modified_font_metric::name_to_index (String s) const
155 return orig_->name_to_index (s);
159 Modified_font_metric::index_to_charcode (int i) const
161 return orig_->index_to_charcode (i);
165 Modified_font_metric::index_to_ascii (int k) const
167 return orig_->index_to_ascii (k);
171 Modified_font_metric::coding_scheme () const
173 return input_encoding_;
177 Modified_font_metric::derived_mark () const
179 scm_gc_mark (coding_vector_);
180 scm_gc_mark (coding_description_);
181 scm_gc_mark (coding_table_);
182 scm_gc_mark (coding_mapping_);
185 /* TODO: put this klutchness behind ly:option switch. */
187 Modified_font_metric::tex_kludge (String text) const
191 for (int i = 0; i < text.length (); i++)
196 /* Accent marks use width of base letter */
197 if (i +1 < text.length ())
199 if (text[i+1]=='\'' || text[i+1]=='`' || text[i+1]=='"'
205 /* For string width \\ is a \ and \_ is a _. */
206 if (text[i+1]=='\\' || text[i+1]=='_')
210 for (i++; (i < text.length ()) && !isspace (text[i])
211 && text[i]!='{' && text[i]!='}'; i++)
214 /* Compensate for the auto-increment in the outer loop. */
218 case '{': // Skip '{' and '}'
223 Box b = get_ascii_char ((unsigned char)text[i]);
225 /* Use the width of 'x' for unknown characters */
226 if (b[X_AXIS].length () == 0)
227 b = get_ascii_char ((unsigned char)'x');
229 w += b[X_AXIS].length ();
230 ydims.unite (b[Y_AXIS]);
235 if (ydims.is_empty ())
236 ydims = Interval (0, 0);
238 return Box (Interval (0, w), ydims);
242 Modified_font_metric::text_stencil (String text) const
245 if (Pango_font * pf = dynamic_cast<Pango_font*> (orig_))
247 Stencil stc = pf->text_stencil (text);
249 Box b = stc.extent_box ();
251 b.scale (magnification_);
252 return Stencil (b, stc.expr());
255 return Font_metric::text_stencil (text);
259 Modified_font_metric::text_dimension (String text) const
262 if (input_encoding_ == "TeX")
263 b = tex_kludge (text);
264 else if (input_encoding_ == "ASCII"
265 || input_encoding_ == ""
266 || input_encoding_ == orig_->coding_scheme ())
272 for (int i = 0; i < text.length (); i++)
274 Box b = get_ascii_char ((unsigned char)text[i]);
276 w += b[X_AXIS].length ();
277 ydims.unite (b[Y_AXIS]);
279 if (ydims.is_empty ())
280 ydims = Interval (0, 0);
282 b = Box(Interval(0,w), ydims);
289 for (int i = 0; i < text.length (); i++)
291 SCM sym = scm_vector_ref (coding_vector_,
292 scm_from_int((unsigned char) text[i]));
296 if (!scm_is_symbol (sym))
299 char const *chars = scm_i_string_chars (scm_symbol_to_string (sym));
301 int idx = orig_->name_to_index (chars);
303 char_box = orig_->get_indexed_char (idx);
305 char_box.scale (magnification_);
306 if (!char_box[X_AXIS].is_empty ())
308 w += char_box[X_AXIS][RIGHT];
310 ydims.unite (char_box[Y_AXIS]);
313 if (ydims.is_empty ())
314 ydims = Interval (0, 0);
316 b = Box (Interval (0, w), ydims);
323 Modified_font_metric::original_font () const
329 LY_DEFINE (ly_font_encoding_alist, "ly:font-encoding-alist",
332 "Given the Modified_font_metric @var{font}, return an "
333 "alist. Keys are input-name, input-vector, "
334 "output-name, output-table, mapping.")
336 Modified_font_metric *fm
337 = dynamic_cast<Modified_font_metric*> (unsmob_metrics (font));
339 SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "Modified_font_metric");
340 return fm->coding_description_;
343 LY_DEFINE (ly_font_encoding, "ly:font-encoding",
346 "Return encoding of @var{font}.")
348 Modified_font_metric *fm
349 = dynamic_cast<Modified_font_metric*> (unsmob_metrics (font));
350 SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "Modified_font_metric");
351 return ly_symbol2scm (fm->original_font ()->coding_scheme ().to_str0 ());
355 Modified_font_metric::sub_fonts () const
357 return orig_->sub_fonts();
361 Modified_font_metric::font_name () const
363 return original_font ()->font_name();