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)
/*
- font-metric.cc -- implement Font_metric
+ font-metric.cc -- implement Font_metric
source file of the GNU LilyPond music typesetter
#include <math.h>
#include <ctype.h>
+#include "scaled-font-metric.hh"
#include "virtual-methods.hh"
#include "warn.hh"
#include "stencil.hh"
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 ()
"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]));
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;
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;
#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;
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 */
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);
{
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);
}
}
/*
- scaled-font-metric.cc -- declare Scaled_font_metric
+ scaled-font-metric.cc -- declare Modified_font_metric
source file of the GNU LilyPond music typesetter
*/
+#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_;
}
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 ();
}
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_);
}
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;
+}
#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
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))
(tab (make-encoding-table vec)))
(list vec tab)))
-
-
;; coding-alist maps NAME -> (list VECTOR TAB)
(define coding-alist