|
Packit |
5d935b |
package Font::TTF::Post;
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head1 NAME
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Font::TTF::Post - Holds the Postscript names for each glyph
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head1 DESCRIPTION
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Holds the postscript names for glyphs. Note that they are not held as an
|
|
Packit |
5d935b |
array, but as indexes into two lists. The first list is the standard Postscript
|
|
Packit |
5d935b |
name list defined by the TrueType standard. The second comes from the font
|
|
Packit |
5d935b |
directly.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Looking up a glyph from a Postscript name or a name from a glyph number is
|
|
Packit |
5d935b |
achieved through methods rather than variable lookup.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
This class handles PostScript table types of 1, 2, 2.5 & 3, but not version 4.
|
|
Packit |
5d935b |
Support for version 2.5 is as per Apple spec rather than MS.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
The way to look up Postscript names or glyphs is:
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$pname = $f->{'post'}{'VAL'}[$gnum];
|
|
Packit |
5d935b |
$gnum = $f->{'post'}{'STRINGS'}{$pname};
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head1 INSTANCE VARIABLES
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Due to different systems having different limitations, there are various class
|
|
Packit |
5d935b |
variables available to control what post table types can be written.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=over 4
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=item $Font::TTF::Post::no25
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
If set tells Font::TTF::Post::out to use table type 2 instead of 2.5 in case apps
|
|
Packit |
5d935b |
cannot handle version 2.5.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=item VAL
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Contains an array indexed by glyph number of Postscript names. This is used when
|
|
Packit |
5d935b |
writing out a font.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=item STRINGS
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
An associative array of Postscript names mapping to the highest glyph with that
|
|
Packit |
5d935b |
name. These may not be in sync with VAL.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=back
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
In addition there are the standard introductory variables defined in the
|
|
Packit |
5d935b |
standard:
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
FormatType
|
|
Packit |
5d935b |
italicAngle
|
|
Packit |
5d935b |
underlinePosition
|
|
Packit |
5d935b |
underlineThickness
|
|
Packit |
5d935b |
isFixedPitch
|
|
Packit |
5d935b |
minMemType42
|
|
Packit |
5d935b |
maxMemType42
|
|
Packit |
5d935b |
minMemType1
|
|
Packit |
5d935b |
maxMemType1
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head1 METHODS
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=cut
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
use strict;
|
|
Packit |
5d935b |
use vars qw(@ISA @base_set %base_set %fields $VERSION $no25 @field_info @base_set);
|
|
Packit |
5d935b |
require Font::TTF::Table;
|
|
Packit |
5d935b |
use Font::TTF::Utils;
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$no25 = 1; # officially deprecated format 2.5 tables in MS spec 1.3
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
@ISA = qw(Font::TTF::Table);
|
|
Packit |
5d935b |
@field_info = (
|
|
Packit |
5d935b |
'FormatType' => 'f',
|
|
Packit |
5d935b |
'italicAngle' => 'f',
|
|
Packit |
5d935b |
'underlinePosition' => 's',
|
|
Packit |
5d935b |
'underlineThickness' => 's',
|
|
Packit |
5d935b |
'isFixedPitch' => 'L',
|
|
Packit |
5d935b |
'minMemType42' => 'L',
|
|
Packit |
5d935b |
'maxMemType42' => 'L',
|
|
Packit |
5d935b |
'minMemType1' => 'L',
|
|
Packit |
5d935b |
'maxMemType1' => 'L');
|
|
Packit |
5d935b |
@base_set = qw(.notdef .null nonmarkingreturn space exclam quotedbl numbersign dollar percent ampersand quotesingle
|
|
Packit |
5d935b |
parenleft parenright asterisk plus comma hyphen period slash zero one two three four five six
|
|
Packit |
5d935b |
seven eight nine colon semicolon less equal greater question at A B C D E F G H I J K L M N O P Q
|
|
Packit |
5d935b |
R S T U V W X Y Z bracketleft backslash bracketright asciicircum underscore grave a b c d e f g h
|
|
Packit |
5d935b |
i j k l m n o p q r s t u v w x y z braceleft bar braceright asciitilde Adieresis Aring Ccedilla
|
|
Packit |
5d935b |
Eacute Ntilde Odieresis Udieresis aacute agrave acircumflex adieresis atilde aring ccedilla eacute
|
|
Packit |
5d935b |
egrave ecircumflex edieresis iacute igrave icircumflex idieresis ntilde oacute ograve ocircumflex
|
|
Packit |
5d935b |
odieresis otilde uacute ugrave ucircumflex udieresis dagger degree cent sterling section bullet
|
|
Packit |
5d935b |
paragraph germandbls registered copyright trademark acute dieresis notequal AE Oslash infinity
|
|
Packit |
5d935b |
plusminus lessequal greaterequal yen mu partialdiff summation product pi integral ordfeminine
|
|
Packit |
5d935b |
ordmasculine Omega ae oslash questiondown exclamdown logicalnot radical florin approxequal
|
|
Packit |
5d935b |
Delta guillemotleft guillemotright ellipsis nonbreakingspace Agrave Atilde Otilde OE oe endash emdash
|
|
Packit |
5d935b |
quotedblleft quotedblright quoteleft quoteright divide lozenge ydieresis Ydieresis fraction currency
|
|
Packit |
5d935b |
guilsinglleft guilsinglright fi fl daggerdbl periodcentered quotesinglbase quotedblbase perthousand
|
|
Packit |
5d935b |
Acircumflex Ecircumflex Aacute Edieresis Egrave Iacute Icircumflex Idieresis Igrave Oacute Ocircumflex
|
|
Packit |
5d935b |
apple Ograve Uacute Ucircumflex Ugrave dotlessi circumflex tilde macron breve dotaccent
|
|
Packit |
5d935b |
ring cedilla hungarumlaut ogonek caron Lslash lslash Scaron scaron Zcaron zcaron brokenbar Eth eth
|
|
Packit |
5d935b |
Yacute yacute Thorn thorn minus multiply onesuperior twosuperior threesuperior onehalf onequarter
|
|
Packit |
5d935b |
threequarters franc Gbreve gbreve Idotaccent Scedilla scedilla Cacute cacute Ccaron ccaron dcroat);
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$VERSION = 0.01; # MJPH 5-AUG-1998 Re-organise data structures
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
sub init
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
my ($k, $v, $c, $i);
|
|
Packit |
5d935b |
for ($i = 0; $i < $#field_info; $i += 2)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
($k, $v, $c) = TTF_Init_Fields($field_info[$i], $c, $field_info[$i + 1]);
|
|
Packit |
5d935b |
next unless defined $k && $k ne "";
|
|
Packit |
5d935b |
$fields{$k} = $v;
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
$i = 0;
|
|
Packit |
5d935b |
%base_set = map {$_ => $i++} @base_set;
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head2 $t->read
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Reads the Postscript table into memory from disk
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=cut
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
sub read
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
my ($self) = @_;
|
|
Packit |
5d935b |
$self->SUPER::read or return $self;
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
my ($dat, $dat1, $i, $off, $c, $maxoff, $form, $angle, $numGlyphs);
|
|
Packit |
5d935b |
my ($fh) = $self->{' INFILE'};
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$numGlyphs = $self->{' PARENT'}{'maxp'}{'numGlyphs'};
|
|
Packit |
5d935b |
init unless ($fields{'FormatType'});
|
|
Packit |
5d935b |
$fh->read($dat, 32);
|
|
Packit |
5d935b |
TTF_Read_Fields($self, $dat, \%fields);
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
if (int($self->{'FormatType'} + .5) == 1)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
for ($i = 0; $i < 258; $i++)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
$self->{'VAL'}[$i] = $base_set[$i];
|
|
Packit |
5d935b |
$self->{'STRINGS'}{$base_set[$i]} = $i unless (defined $self->{'STRINGS'}{$base_set[$i]});
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
} elsif (int($self->{'FormatType'} * 2 + .1) == 5)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
$fh->read($dat, 2);
|
|
Packit |
5d935b |
$numGlyphs = unpack("n", $dat);
|
|
Packit |
5d935b |
$fh->read($dat, $numGlyphs);
|
|
Packit |
5d935b |
for ($i = 0; $i < $numGlyphs; $i++)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
$off = unpack("c", substr($dat, $i, 1));
|
|
Packit |
5d935b |
$self->{'VAL'}[$i] = $base_set[$i + $off];
|
|
Packit |
5d935b |
$self->{'STRINGS'}{$base_set[$i + $off]} = $i unless (defined $self->{'STRINGS'}{$base_set[$i + $off]});
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
} elsif (int($self->{'FormatType'} + .5) == 2)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
my (@strings);
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$fh->read($dat, ($numGlyphs + 1) << 1);
|
|
Packit |
5d935b |
for ($i = 0; $i < $numGlyphs; $i++)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
$off = unpack("n", substr($dat, ($i + 1) << 1, 2));
|
|
Packit |
5d935b |
$maxoff = $off if (!defined $maxoff || $off > $maxoff);
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
for ($i = 0; $i < $maxoff - 257; $i++)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
$fh->read($dat1, 1);
|
|
Packit |
5d935b |
$off = unpack("C", $dat1);
|
|
Packit |
5d935b |
$fh->read($dat1, $off);
|
|
Packit |
5d935b |
$strings[$i] = $dat1;
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
for ($i = 0; $i < $numGlyphs; $i++)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
$off = unpack("n", substr($dat, ($i + 1) << 1, 2));
|
|
Packit |
5d935b |
if ($off > 257)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
$self->{'VAL'}[$i] = $strings[$off - 258];
|
|
Packit |
5d935b |
$self->{'STRINGS'}{$strings[$off - 258]} = $i;
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
else
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
$self->{'VAL'}[$i] = $base_set[$off];
|
|
Packit |
5d935b |
$self->{'STRINGS'}{$base_set[$off]} = $i unless (defined $self->{'STRINGS'}{$base_set[$off]});
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
$self;
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head2 $t->out($fh)
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Writes out a new Postscript name table from memory or copies from disk
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=cut
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
sub out
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
my ($self, $fh) = @_;
|
|
Packit |
5d935b |
my ($i, $num);
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
return $self->SUPER::out($fh) unless $self->{' read'};
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$num = $self->{' PARENT'}{'maxp'}{'numGlyphs'};
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
init unless ($fields{'FormatType'});
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
for ($i = $#{$self->{'VAL'}}; !defined $self->{'VAL'}[$i] && $i > 0; $i--)
|
|
Packit |
5d935b |
{ pop(@{$self->{'VAL'}}); }
|
|
Packit |
5d935b |
if ($#{$self->{'VAL'}} < 0)
|
|
Packit |
5d935b |
{ $self->{'FormatType'} = 3; }
|
|
Packit |
5d935b |
else
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
$self->{'FormatType'} = 1;
|
|
Packit |
5d935b |
for ($i = 0; $i < $num; $i++)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
if (!defined $base_set{$self->{'VAL'}[$i]})
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
$self->{'FormatType'} = 2;
|
|
Packit |
5d935b |
last;
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
elsif ($base_set{$self->{'VAL'}[$i]} != $i)
|
|
Packit |
5d935b |
{ $self->{'FormatType'} = ($no25 ? 2 : 2.5); }
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$fh->print(TTF_Out_Fields($self, \%fields, 32));
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
return $self if (int($self->{'FormatType'} + .4) == 3);
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
if (int($self->{'FormatType'} + .5) == 2)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
my (@ind);
|
|
Packit |
5d935b |
my ($count) = 0;
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$fh->print(pack("n", $num));
|
|
Packit |
5d935b |
for ($i = 0; $i < $num; $i++)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
if (defined $base_set{$self->{'VAL'}[$i]})
|
|
Packit |
5d935b |
{ $fh->print(pack("n", $base_set{$self->{'VAL'}[$i]})); }
|
|
Packit |
5d935b |
else
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
$fh->print(pack("n", $count + 258));
|
|
Packit |
5d935b |
$ind[$count++] = $i;
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
for ($i = 0; $i < $count; $i++)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
$fh->print(pack("C", length($self->{'VAL'}[$ind[$i]])));
|
|
Packit |
5d935b |
$fh->print($self->{'VAL'}[$ind[$i]]);
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
} elsif (int($self->{'FormatType'} * 2 + .5) == 5)
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
$fh->print(pack("n", $num));
|
|
Packit |
5d935b |
for ($i = 0; $i < $num; $i++)
|
|
Packit |
5d935b |
{ $fh->print(pack("c", defined $base_set{$self->{'VAL'}[$i]} ?
|
|
Packit |
5d935b |
$base_set{$self->{'VAL'}[$i]} - $i : -$i)); }
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$self;
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head2 $t->XML_element($context, $depth, $key, $val)
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Outputs the names as one block of XML
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=cut
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
sub XML_element
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
my ($self) = shift;
|
|
Packit |
5d935b |
my ($context, $depth, $key, $val) = @_;
|
|
Packit |
5d935b |
my ($fh) = $context->{'fh'};
|
|
Packit |
5d935b |
my ($i);
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
return $self->SUPER::XML_element(@_) unless ($key eq 'STRINGS' || $key eq 'VAL');
|
|
Packit |
5d935b |
return unless ($key eq 'VAL');
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
$fh->print("$depth<names>\n");
|
|
Packit |
5d935b |
for ($i = 0; $i <= $#{$self->{'VAL'}}; $i++)
|
|
Packit |
5d935b |
{ $fh->print("$depth$context->{'indent'}<name post='$self->{'VAL'}[$i]' gid='$i'/>\n"); }
|
|
Packit |
5d935b |
$fh->print("$depth</names>\n");
|
|
Packit |
5d935b |
$self;
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head2 $t->minsize()
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Returns the minimum size this table can be. If it is smaller than this, then the table
|
|
Packit |
5d935b |
must be bad and should be deleted or whatever.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=cut
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
sub minsize
|
|
Packit |
5d935b |
{
|
|
Packit |
5d935b |
return 32;
|
|
Packit |
5d935b |
}
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
1;
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head1 BUGS
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=over 4
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=item *
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
No support for type 4 tables
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=back
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head1 AUTHOR
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Martin Hosken L<http://scripts.sil.org/FontUtils>.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=head1 LICENSING
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
Copyright (c) 1998-2016, SIL International (http://www.sil.org)
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
This module is released under the terms of the Artistic License 2.0.
|
|
Packit |
5d935b |
For details, see the full text of the license in the file LICENSE.
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
=cut
|
|
Packit |
5d935b |
|
|
Packit |
5d935b |
|