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;
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));
35 Modified_font_metric::make_scaled_font_metric (SCM coding, Font_metric *m, Real s)
37 String scheme = ly_scm2string (coding);
39 Modified_font_metric *sfm = new Modified_font_metric (scheme, m, s);
41 return sfm->self_scm ();
45 Modified_font_metric::design_size () const
47 return orig_->design_size ();
52 Modified_font_metric::get_indexed_char (int i) const
54 Box b = orig_->get_indexed_char (i);
55 b.scale (magnification_);
60 Modified_font_metric::get_ascii_char (int i) const
62 Box b = orig_->get_ascii_char (i);
63 b.scale (magnification_);
68 Modified_font_metric::count () const
70 return orig_->count ();
74 Modified_font_metric::get_indexed_wxwy (int k) const
76 Offset o = orig_->get_indexed_wxwy (k);
77 return o * magnification_;
81 Modified_font_metric::name_to_index (String s) const
83 return orig_->name_to_index (s);
87 Modified_font_metric::index_to_ascii (int k) const
89 return orig_->index_to_ascii (k);
93 Modified_font_metric::coding_scheme () const
95 return coding_scheme_;
99 Modified_font_metric::derived_mark ()
101 scm_gc_mark (coding_vector_);
102 scm_gc_mark (coding_table_);
103 scm_gc_mark (coding_permutation_);
107 Modified_font_metric::tex_kludge (String text) const
113 TODO: put this klutchness behind ly:option switch.
115 for (int i = 0; i < text.length (); i++)
120 // accent marks use width of base letter
121 if (i +1 < text.length ())
123 if (text[i+1]=='\'' || text[i+1]=='`' || text[i+1]=='"' ||
129 // for string width \\ is a \ and \_ is a _.
130 if (text[i+1]=='\\' || text[i+1]=='_')
136 for (i++; (i < text.length ()) && !isspace (text[i])
137 && text[i]!='{' && text[i]!='}'; i++)
141 i--; // Compensate for the increment in the outer loop!
143 case '{': // Skip '{' and '}'
148 Box b = get_ascii_char ((unsigned char)text[i]);
150 // Ugh, use the width of 'x' for unknown characters
151 if (b[X_AXIS].length () == 0)
152 b = get_ascii_char ((unsigned char)'x');
154 w += b[X_AXIS].length ();
155 ydims.unite (b[Y_AXIS]);
160 if (ydims.is_empty ())
161 ydims = Interval (0, 0);
163 return Box (Interval (0, w), ydims);
167 Modified_font_metric::text_dimension (String text)
170 if (coding_scheme_ == "TeX")
172 b = tex_kludge (text);
174 else if (coding_scheme_ == "ASCII"
175 || coding_scheme_ == orig_->coding_scheme ())
181 for (int i = 0; i < text.length (); i++)
183 Box b = get_ascii_char ((unsigned char)text[i]);
185 w += b[X_AXIS].length ();
186 ydims.unite (b[Y_AXIS]);
188 if (ydims.is_empty ())
189 ydims = Interval (0, 0);
191 b = Box(Interval(0,w), ydims);
195 if (!gh_vector_p (coding_vector_))
197 coding_vector_ = scm_call_1 (ly_scheme_function ("get-coding-vector"),
198 scm_makfrom0str (coding_scheme_.to_str0 ()));
200 if (!gh_vector_p (coding_vector_))
202 programming_error ("get-coding-vector should return vector");
203 coding_vector_ = scm_c_make_vector (256, ly_symbol2scm (".notdef"));
206 coding_table_ = scm_call_1 (ly_scheme_function ("get-coding-table"),
207 scm_makfrom0str (orig_->coding_scheme ().to_str0 ()));
209 coding_permutation_ = scm_call_2 (ly_scheme_function ("make-encoding-permutation"),
217 for (int i = 0; i < text.length (); i++)
219 SCM sym = scm_vector_ref (coding_vector_,
220 SCM_MAKINUM((unsigned char) text[i]));
224 if (!gh_symbol_p (sym) && !gh_string_p (sym))
227 char const * chars = gh_symbol_p (sym)
228 ? SCM_SYMBOL_CHARS(sym) : SCM_STRING_CHARS(sym);
231 int idx = orig_->name_to_index (chars);
234 char_box = orig_->get_indexed_char (idx);
237 if (!char_box[X_AXIS].is_empty ())
238 w += char_box[X_AXIS][RIGHT]; // length ?
240 ydims.unite (char_box[Y_AXIS]);
243 if (ydims.is_empty ())
244 ydims = Interval (0, 0);
247 b = Box (Interval (0, w), ydims);
250 b.scale (magnification_);
255 LY_DEFINE (ly_font_enccoding, "ly:font-encoding", 1 , 0, 0,
257 "Given the Modified_font_metric @var{font}, return a "
258 "list containing (input-coding, output-coding, permutation).")
260 Modified_font_metric * fm
261 = dynamic_cast<Modified_font_metric*> (unsmob_metrics (font));
263 SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "Modified_font_metric");
264 return scm_list_3 (fm->coding_vector_,
266 fm->coding_permutation_);