X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fafm.cc;h=5510c8fe75e0956af51decd139f554a9f91937ee;hb=21085be16bbb0fc1914210b69476c4f0a3ec92ea;hp=71a1e25ea98c9d7e8f26e44bdb5bf83c1dd3c5b7;hpb=876ccb4004d92f3b7bd539753f8f9339b7d48490;p=lilypond.git diff --git a/lily/afm.cc b/lily/afm.cc index 71a1e25ea9..5510c8fe75 100644 --- a/lily/afm.cc +++ b/lily/afm.cc @@ -3,154 +3,194 @@ source file of the GNU LilyPond music typesetter - (c) 1998--1999 Han-Wen Nienhuys + (c) 2000--2003 Han-Wen Nienhuys */ +#ifndef _GNU_SOURCE // we want memmem +#define _GNU_SOURCE +#endif +#include +#include "libc-extension.hh" #include "afm.hh" -#include "box.hh" -#include "direction.hh" -#include "debug.hh" +#include "warn.hh" +#include "molecule.hh" +#include "dimensions.hh" -Box & -Adobe_font_char_metric::bbox () +Adobe_font_metric::Adobe_font_metric (AFM_Font_info * fi) { - return B_; -} + checksum_ = 0; + font_inf_ = fi; -String & -Adobe_font_char_metric::name () -{ - return N_; + for (int i= 256 >? fi->numOfChars; i--;) + ascii_to_metric_idx_.push (-1); + + for (int i=0; i < fi->numOfChars; i++) + { + AFM_CharMetricInfo * c = fi->cmi + i; + + /* + Some TeX afm files contain code = -1. We don't know why, let's + ignore it. + + */ + if (c->code >= 0) + ascii_to_metric_idx_[c->code] = i; + name_to_metric_dict_[c->name] = i; + } } -int & -Adobe_font_char_metric::code () + +SCM +Adobe_font_metric::make_afm (AFM_Font_info *fi, unsigned int checksum) { - return C_; + Adobe_font_metric * fm = new Adobe_font_metric (fi); + fm->checksum_ = checksum; + return fm->self_scm (); } -Real & -Adobe_font_char_metric::width () + +AFM_CharMetricInfo const * +Adobe_font_metric::find_ascii_metric (int a , bool warn) const { - return WX_; + if (ascii_to_metric_idx_[a] >=0) + { + int code = ascii_to_metric_idx_[a]; + if (code>=0) + { + return font_inf_->cmi + code; + } + } + else if (warn) + { + warning (_f ("can't find character number: %d", a)); + } + + return 0; } -Adobe_font_char_metric::Adobe_font_char_metric () +AFM_CharMetricInfo const * +Adobe_font_metric::find_char_metric (String nm, bool warn) const { - B_ = Box( Interval(0,0), Interval (0,0)); - WX_ = 0.0; - C_ = 0; - C_ = -1; + std::map::const_iterator ai = name_to_metric_dict_.find (nm); + + if (ai == name_to_metric_dict_.end ()) + { + if (warn) + { + warning (_f ("can't find character called: `%s'", nm.to_str0 ())); + } + return 0; + } + else + return font_inf_->cmi + (*ai).second; } -Adobe_font_metric::Adobe_font_metric () +int +Adobe_font_metric::count () const { - ItalicAngle_ = 0.0; - IsFixedPitch_ = false; - UnderlinePosition_ =0.; - UnderlineThickness_=0.; + return font_inf_->numOfChars ; } - Box -Adobe_font_char_metric::dimensions () const +Adobe_font_metric::get_char (int code) const { - Box b= B_; - - b[X_AXIS] *= size_ / 1000.0; - b[Y_AXIS] *= size_ / 1000.0; + AFM_CharMetricInfo const + * c = find_ascii_metric (code,false); + Box b (Interval (0,0),Interval (0,0)); + if (c) + b = afm_bbox_to_box (c->charBBox); return b; } +SCM +read_afm_file (String nm) +{ + FILE *f = fopen (nm.to_str0 () , "r"); + char s[2048]; + char *check_key = "Comment TfmCheckSum"; + + unsigned int cs = 0; + +#if 0 + fread (s, sizeof (s), sizeof (*s), f); + if (char const* p = (char const *) + memmem (s, sizeof (s), check_key, strlen (check_key))) + sscanf (p + strlen (check_key), "%ud", &cs); +#else + s[0] = 0; + /* Assume check_key in first 10 lines */ + for (int i = 0; i < 10; i++) + { + fgets (s, sizeof (s), f); + if (strncmp (s, check_key, strlen (check_key)) == 0) + { + sscanf (s + strlen (check_key), "%ud", &cs); + break; + } + } +#endif + + rewind (f); + + AFM_Font_info * fi; + int ok = AFM_parseFile (f, &fi, ~1); + if (ok) + { + error (_f ("Error parsing AFM file: `%s'", nm.to_str0 ())); + exit (2); + } + fclose (f); -#define APPEND_CHAR_METRIC_ELT(k) outstr += to_str (#k) + " " + to_str (k ## _) + "; " - -String -box_str (Box b) -{ - return to_str (b[X_AXIS][SMALLER]) + " " + - to_str(b[Y_AXIS][SMALLER]) + " " + - to_str (b[X_AXIS][BIGGER]) + " "+ - to_str (b[Y_AXIS][BIGGER]); + return Adobe_font_metric::make_afm (fi, cs); } -#define APPEND_BOX(k) outstr += to_str (#k) + " " + box_str (k ## _) + ";" -String -Adobe_font_char_metric::str () const +/* + actually, AFMs will be printers point, usually, but our .py script dumps + real points. + */ +Box +afm_bbox_to_box (AFM_BBox bb) { - String outstr ; + return Box (Interval (bb.llx, bb.urx)* (1/1000.0) PT, + Interval (bb.lly, bb.ury)* (1/1000.0) PT); - APPEND_CHAR_METRIC_ELT (C); - APPEND_CHAR_METRIC_ELT(N); - APPEND_CHAR_METRIC_ELT(WX); - - APPEND_BOX(B); - return outstr + "\n"; } - -#define WRITESTRING(k) outstr += String (#k) + " " + to_str (k ## _) + "\n" - -String -Adobe_font_metric::str () const -{ - String outstr; - WRITESTRING(FontName); - WRITESTRING(FullName); - WRITESTRING(FamilyName); - WRITESTRING(Weight); - WRITESTRING(Version); - WRITESTRING(Notice); - WRITESTRING(EncodingScheme); - WRITESTRING(ItalicAngle); - WRITESTRING(UnderlineThickness); - WRITESTRING(UnderlinePosition); - outstr += "FontBBox " + box_str (FontBBox_) + "\n"; - - for (int i=0; i < char_metrics_.size (); i++) - outstr += char_metrics_[i].str (); - return outstr; -} -Adobe_font_char_metric dummy_static_char_metric; - -Adobe_font_char_metric const & -Adobe_font_metric::find_char (String nm, bool warn) const +Adobe_font_metric::~Adobe_font_metric () { - if (!name_to_metric_dict_.elem_b (nm)) - { - if (warn) - { - warning (_f ("Can't find character called: `%s'", nm.ch_C())); - } - return dummy_static_char_metric; - } - - return char_metrics_[name_to_metric_dict_ [nm]]; + AFM_free (font_inf_); } - -Character_metric const * -Adobe_font_metric::get_char (int code, bool warn) const +/* + return a molecule, without fontification + */ +Molecule +Adobe_font_metric::find_by_name (String s) const { - return &find_ascii (code,warn); -} + AFM_CharMetricInfo const *cm = find_char_metric (s, false); -Adobe_font_char_metric const & -Adobe_font_metric::find_ascii (int a , bool warn) const -{ - int code = ascii_to_metric_idx_[a]; - if (code>=0) - { - return char_metrics_[code]; - } - else if (warn ) + if (!cm) { - warning (_f ("Can't find character number: %d", a)); + /* + Why don't we return empty? + */ + + Molecule m; + m.set_empty (false); + return m; } - return dummy_static_char_metric; + + SCM at = (scm_list_n (ly_symbol2scm ("char"), + scm_int2num (cm->code), + SCM_UNDEFINED)); + + // at= fontify_atom ((Font_metric*)this, at); + Box b = afm_bbox_to_box (cm->charBBox); + + return Molecule (b, at); }