]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/scaled-font-metric.cc (text_dimension): move function from
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Tue, 6 Apr 2004 01:07:11 +0000 (01:07 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Tue, 6 Apr 2004 01:07:11 +0000 (01:07 +0000)
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
lily/font-metric.cc
lily/include/font-metric.hh
lily/include/lily-proto.hh
lily/include/scaled-font-metric.hh
lily/paper-def.cc
lily/scaled-font-metric.cc
lily/text-item.cc
scm/encoding.scm

index 694db14fd50551158f21f6eed6ed3a9b0f3a18a2..06d3fd3aa3c1dff7e29c6990c8080863ad295e0b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2004-04-06  Han-Wen Nienhuys   <hanwen@xs4all.nl>
 
+       * 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)
 
index 65ecc6cc6cf073d0d24f28c647cd3c94c473bac7..2527069190ea16adf330c45ab96cc8277bf92dce 100644 (file)
@@ -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 <math.h>
 #include <ctype.h>
 
+#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<Modified_font_metric*>
+    (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]));
index 10da37bb728f8f08bf25fc8da90e1e030b20c9fe..d3574bbc35010d548c1cc110584f58b9715ffb3e 100644 (file)
@@ -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;
index 7b1ce3da0571eb16ae4400c660d5ab4695e6b2e7..b8181cdf5855266b4ddaf9dc184e06ea9fb4116c 100644 (file)
@@ -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;
index a8c5b0a630fd34cb5843f6cd09420a3eb7308a5d..5a738c01adfba69bb52223eaacc5d9376abb6356 100644 (file)
 #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 */
index ffcc2409d1d8383208786275ca098549d5ce5216..8fba6dc691404e069fe6f69c216f85cd04d41dd1 100644 (file)
@@ -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<Scaled_font_metric*> (fm))
+         if (dynamic_cast<Modified_font_metric*> (fm))
            l = gh_cons (fm->self_scm (), l);
        }
     }
index e6cd06f88bd8f408bf52815637779bc859068964..863e589034fd5194b72692bdb29e750dbbb5f2d2 100644 (file)
@@ -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 <ctype.h>
+
+#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;
+}
index 63ed2334fde7c1e48f31b9307191765c52d59603..aa86ab3cb6d78850638145a488910ac7e432c7af 100644 (file)
@@ -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<Virtual_font_metric*> (fm))
-       /* ARGH. */
-       programming_error ("Can't use virtual font for text.");
+      Box b;
+      if (Modified_font_metric* mf = dynamic_cast<Modified_font_metric*> (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))
index 0767ad9a23ca5f55f94b3be1315ce04746c8b996..f161696926cd4ff0ae1689999beb1dba2d7ac91e 100644 (file)
@@ -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