X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Ffont-metric.cc;h=a1c0f72bff479983fe3967615dbd22e9f2d61163;hb=955f829883aa125b2b633b1e71f6256da5b773fa;hp=8c8a8e31a7f28e6062ff505971fc5ab0da123f12;hpb=82731e802565546441c401a84a13b486e54eb760;p=lilypond.git diff --git a/lily/font-metric.cc b/lily/font-metric.cc index 8c8a8e31a7..a1c0f72bff 100644 --- a/lily/font-metric.cc +++ b/lily/font-metric.cc @@ -3,15 +3,19 @@ source file of the GNU LilyPond music typesetter - (c) 1999 Han-Wen Nienhuys - + (c) 1999--2003 Han-Wen Nienhuys + + Mats Bengtsson (the ugly TeX parsing in text_dimension) */ #include #include - +#include "warn.hh" +#include "molecule.hh" +#include "ly-smobs.icc" #include "font-metric.hh" +#include "string.hh" Box Font_metric::text_dimension (String text) const @@ -19,82 +23,172 @@ Font_metric::text_dimension (String text) const Interval ydims; Real w=0.0; - for (int i = 0; i < text.length_i (); i++) + for (int i = 0; i < text.length (); i++) { - if (text[i]=='\\') + switch (text[i]) { - for (i++; (i < text.length_i ()) && isalpha(text[i]); i++) + case '\\': + // accent marks use width of base letter + if (i +1 < text.length ()) + { + if (text[i+1]=='\'' || text[i+1]=='`' || text[i+1]=='"' || + text[i+1]=='^') + { + i++; + break; + } + // for string width \\ is a \ and \_ is a _. + if (text[i+1]=='\\' || text[i+1]=='_') + { + break; + } + } + + for (i++; (i < text.length ()) && !isspace (text[i]) + && text[i]!='{' && text[i]!='}'; i++) ; // ugh. i--; // Compensate for the increment in the outer loop! - } - else - { - Character_metric const *c = get_char ((unsigned char)text[i],false); - + break; + case '{': // Skip '{' and '}' + case '}': + break; + + default: + Box b = get_char ((unsigned char)text[i]); + // Ugh, use the width of 'x' for unknown characters - if (c->dimensions()[X_AXIS].length () == 0) - c = get_char ((unsigned char)'x',false); + if (b[X_AXIS].length () == 0) + b = get_char ((unsigned char)'x'); - w += c->dimensions()[X_AXIS].length (); - ydims.unite (c->dimensions()[Y_AXIS]); + w += b[X_AXIS].length (); + ydims.unite (b[Y_AXIS]); + break; } } if (ydims.empty_b ()) ydims = Interval (0,0); - return Box(Interval (0, w), ydims); + return Box (Interval (0, w), ydims); } -Box -Scaled_font_metric::text_dimension (String t) const + +Font_metric::~Font_metric () { - Real realmag = pow (1.2, magstep_i_); - Box b (orig_l_->text_dimension (t)); +} - return Box(b[X_AXIS]* realmag, b[Y_AXIS]*realmag); +Font_metric::Font_metric () +{ + description_ = SCM_EOL; + self_scm_ = SCM_EOL; + smobify_self (); } +Font_metric::Font_metric (Font_metric const &) +{ +} -Box -Character_metric::dimensions () const +int +Font_metric::count () const { - return Box(Interval(0,0), Interval(0,0)); + return 0; } -Font_metric::~Font_metric () +Box +Font_metric::get_char (int)const +{ + return Box (Interval (0,0),Interval (0,0)); +} + + +void +Font_metric::derived_mark ()const { + } -Character_metric::~Character_metric() + + +SCM +Font_metric::mark_smob (SCM s) { + Font_metric * m = (Font_metric*) SCM_CELL_WORD_1 (s); + + m->derived_mark(); + return m->description_; } -Character_metric const * -Font_metric::get_char (int, bool)const +int +Font_metric::print_smob (SCM s, SCM port, scm_print_state *) { - return 0; + Font_metric *m = unsmob_metrics (s); + scm_puts ("#description_, port); + scm_puts (">", port); + return 1; } -Scaled_font_metric::Scaled_font_metric (Font_metric* m, int s) + + +IMPLEMENT_SMOBS (Font_metric); +IMPLEMENT_DEFAULT_EQUAL_P (Font_metric); +IMPLEMENT_TYPE_P (Font_metric, "ly:font-metric?"); + +Molecule +Font_metric::find_by_name (String) const { - magstep_i_ = s; - orig_l_ = m; + Molecule m ; + return m; } -SCM -Font_metric::description () const +LY_DEFINE(ly_find_glyph_by_name, "ly:find-glyph-by-name", 2 , 0, 0, + (SCM font, SCM name), + "This function retrieves a Molecule for the glyph named @var{name} in " +"@var{font}. The font must be available as an AFM file.") { - return gh_cons (ly_symbol2scm (name_str_.ch_C()), gh_int2scm (0)); + Font_metric *fm = unsmob_metrics (font); + SCM_ASSERT_TYPE(fm, font, SCM_ARG1, __FUNCTION__, "font-metric"); + SCM_ASSERT_TYPE(gh_string_p (name), name, SCM_ARG2, __FUNCTION__, "string"); + + return fm->find_by_name (ly_scm2string (name)).smobbed_copy (); } +LY_DEFINE(ly_get_glyph, "ly:get-glyph", 2 , 0, 0, + (SCM font, SCM index), + "This function retrieves a Molecule for the glyph numbered @var{index} in " +"@var{font}. ") +{ + Font_metric *fm = unsmob_metrics (font); + SCM_ASSERT_TYPE(fm, font, SCM_ARG1, __FUNCTION__, "font-metric"); + SCM_ASSERT_TYPE(gh_number_p (index), index, SCM_ARG2, __FUNCTION__, "number"); -SCM -Scaled_font_metric::description () const + return fm->get_char_molecule (gh_scm2int (index)).smobbed_copy (); +} + +LY_DEFINE(ly_text_dimension,"ly:text-dimension", 2 , 0, 0, + (SCM font, SCM text), + "Given the font metric in @var{font} and the string @var{text}, compute " +"the extents of that text in that font. The return value is a pair of " +"number-pairs.") +{ + Box b; + Font_metric *fm = unsmob_metrics (font); + SCM_ASSERT_TYPE(fm, font, SCM_ARG1, __FUNCTION__, "font-metric"); + SCM_ASSERT_TYPE(gh_string_p (text), text, SCM_ARG2, __FUNCTION__, "string"); + + b = fm->text_dimension (ly_scm2string (text)); + + return gh_cons (ly_interval2scm (b[X_AXIS]), ly_interval2scm(b[Y_AXIS])); +} + +Molecule +Font_metric::get_char_molecule (int code) const { - SCM od = orig_l_->description (); - gh_set_cdr_x (od, gh_int2scm (magstep_i_)); - return od; + SCM at = scm_list_n (ly_symbol2scm ("char"), gh_int2scm (code), + SCM_UNDEFINED); + at = fontify_atom (this, at); + Box b = get_char (code); + return Molecule (b, at); }