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
);