.ly version update.
[lilypond.git] / lily / afm.cc
blob5510c8fe75e0956af51decd139f554a9f91937ee
1 /*
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>
8 */
10 #ifndef _GNU_SOURCE // we want memmem
11 #define _GNU_SOURCE
12 #endif
13 #include <string.h>
14 #include "libc-extension.hh"
15 #include "afm.hh"
16 #include "warn.hh"
17 #include "molecule.hh"
18 #include "dimensions.hh"
20 Adobe_font_metric::Adobe_font_metric (AFM_Font_info * fi)
22 checksum_ = 0;
23 font_inf_ = 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
34 ignore it.
37 if (c->code >= 0)
38 ascii_to_metric_idx_[c->code] = i;
39 name_to_metric_dict_[c->name] = i;
44 SCM
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];
59 if (code>=0)
61 return font_inf_->cmi + code;
64 else if (warn)
66 warning (_f ("can't find character number: %d", a));
69 return 0;
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 ())
79 if (warn)
81 warning (_f ("can't find character called: `%s'", nm.to_str0 ()));
83 return 0;
85 else
86 return font_inf_->cmi + (*ai).second;
89 int
90 Adobe_font_metric::count () const
92 return font_inf_->numOfChars ;
95 Box
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));
101 if (c)
102 b = afm_bbox_to_box (c->charBBox);
104 return b;
108 read_afm_file (String nm)
110 FILE *f = fopen (nm.to_str0 () , "r");
111 char s[2048];
112 char *check_key = "Comment TfmCheckSum";
114 unsigned int cs = 0;
116 #if 0
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);
121 #else
122 s[0] = 0;
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);
130 break;
133 #endif
135 rewind (f);
137 AFM_Font_info * fi;
138 int ok = AFM_parseFile (f, &fi, ~1);
140 if (ok)
142 error (_f ("Error parsing AFM file: `%s'", nm.to_str0 ()));
143 exit (2);
145 fclose (f);
147 return Adobe_font_metric::make_afm (fi, cs);
152 actually, AFMs will be printers point, usually, but our .py script dumps
153 real points.
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
172 Molecule
173 Adobe_font_metric::find_by_name (String s) const
175 AFM_CharMetricInfo const *cm = find_char_metric (s, false);
177 if (!cm)
180 Why don't we return empty?
183 Molecule m;
184 m.set_empty (false);
185 return m;
188 SCM at = (scm_list_n (ly_symbol2scm ("char"),
189 scm_int2num (cm->code),
190 SCM_UNDEFINED));
192 // at= fontify_atom ((Font_metric*)this, at);
193 Box b = afm_bbox_to_box (cm->charBBox);
195 return Molecule (b, at);