From 9f127ca14c9af5c0956a7ac82b7b15cd67fd7d57 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Tue, 6 Apr 2004 01:07:11 +0000 Subject: [PATCH] * lily/scaled-font-metric.cc (text_dimension): move function from Font_metric (make_scaled_font_metric): init coding_scheme_ to TeX (text_dimension): use get-coding-vector for non TeX coding_scheme_ * lily/include/scaled-font-metric.hh (struct Modified_font_metric): rename from Scaled_font_metric * scm/encoding.scm (read-encoding-file): split up large function, leave caching to (delay) --- ChangeLog | 8 ++ lily/font-metric.cc | 66 ++--------- lily/include/font-metric.hh | 1 - lily/include/lily-proto.hh | 2 +- lily/include/scaled-font-metric.hh | 15 ++- lily/paper-def.cc | 4 +- lily/scaled-font-metric.cc | 177 +++++++++++++++++++++++++---- lily/text-item.cc | 19 +++- scm/encoding.scm | 2 - 9 files changed, 198 insertions(+), 96 deletions(-) diff --git a/ChangeLog b/ChangeLog index 694db14fd5..06d3fd3aa3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2004-04-06 Han-Wen Nienhuys + * lily/scaled-font-metric.cc (text_dimension): move function from + Font_metric + (make_scaled_font_metric): init coding_scheme_ to TeX + (text_dimension): use get-coding-vector for non TeX coding_scheme_ + + * lily/include/scaled-font-metric.hh (struct + Modified_font_metric): rename from Scaled_font_metric + * scm/encoding.scm (read-encoding-file): split up large function, leave caching to (delay) diff --git a/lily/font-metric.cc b/lily/font-metric.cc index 65ecc6cc6c..2527069190 100644 --- a/lily/font-metric.cc +++ b/lily/font-metric.cc @@ -1,5 +1,5 @@ /* - font-metric.cc -- implement Font_metric + font-metric.cc -- implement Font_metric source file of the GNU LilyPond music typesetter @@ -11,6 +11,7 @@ #include #include +#include "scaled-font-metric.hh" #include "virtual-methods.hh" #include "warn.hh" #include "stencil.hh" @@ -30,61 +31,7 @@ Font_metric::coding_scheme () const return "FontSpecific"; } -Box -Font_metric::text_dimension (String text) const -{ - Interval ydims; - Real w=0.0; - - for (int i = 0; i < text.length (); i++) - { - - switch (text[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! - break; - case '{': // Skip '{' and '}' - case '}': - break; - - default: - Box b = get_ascii_char ((unsigned char)text[i]); - - // Ugh, use the width of 'x' for unknown characters - if (b[X_AXIS].length () == 0) - b = get_ascii_char ((unsigned char)'x'); - - w += b[X_AXIS].length (); - ydims.unite (b[Y_AXIS]); - break; - } - } - if (ydims.is_empty ()) - ydims = Interval (0, 0); - - return Box (Interval (0, w), ydims); -} + Font_metric::Font_metric () @@ -211,10 +158,11 @@ LY_DEFINE (ly_text_dimension,"ly:text-dimension", "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"); + Modified_font_metric*fm = dynamic_cast + (unsmob_metrics (font)); + SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "modified 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])); diff --git a/lily/include/font-metric.hh b/lily/include/font-metric.hh index 10da37bb72..d3574bbc35 100644 --- a/lily/include/font-metric.hh +++ b/lily/include/font-metric.hh @@ -26,7 +26,6 @@ public: virtual Offset get_indexed_wxwy (int) const; virtual Box get_indexed_char (int index) const; virtual Box get_ascii_char (int ascii) const; - virtual Box text_dimension (String) const; virtual int name_to_index (String) const; virtual Real design_size () const; virtual Stencil find_by_name (String) const; diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh index 7b1ce3da05..b8181cdf58 100644 --- a/lily/include/lily-proto.hh +++ b/lily/include/lily-proto.hh @@ -126,7 +126,7 @@ class Repeated_music; class Event; class Event_chord; class Event_chord_iterator; -class Scaled_font_metric; +class Modified_font_metric; class Scheme_hash_table; class Score; class Grob; diff --git a/lily/include/scaled-font-metric.hh b/lily/include/scaled-font-metric.hh index a8c5b0a630..5a738c01ad 100644 --- a/lily/include/scaled-font-metric.hh +++ b/lily/include/scaled-font-metric.hh @@ -13,9 +13,12 @@ #include "font-metric.hh" /* Perhaps junk this, and move this to paper_def as interface? */ -struct Scaled_font_metric : public Font_metric +struct Modified_font_metric : public Font_metric { - virtual Box text_dimension (String) const; +public: + Box text_dimension (String); + + virtual Stencil find_by_name (String) const; static SCM make_scaled_font_metric (Font_metric*, Real); virtual int count () const; @@ -25,12 +28,16 @@ struct Scaled_font_metric : public Font_metric protected: virtual Real design_size () const; + virtual void derived_mark (); virtual Box get_indexed_char (int)const; - virtual Box get_ascii_char (int)const; + virtual Box get_ascii_char (int) const; Font_metric *orig_; Real magnification_; + String coding_scheme_; + SCM coding_vector_; - Scaled_font_metric (Font_metric*, Real); + Modified_font_metric (Font_metric*, Real); + Box tex_kludge (String) const; }; #endif /* SCALED_FONT_METRIC_HH */ diff --git a/lily/paper-def.cc b/lily/paper-def.cc index ffcc2409d1..8fba6dc691 100644 --- a/lily/paper-def.cc +++ b/lily/paper-def.cc @@ -153,7 +153,7 @@ Paper_def::find_scaled_font (Font_metric *f, Real m) m /= gh_scm2double (scm_variable_ref (scale_var)); - val = Scaled_font_metric::make_scaled_font_metric (f, m); + val = Modified_font_metric::make_scaled_font_metric (f, m); } sizes = scm_acons (gh_double2scm (m), val, sizes); @@ -182,7 +182,7 @@ Paper_def::font_descriptions () const { Font_metric *fm= unsmob_metrics (gh_cdar (t)); - if (dynamic_cast (fm)) + if (dynamic_cast (fm)) l = gh_cons (fm->self_scm (), l); } } diff --git a/lily/scaled-font-metric.cc b/lily/scaled-font-metric.cc index e6cd06f88b..863e589034 100644 --- a/lily/scaled-font-metric.cc +++ b/lily/scaled-font-metric.cc @@ -1,5 +1,5 @@ /* - scaled-font-metric.cc -- declare Scaled_font_metric + scaled-font-metric.cc -- declare Modified_font_metric source file of the GNU LilyPond music typesetter @@ -7,13 +7,16 @@ */ +#include + +#include "warn.hh" #include "scaled-font-metric.hh" #include "string.hh" #include "stencil.hh" - -Scaled_font_metric::Scaled_font_metric (Font_metric* m, Real magn) +Modified_font_metric::Modified_font_metric (Font_metric* m, Real magn) { + coding_vector_ = SCM_EOL; magnification_ = magn; SCM desc = m->description_; @@ -25,20 +28,23 @@ Scaled_font_metric::Scaled_font_metric (Font_metric* m, Real magn) } SCM -Scaled_font_metric::make_scaled_font_metric (Font_metric *m, Real s) +Modified_font_metric::make_scaled_font_metric (Font_metric *m, Real s) { - Scaled_font_metric *sfm = new Scaled_font_metric (m, s); + Modified_font_metric *sfm = new Modified_font_metric (m, s); + + sfm->coding_scheme_ = "TeX"; + return sfm->self_scm (); } Real -Scaled_font_metric::design_size () const +Modified_font_metric::design_size () const { return orig_->design_size (); } Stencil -Scaled_font_metric::find_by_name (String s) const +Modified_font_metric::find_by_name (String s) const { Stencil m = orig_->find_by_name (s); Box b = m.extent_box (); @@ -48,7 +54,7 @@ Scaled_font_metric::find_by_name (String s) const } Box -Scaled_font_metric::get_indexed_char (int i) const +Modified_font_metric::get_indexed_char (int i) const { Box b = orig_->get_indexed_char (i); b.scale (magnification_); @@ -56,43 +62,172 @@ Scaled_font_metric::get_indexed_char (int i) const } Box -Scaled_font_metric::get_ascii_char (int i) const +Modified_font_metric::get_ascii_char (int i) const { Box b = orig_->get_ascii_char (i); b.scale (magnification_); return b; } -Box -Scaled_font_metric::text_dimension (String t) const -{ - Box b (orig_->text_dimension (t)); - b.scale (magnification_); - return b; -} int -Scaled_font_metric::count () const +Modified_font_metric::count () const { return orig_->count (); } Offset -Scaled_font_metric::get_indexed_wxwy (int k) const +Modified_font_metric::get_indexed_wxwy (int k) const { Offset o = orig_->get_indexed_wxwy (k); return o * magnification_; } int -Scaled_font_metric::name_to_index (String s)const +Modified_font_metric::name_to_index (String s)const { return orig_->name_to_index (s); } String -Scaled_font_metric::coding_scheme () const +Modified_font_metric::coding_scheme () const { - return orig_->coding_scheme (); + return coding_scheme_; } +void +Modified_font_metric::derived_mark () +{ + scm_gc_mark (coding_vector_); +} + + +Box +Modified_font_metric::tex_kludge (String text) const +{ + Interval ydims; + Real w=0.0; + + /* + TODO: put this klutchness behind ly:option switch. + */ + for (int i = 0; i < text.length (); i++) + { + + switch (text[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! + break; + case '{': // Skip '{' and '}' + case '}': + break; + + default: + Box b = get_ascii_char ((unsigned char)text[i]); + + // Ugh, use the width of 'x' for unknown characters + if (b[X_AXIS].length () == 0) + b = get_ascii_char ((unsigned char)'x'); + + w += b[X_AXIS].length (); + ydims.unite (b[Y_AXIS]); + break; + } + } + + if (ydims.is_empty ()) + ydims = Interval (0, 0); + + return Box (Interval (0, w), ydims); +} + +Box +Modified_font_metric::text_dimension (String text) +{ + Box b; + if (coding_scheme_ == "TeX") + { + b = tex_kludge (text); + } + else if (coding_scheme_ == "ASCII" + || coding_scheme_ == orig_->coding_scheme ()) + { + Interval ydims; + + Real w=0.0; + + for (int i = 0; i < text.length (); i++) + { + Box b = get_ascii_char ((unsigned char)text[i]); + + w += b[X_AXIS].length (); + ydims.unite (b[Y_AXIS]); + } + } + else + { + if (!gh_vector_p (coding_vector_)) + { + coding_vector_ = scm_call_1 (ly_scheme_function ("get-coding-vector"), + scm_makfrom0str (coding_scheme_.to_str0 ())); + + if (!gh_vector_p (coding_vector_)) + { + programming_error ("get-coding-vector should return vector"); + coding_vector_ = scm_c_make_vector (256, ly_symbol2scm (".notdef")); + } + } + + Interval ydims; + Real w=0.0; + + for (int i = 0; i < text.length (); i++) + { + SCM sym = scm_vector_ref (coding_vector_, + SCM_MAKINUM((unsigned char) text[i])); + + Box char_box; + + if (!gh_symbol_p (sym)) + continue; + + int idx = orig_->name_to_index (SCM_SYMBOL_CHARS(sym)); + + if (idx >= 0) + { + char_box = orig_->get_indexed_char (idx); + } + if (!char_box[X_AXIS].is_empty ()) + w += char_box[X_AXIS][RIGHT]; // length ? + + ydims.unite (char_box[Y_AXIS]); + } + + + b = Box (Interval (0, w), ydims); + } + + b.scale (magnification_); + return b; +} diff --git a/lily/text-item.cc b/lily/text-item.cc index 63ed2334fd..aa86ab3cb6 100644 --- a/lily/text-item.cc +++ b/lily/text-item.cc @@ -14,6 +14,7 @@ #include "font-interface.hh" #include "virtual-font-metric.hh" #include "paper-def.hh" +#include "scaled-font-metric.hh" MAKE_SCHEME_CALLBACK (Text_item, interpret_markup, 3) SCM @@ -27,13 +28,19 @@ Text_item::interpret_markup (SCM paper, SCM props, SCM markup) Font_metric *fm = select_font (pap, props); SCM lst = scm_list_n (ly_symbol2scm ("text"), markup, SCM_UNDEFINED); - if (dynamic_cast (fm)) - /* ARGH. */ - programming_error ("Can't use virtual font for text."); + Box b; + if (Modified_font_metric* mf = dynamic_cast (fm)) + { + lst = fontify_atom (mf, lst); + + Box b = mf->text_dimension (str); + } else - lst = fontify_atom (fm, lst); - - Box b = fm->text_dimension (str); + { + /* ARGH. */ + programming_error ("Must have Modified_font_metric for text."); + } + return Stencil (b, lst).smobbed_copy (); } else if (gh_pair_p (markup)) diff --git a/scm/encoding.scm b/scm/encoding.scm index 0767ad9a23..f161696926 100644 --- a/scm/encoding.scm +++ b/scm/encoding.scm @@ -70,8 +70,6 @@ vector of symbols." (tab (make-encoding-table vec))) (list vec tab))) - - ;; coding-alist maps NAME -> (list VECTOR TAB) (define coding-alist -- 2.39.5