/*
- modified-font-metric.cc -- declare Modified_font_metric
-
- source file of the GNU LilyPond music typesetter
-
- (c) 1999--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
-*/
+ This file is part of LilyPond, the GNU music typesetter.
-#include <ctype.h>
+ Copyright (C) 1999--2012 Han-Wen Nienhuys <hanwen@xs4all.nl>
+
+ LilyPond is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ LilyPond is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <cctype>
+using namespace std;
-#include "warn.hh"
#include "modified-font-metric.hh"
-#include "string.hh"
+#include "pango-font.hh"
+#include "warn.hh"
#include "stencil.hh"
+#include "main.hh"
+#include "program-option.hh"
-Modified_font_metric::Modified_font_metric (String input_encoding,
- Font_metric *m, Real magn)
+Modified_font_metric::Modified_font_metric (Font_metric *fm,
+ Real magnification)
{
- /* UGR, FIXME:
+ magnification_ = magnification;
- THIS.coding_scheme == input encoding.
- ORIG.coding_scheme () == font_encoding.
+ SCM desc = fm->description_;
- encoding is hairy enough by itself, should fix treacherous naming. */
-
- coding_scheme_ = input_encoding;
-
- coding_vector_ = SCM_EOL;
- coding_mapping_ = SCM_EOL;
- coding_table_ = SCM_EOL;
- coding_description_ = SCM_EOL;
-
- magnification_ = magn;
-
- SCM desc = m->description_;
-
- Real total_mag = magn * ly_scm2double (ly_cdr (desc));
+ Real total_mag = magnification * scm_to_double (scm_cdr (desc));
assert (total_mag);
-
- description_ = scm_cons (ly_car (desc), scm_make_real (total_mag));
- orig_ = m;
-
- if (coding_scheme_ != ""
- && coding_scheme_ != "TeX"
- && coding_scheme_ != "ASCII"
- && coding_scheme_ != orig_->coding_scheme ())
- {
- coding_vector_
- = scm_call_1 (ly_scheme_function ("get-coding-vector"),
- scm_makfrom0str (coding_scheme_.to_str0 ()));
-
- if (!ly_c_vector_p (coding_vector_))
- {
- programming_error ("get-coding-vector should return vector");
- coding_vector_ = scm_c_make_vector (256, ly_symbol2scm (".notdef"));
- }
- coding_table_
- = scm_call_1 (ly_scheme_function ("get-coding-table"),
- scm_makfrom0str (orig_->coding_scheme ().to_str0 ()));
-
- coding_mapping_
- = scm_call_2 (ly_scheme_function ("make-encoding-mapping"),
- coding_vector_,
- coding_table_);
-
- coding_description_ = SCM_EOL;
- coding_description_
- = scm_acons (ly_symbol2scm ("input-name"),
- scm_makfrom0str (coding_scheme_.to_str0 ()),
- coding_description_);
- coding_description_
- = scm_acons (ly_symbol2scm ("input-vector"),
- coding_vector_, coding_description_);
- coding_description_
- = scm_acons (ly_symbol2scm ("output-name"),
- scm_makfrom0str (orig_->coding_scheme ().to_str0 ()),
- coding_description_);
- coding_description_
- = scm_acons (ly_symbol2scm ("output-table"),
- coding_table_,
- coding_description_);
- coding_description_
- = scm_acons (ly_symbol2scm ("char-mapping"),
- coding_mapping_,
- coding_description_);
- }
-}
-
-
-
-LY_DEFINE (ly_font_encoding_alist, "ly:font-encoding-alist",
- 1, 0, 0,
- (SCM font),
- "Given the Modified_font_metric @var{font}, return an "
- "alist. Keys are input-name, input-vector, "
- "output-name, output-table, mapping.")
-{
- Modified_font_metric *fm
- = dynamic_cast<Modified_font_metric*> (unsmob_metrics (font));
-
- SCM_ASSERT_TYPE (fm, font, SCM_ARG1, __FUNCTION__, "Modified_font_metric");
- return fm->coding_description_;
+ description_ = scm_cons (scm_car (desc), scm_from_double (total_mag));
+ orig_ = fm;
}
SCM
-Modified_font_metric::make_scaled_font_metric (SCM coding,
- Font_metric *m, Real s)
+Modified_font_metric::make_scaled_font_metric (Font_metric *fm, Real scaling)
{
- /*
- UGH.
- */
- if (ly_c_symbol_p (coding))
- coding = scm_symbol_to_string (coding);
-
- String scheme = scm_is_string (coding) ? ly_scm2string (coding) : "";
-
- Modified_font_metric *sfm = new Modified_font_metric (scheme, m, s);
-
+ Modified_font_metric *sfm = new Modified_font_metric (fm, scaling);
return sfm->self_scm ();
}
return orig_->design_size ();
}
-
-Box
-Modified_font_metric::get_indexed_char (int i) const
+Box
+Modified_font_metric::get_indexed_char_dimensions (vsize i) const
{
- Box b = orig_->get_indexed_char (i);
+ Box b = orig_->get_indexed_char_dimensions (i);
b.scale (magnification_);
- return b;
+ return b;
}
-Box
-Modified_font_metric::get_ascii_char (int i) const
+Real
+Modified_font_metric::get_magnification () const
{
- Box b = orig_->get_ascii_char (i);
- b.scale (magnification_);
- return b;
+ return magnification_;
}
-int
+vsize
Modified_font_metric::count () const
{
return orig_->count ();
}
Offset
-Modified_font_metric::get_indexed_wxwy (int k) const
+Modified_font_metric::attachment_point (const string &s) const
{
- Offset o = orig_->get_indexed_wxwy (k);
+ Offset o = orig_->attachment_point (s);
return o * magnification_;
}
-int
-Modified_font_metric::name_to_index (String s) const
+Offset
+Modified_font_metric::get_indexed_wxwy (vsize k) const
{
- return orig_->name_to_index (s);
+ Offset o = orig_->get_indexed_wxwy (k);
+ return o * magnification_;
}
-int
-Modified_font_metric::index_to_ascii (int k) const
+size_t
+Modified_font_metric::name_to_index (string s) const
{
- return orig_->index_to_ascii (k);
+ return orig_->name_to_index (s);
}
-String
-Modified_font_metric::coding_scheme () const
+vsize
+Modified_font_metric::index_to_charcode (vsize i) const
{
- return coding_scheme_;
+ return orig_->index_to_charcode (i);
}
void
Modified_font_metric::derived_mark () const
{
- scm_gc_mark (coding_vector_);
- scm_gc_mark (coding_description_);
- scm_gc_mark (coding_table_);
- scm_gc_mark (coding_mapping_);
-}
-
-/* TODO: put this klutchness behind ly:option switch. */
-Box
-Modified_font_metric::tex_kludge (String text) const
-{
- Interval ydims;
- Real w = 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++)
- ;
-
- /* Compensate for the auto-increment in the outer loop. */
- i--;
- break;
-
- case '{': // Skip '{' and '}'
- case '}':
- break;
-
- default:
- Box b = get_ascii_char ((unsigned char)text[i]);
-
- /* 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)
+Stencil
+Modified_font_metric::text_stencil (Output_def *state,
+ const string &text, bool feta) const
{
- Box b;
- if (coding_scheme_ == "TeX")
- b = tex_kludge (text);
- else if (coding_scheme_ == "ASCII"
- || coding_scheme_ == ""
- || coding_scheme_ == orig_->coding_scheme ())
+ Box b;
+ if (Pango_font *pf = dynamic_cast<Pango_font *> (orig_))
{
- Interval ydims;
-
- Real w=0.0;
+ Stencil stc = pf->text_stencil (state, text, feta);
- 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]);
- }
- if (ydims.is_empty ())
- ydims = Interval (0, 0);
+ Box b = stc.extent_box ();
- b = Box(Interval(0,w), ydims);
+ b.scale (magnification_);
+ Stencil scaled (b, stc.expr ());
+ return scaled;
}
- else
- {
- Interval ydims;
- Real w = 0.0;
-
- for (int i = 0; i < text.length (); i++)
- {
- SCM sym = scm_vector_ref (coding_vector_,
- scm_from_int((unsigned char) text[i]));
-
- Box char_box;
- if (!ly_c_symbol_p (sym))
- continue;
-
- char const * chars = scm_i_string_chars (scm_symbol_to_string(sym));
-
- int idx = orig_->name_to_index (chars);
- if (idx >= 0)
- char_box = orig_->get_indexed_char (idx);
-
- char_box.scale (magnification_);
- if (!char_box[X_AXIS].is_empty ())
- /* length ? */
- w += char_box[X_AXIS][RIGHT];
-
- ydims.unite (char_box[Y_AXIS]);
- }
-
- if (ydims.is_empty ())
- ydims = Interval (0, 0);
-
- b = Box (Interval (0, w), ydims);
- }
-
- return b;
+ return Font_metric::text_stencil (state, text, feta);
}
-Font_metric*
+Font_metric *
Modified_font_metric::original_font () const
{
return orig_;
}
+
+SCM
+Modified_font_metric::sub_fonts () const
+{
+ return orig_->sub_fonts ();
+}
+
+string
+Modified_font_metric::font_name () const
+{
+ return original_font ()->font_name ();
+}