2 scaled-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>
13 #include "scaled-font-metric.hh"
17 Modified_font_metric::Modified_font_metric (String coding, Font_metric* m, Real magn)
19 coding_vector_ = SCM_EOL;
20 coding_mapping_ = SCM_EOL;
21 coding_table_ = SCM_EOL;
22 coding_description_ = SCM_EOL;
24 coding_scheme_ = coding;
25 magnification_ = magn;
27 SCM desc = m->description_;
29 Real total_mag = magn * ly_scm2double (ly_cdr (desc));
32 description_ = scm_cons (ly_car (desc), scm_make_real (total_mag));
35 if (coding_scheme_ != ""
36 && coding_scheme_ != "TeX"
37 && coding_scheme_ != "ASCII"
38 && coding_scheme_ != orig_->coding_scheme ())
40 coding_vector_ = scm_call_1 (ly_scheme_function ("get-coding-vector"),
41 scm_makfrom0str (coding_scheme_.to_str0 ()));
43 if (!ly_c_vector_p (coding_vector_))
45 programming_error ("get-coding-vector should return vector");
46 coding_vector_ = scm_c_make_vector (256, ly_symbol2scm (".notdef"));
50 coding_table_ = scm_call_1 (ly_scheme_function ("get-coding-table"),
51 scm_makfrom0str (orig_->coding_scheme ().to_str0 ()));
53 coding_mapping_ = scm_call_2 (ly_scheme_function ("make-encoding-mapping"),
57 coding_description_= SCM_EOL;
58 coding_description_ = scm_acons (ly_symbol2scm ("input-name"),
59 scm_makfrom0str (coding_scheme_.to_str0 ()),
61 coding_description_ = scm_acons (ly_symbol2scm ("input-vector"),
62 coding_vector_, coding_description_);
63 coding_description_ = scm_acons (ly_symbol2scm ("output-name"),
64 scm_makfrom0str (orig_->coding_scheme ().to_str0 ()),
66 coding_description_ = scm_acons (ly_symbol2scm ("output-table"),
69 coding_description_ = scm_acons (ly_symbol2scm ("char-mapping"),
77 LY_DEFINE (ly_font_encoding_alist, "ly:font-encoding-alist",
80 "Given the Modified_font_metric @var{font}, return an "
81 "alist. Keys are input-name, input-vector, "
82 "output-name, output-table, mapping.")
84 Modified_font_metric *fm
85 = dynamic_cast<Modified_font_metric*> (unsmob_metrics (font));
87 SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "Modified_font_metric");
88 return fm->coding_description_;
92 Modified_font_metric::make_scaled_font_metric (SCM coding, Font_metric *m, Real s)
97 if (ly_c_symbol_p (coding))
98 coding = scm_symbol_to_string (coding);
100 String scheme = ly_c_string_p (coding) ? ly_scm2string (coding) : "";
102 Modified_font_metric *sfm = new Modified_font_metric (scheme, m, s);
104 return sfm->self_scm ();
108 Modified_font_metric::design_size () const
110 return orig_->design_size ();
115 Modified_font_metric::get_indexed_char (int i) const
117 Box b = orig_->get_indexed_char (i);
118 b.scale (magnification_);
123 Modified_font_metric::get_ascii_char (int i) const
125 Box b = orig_->get_ascii_char (i);
126 b.scale (magnification_);
131 Modified_font_metric::count () const
133 return orig_->count ();
137 Modified_font_metric::get_indexed_wxwy (int k) const
139 Offset o = orig_->get_indexed_wxwy (k);
140 return o * magnification_;
144 Modified_font_metric::name_to_index (String s) const
146 return orig_->name_to_index (s);
150 Modified_font_metric::index_to_ascii (int k) const
152 return orig_->index_to_ascii (k);
156 Modified_font_metric::coding_scheme () const
158 return coding_scheme_;
162 Modified_font_metric::derived_mark () const
164 scm_gc_mark (coding_vector_);
165 scm_gc_mark (coding_description_);
166 scm_gc_mark (coding_table_);
167 scm_gc_mark (coding_mapping_);
171 Modified_font_metric::tex_kludge (String text) const
177 TODO: put this klutchness behind ly:option switch.
179 for (int i = 0; i < text.length (); i++)
184 // accent marks use width of base letter
185 if (i +1 < text.length ())
187 if (text[i+1]=='\'' || text[i+1]=='`' || text[i+1]=='"' ||
193 // for string width \\ is a \ and \_ is a _.
194 if (text[i+1]=='\\' || text[i+1]=='_')
200 for (i++; (i < text.length ()) && !isspace (text[i])
201 && text[i]!='{' && text[i]!='}'; i++)
205 i--; // Compensate for the increment in the outer loop!
207 case '{': // Skip '{' and '}'
212 Box b = get_ascii_char ((unsigned char)text[i]);
214 // Ugh, use the width of 'x' for unknown characters
215 if (b[X_AXIS].length () == 0)
216 b = get_ascii_char ((unsigned char)'x');
218 w += b[X_AXIS].length ();
219 ydims.unite (b[Y_AXIS]);
224 if (ydims.is_empty ())
225 ydims = Interval (0, 0);
227 return Box (Interval (0, w), ydims);
231 Modified_font_metric::text_dimension (String text)
234 if (coding_scheme_ == "TeX")
236 b = tex_kludge (text);
238 else if (coding_scheme_ == "ASCII"
239 || coding_scheme_ == ""
240 || coding_scheme_ == orig_->coding_scheme ())
246 for (int i = 0; i < text.length (); i++)
248 Box b = get_ascii_char ((unsigned char)text[i]);
250 w += b[X_AXIS].length ();
251 ydims.unite (b[Y_AXIS]);
253 if (ydims.is_empty ())
254 ydims = Interval (0, 0);
256 b = Box(Interval(0,w), ydims);
263 for (int i = 0; i < text.length (); i++)
265 SCM sym = scm_vector_ref (coding_vector_,
266 scm_from_int((unsigned char) text[i]));
270 if (!ly_c_symbol_p (sym))
273 char const * chars = SCM_SYMBOL_CHARS(sym);
275 int idx = orig_->name_to_index (chars);
278 char_box = orig_->get_indexed_char (idx);
281 char_box.scale (magnification_);
282 if (!char_box[X_AXIS].is_empty ())
283 w += char_box[X_AXIS][RIGHT]; // length ?
285 ydims.unite (char_box[Y_AXIS]);
288 if (ydims.is_empty ())
289 ydims = Interval (0, 0);
292 b = Box (Interval (0, w), ydims);
299 Modified_font_metric::original_font () const