nasm/doc/ttfmetrics.ph
H. Peter Anvin ceabd83dcf doc: fix fonts where the scale (unitsPerEm) is not 1000
AFM metrics always have 1000 font units to a scaled PostScript point,
but TTF/OTF doesn't have to.  The easiest way (and the one which
best avoids unnecessary rounding) is to store the scale in the
metrics, and change pswidth.ph to return the width in PostScript
points instead of font units.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2017-04-10 15:21:04 -07:00

64 lines
1.4 KiB
Perl

#!/usr/bin/perl
use Font::TTF::Font;
use Font::TTF::Head;
use Font::TTF::Hmtx;
use Font::TTF::Cmap;
use Font::TTF::Maxp;
use Font::TTF::PSNames;
use Font::TTF::Post;
use strict;
sub parse_ttf_file($) {
my($filename) = @_;
my $fontdata = {
widths => {},
kern => {}
};
my $f = Font::TTF::Font->open($filename);
return undef if (!defined($f));
$fontdata->{file} = $filename;
$fontdata->{type} = defined($f->{' CFF'}) ? 'otf' : 'ttf';
$f->{head}->read();
$fontdata->{scale} = $f->{head}{unitsPerEm};
$f->{maxp}->read();
my $glyphs = $f->{maxp}{numGlyphs};
$f->{cmap}->read();
$f->{hmtx}->read();
$f->{name}->read();
$fontdata->{name} = $f->{name}->find_name(6); # PostScript name
$f->{post}->read();
my $psglyphs = 0;
my $psmap = $f->{post}->{VAL};
$psmap = [] if (!defined($psmap));
#printf "Glyphs with PostScript names: %d\n", scalar(@$psmap);
# Can be done as an array of arrays in case of multiple unicodes to
# one glyph...
my @unimap = $f->{cmap}->reverse();
for (my $i = 0; $i < $glyphs; $i++) {
my $width = $f->{hmtx}->{advance}[$i];
my $psname = $psmap->[$i];
if (!defined($psname)) {
$psname = Font::TTF::PSNames::lookup($unimap[$i]);
}
next if (!defined($psname) || ($psname eq '.notdef'));
$fontdata->{widths}{$psname} = $f->{hmtx}->{advance}[$i];
}
$f->release;
return $fontdata;
}
1;