2 afm.cc -- implement Adobe_font_metric
4 source file of the GNU LilyPond music typesetter
6 (c) 2000--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #ifndef _GNU_SOURCE // we want memmem
14 #include "libc-extension.hh"
17 #include "molecule.hh"
18 #include "dimensions.hh"
20 Adobe_font_metric::Adobe_font_metric (AFM_Font_info * fi)
25 for (int i= 256 >? fi->numOfChars; i--;)
26 ascii_to_metric_idx_.push (-1);
28 for (int i=0; i < fi->numOfChars; i++)
30 AFM_CharMetricInfo * c = fi->cmi + i;
33 Some TeX afm files contain code = -1. We don't know why, let's
38 ascii_to_metric_idx_[c->code] = i;
39 name_to_metric_dict_[c->name] = i;
45 Adobe_font_metric::make_afm (AFM_Font_info *fi, unsigned int checksum)
47 Adobe_font_metric * fm = new Adobe_font_metric (fi);
48 fm->checksum_ = checksum;
49 return fm->self_scm ();
53 AFM_CharMetricInfo const *
54 Adobe_font_metric::find_ascii_metric (int a , bool warn) const
56 if (ascii_to_metric_idx_[a] >=0)
58 int code = ascii_to_metric_idx_[a];
61 return font_inf_->cmi + code;
66 warning (_f ("can't find character number: %d", a));
72 AFM_CharMetricInfo const *
73 Adobe_font_metric::find_char_metric (String nm, bool warn) const
75 std::map<String,int>::const_iterator ai = name_to_metric_dict_.find (nm);
77 if (ai == name_to_metric_dict_.end ())
81 warning (_f ("can't find character called: `%s'", nm.to_str0 ()));
86 return font_inf_->cmi + (*ai).second;
90 Adobe_font_metric::count () const
92 return font_inf_->numOfChars ;
96 Adobe_font_metric::get_char (int code) const
98 AFM_CharMetricInfo const
99 * c = find_ascii_metric (code,false);
100 Box b (Interval (0,0),Interval (0,0));
102 b = afm_bbox_to_box (c->charBBox);
108 read_afm_file (String nm)
110 FILE *f = fopen (nm.to_str0 () , "r");
112 char *check_key = "Comment TfmCheckSum";
117 fread (s, sizeof (s), sizeof (*s), f);
118 if (char const* p = (char const *)
119 memmem (s, sizeof (s), check_key, strlen (check_key)))
120 sscanf (p + strlen (check_key), "%ud", &cs);
123 /* Assume check_key in first 10 lines */
124 for (int i = 0; i < 10; i++)
126 fgets (s, sizeof (s), f);
127 if (strncmp (s, check_key, strlen (check_key)) == 0)
129 sscanf (s + strlen (check_key), "%ud", &cs);
138 int ok = AFM_parseFile (f, &fi, ~1);
142 error (_f ("Error parsing AFM file: `%s'", nm.to_str0 ()));
147 return Adobe_font_metric::make_afm (fi, cs);
152 actually, AFMs will be printers point, usually, but our .py script dumps
156 afm_bbox_to_box (AFM_BBox bb)
158 return Box (Interval (bb.llx, bb.urx)* (1/1000.0) PT,
159 Interval (bb.lly, bb.ury)* (1/1000.0) PT);
164 Adobe_font_metric::~Adobe_font_metric ()
166 AFM_free (font_inf_);
170 return a molecule, without fontification
173 Adobe_font_metric::find_by_name (String s) const
175 AFM_CharMetricInfo const *cm = find_char_metric (s, false);
180 Why don't we return empty?
188 SCM at = (scm_list_n (ly_symbol2scm ("char"),
189 scm_int2num (cm->code),
192 // at= fontify_atom ((Font_metric*)this, at);
193 Box b = afm_bbox_to_box (cm->charBBox);
195 return Molecule (b, at);