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_permutation_ = SCM_EOL;
21 coding_table_ = SCM_EOL;
22 coding_permutation_ = SCM_EOL;
23 coding_scheme_ = coding;
24 magnification_ = magn;
25 SCM desc = m->description_;
27 Real total_mag = magn * gh_scm2double (ly_cdr (desc));
30 description_ = gh_cons (ly_car (desc), gh_double2scm (total_mag));
33 if (coding_scheme_ != "TeX"
34 && coding_scheme_ != "ASCII"
35 && coding_scheme_ != orig_->coding_scheme ())
37 coding_vector_ = scm_call_1 (ly_scheme_function ("get-coding-vector"),
38 scm_makfrom0str (coding_scheme_.to_str0 ()));
40 if (!gh_vector_p (coding_vector_))
42 programming_error ("get-coding-vector should return vector");
43 coding_vector_ = scm_c_make_vector (256, ly_symbol2scm (".notdef"));
47 coding_table_ = scm_call_1 (ly_scheme_function ("get-coding-table"),
48 scm_makfrom0str (orig_->coding_scheme ().to_str0 ()));
50 coding_permutation_ = scm_call_2 (ly_scheme_function ("make-encoding-permutation"),
54 coding_description_= scm_list_5 (scm_makfrom0str (coding_scheme_.to_str0 ()),
56 scm_makfrom0str (orig_->coding_scheme ().to_str0 ()),
63 coding_permutation_ = scm_vector (coding_description_);
69 Modified_font_metric::make_scaled_font_metric (SCM coding, Font_metric *m, Real s)
71 String scheme = ly_scm2string (coding);
73 Modified_font_metric *sfm = new Modified_font_metric (scheme, m, s);
75 return sfm->self_scm ();
79 Modified_font_metric::design_size () const
81 return orig_->design_size ();
86 Modified_font_metric::get_indexed_char (int i) const
88 Box b = orig_->get_indexed_char (i);
89 b.scale (magnification_);
94 Modified_font_metric::get_ascii_char (int i) const
96 Box b = orig_->get_ascii_char (i);
97 b.scale (magnification_);
102 Modified_font_metric::count () const
104 return orig_->count ();
108 Modified_font_metric::get_indexed_wxwy (int k) const
110 Offset o = orig_->get_indexed_wxwy (k);
111 return o * magnification_;
115 Modified_font_metric::name_to_index (String s) const
117 return orig_->name_to_index (s);
121 Modified_font_metric::index_to_ascii (int k) const
123 return orig_->index_to_ascii (k);
127 Modified_font_metric::coding_scheme () const
129 return coding_scheme_;
133 Modified_font_metric::derived_mark ()
135 scm_gc_mark (coding_vector_);
136 scm_gc_mark (coding_description_);
137 scm_gc_mark (coding_table_);
138 scm_gc_mark (coding_permutation_);
142 Modified_font_metric::tex_kludge (String text) const
148 TODO: put this klutchness behind ly:option switch.
150 for (int i = 0; i < text.length (); i++)
155 // accent marks use width of base letter
156 if (i +1 < text.length ())
158 if (text[i+1]=='\'' || text[i+1]=='`' || text[i+1]=='"' ||
164 // for string width \\ is a \ and \_ is a _.
165 if (text[i+1]=='\\' || text[i+1]=='_')
171 for (i++; (i < text.length ()) && !isspace (text[i])
172 && text[i]!='{' && text[i]!='}'; i++)
176 i--; // Compensate for the increment in the outer loop!
178 case '{': // Skip '{' and '}'
183 Box b = get_ascii_char ((unsigned char)text[i]);
185 // Ugh, use the width of 'x' for unknown characters
186 if (b[X_AXIS].length () == 0)
187 b = get_ascii_char ((unsigned char)'x');
189 w += b[X_AXIS].length ();
190 ydims.unite (b[Y_AXIS]);
195 if (ydims.is_empty ())
196 ydims = Interval (0, 0);
198 return Box (Interval (0, w), ydims);
202 Modified_font_metric::text_dimension (String text)
205 if (coding_scheme_ == "TeX")
207 b = tex_kludge (text);
209 else if (coding_scheme_ == "ASCII"
210 || coding_scheme_ == orig_->coding_scheme ())
216 for (int i = 0; i < text.length (); i++)
218 Box b = get_ascii_char ((unsigned char)text[i]);
220 w += b[X_AXIS].length ();
221 ydims.unite (b[Y_AXIS]);
223 if (ydims.is_empty ())
224 ydims = Interval (0, 0);
226 b = Box(Interval(0,w), ydims);
233 for (int i = 0; i < text.length (); i++)
235 SCM sym = scm_vector_ref (coding_vector_,
236 SCM_MAKINUM((unsigned char) text[i]));
240 if (!gh_symbol_p (sym))
243 char const * chars = SCM_SYMBOL_CHARS(sym);
245 int idx = orig_->name_to_index (chars);
248 char_box = orig_->get_indexed_char (idx);
251 if (!char_box[X_AXIS].is_empty ())
252 w += char_box[X_AXIS][RIGHT]; // length ?
254 ydims.unite (char_box[Y_AXIS]);
257 if (ydims.is_empty ())
258 ydims = Interval (0, 0);
261 b = Box (Interval (0, w), ydims);
264 b.scale (magnification_);
268 LY_DEFINE (ly_font_encoding, "ly:font-encoding",
271 "Given the Modified_font_metric @var{font}, return a "
272 "vector containing (input-coding-name, input-coding, "
273 "output-coding-name, output-coding, permutation).")
275 Modified_font_metric *fm
276 = dynamic_cast<Modified_font_metric*> (unsmob_metrics (font));
278 SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "Modified_font_metric");
279 return fm->coding_description_;
282 LY_DEFINE (ly_font_coding_name, "ly:font-coding-name",
285 "Return the CODING-NAME of the Modified_font_metric @var{font}.")
287 Modified_font_metric *fm
288 = dynamic_cast<Modified_font_metric*> (unsmob_metrics (font));
290 SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "Modified_font_metric");
291 return scm_makfrom0str (fm->coding_scheme ().to_str0 ());