Blame lib/Font/TTF/Maxp.pm

Packit 5d935b
package Font::TTF::Maxp;
Packit 5d935b
Packit 5d935b
=head1 NAME
Packit 5d935b
Packit 5d935b
Font::TTF::Maxp - Maximum Profile table in a font
Packit 5d935b
Packit 5d935b
=head1 DESCRIPTION
Packit 5d935b
Packit 5d935b
A collection of useful instance variables following the TTF standard. Probably
Packit 5d935b
the most used being C<numGlyphs>. Note that this particular value is
Packit 5d935b
foundational and should be kept up to date by the application, it is not updated
Packit 5d935b
by C<update>.
Packit 5d935b
Packit 5d935b
Handles table versions 0.5, 1.0
Packit 5d935b
Packit 5d935b
=head1 INSTANCE VARIABLES
Packit 5d935b
Packit 5d935b
No others beyond those specified in the standard:
Packit 5d935b
Packit 5d935b
    numGlyphs
Packit 5d935b
    maxPoints
Packit 5d935b
    maxContours
Packit 5d935b
    maxCompositePoints
Packit 5d935b
    maxCompositeContours
Packit 5d935b
    maxZones
Packit 5d935b
    maxTwilightPoints
Packit 5d935b
    maxStorage
Packit 5d935b
    maxFunctionDefs
Packit 5d935b
    maxInstructionDefs
Packit 5d935b
    maxStackElements
Packit 5d935b
    maxSizeOfInstructions
Packit 5d935b
    maxComponentElements
Packit 5d935b
    maxComponentDepth
Packit 5d935b
Packit 5d935b
Packit 5d935b
=head1 METHODS
Packit 5d935b
Packit 5d935b
=cut
Packit 5d935b
Packit 5d935b
use strict;
Packit 5d935b
use vars qw(@ISA %fields @field_info);
Packit 5d935b
use Font::TTF::Utils;
Packit 5d935b
Packit 5d935b
@ISA = qw(Font::TTF::Table);
Packit 5d935b
@field_info = (
Packit 5d935b
    'numGlyphs' => 'S',
Packit 5d935b
    'maxPoints' => 'S',
Packit 5d935b
    'maxContours' => 'S',
Packit 5d935b
    'maxCompositePoints' => 'S',
Packit 5d935b
    'maxCompositeContours' => 'S',
Packit 5d935b
    'maxZones' => 'S',
Packit 5d935b
    'maxTwilightPoints' => 'S',
Packit 5d935b
    'maxStorage' => 'S',
Packit 5d935b
    'maxFunctionDefs' => 'S',
Packit 5d935b
    'maxInstructionDefs' => 'S',
Packit 5d935b
    'maxStackElements' => 'S',
Packit 5d935b
    'maxSizeOfInstructions' => 'S',
Packit 5d935b
    'maxComponentElements' => 'S',
Packit 5d935b
    'maxComponentDepth' => 'S');
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
}
Packit 5d935b
Packit 5d935b
Packit 5d935b
=head2 $t->read
Packit 5d935b
Packit 5d935b
Reads the table into memory
Packit 5d935b
Packit 5d935b
=cut
Packit 5d935b
Packit 5d935b
sub read
Packit 5d935b
{
Packit 5d935b
    my ($self) = @_;
Packit 5d935b
    my ($dat);
Packit 5d935b
Packit 5d935b
    $self->SUPER::read or return $self;
Packit 5d935b
Packit 5d935b
    init unless defined $fields{'numGlyphs'};    # any key would do
Packit 5d935b
    $self->{' INFILE'}->read($dat, 4);
Packit 5d935b
    $self->{'version'} = TTF_Unpack("v", $dat);
Packit 5d935b
Packit 5d935b
    if ($self->{'version'} == 0.5)
Packit 5d935b
    {
Packit 5d935b
        $self->{' INFILE'}->read($dat, 2);
Packit 5d935b
        $self->{'numGlyphs'} = unpack("n", $dat);
Packit 5d935b
    } else
Packit 5d935b
    {
Packit 5d935b
        $self->{' INFILE'}->read($dat, 28);
Packit 5d935b
        TTF_Read_Fields($self, $dat, \%fields);
Packit 5d935b
    }
Packit 5d935b
    $self;
Packit 5d935b
}
Packit 5d935b
Packit 5d935b
Packit 5d935b
=head2 $t->out($fh)
Packit 5d935b
Packit 5d935b
Writes the table to a file either from memory or by copying.
Packit 5d935b
Packit 5d935b
=cut
Packit 5d935b
Packit 5d935b
sub out
Packit 5d935b
{
Packit 5d935b
    my ($self, $fh) = @_;
Packit 5d935b
Packit 5d935b
    return $self->SUPER::out($fh) unless $self->{' read'};
Packit 5d935b
    $fh->print(TTF_Pack("v", $self->{'version'}));
Packit 5d935b
    
Packit 5d935b
    if ($self->{'version'} == 0.5)
Packit 5d935b
    { $fh->print(pack("n", $self->{'numGlyphs'})); }
Packit 5d935b
    else
Packit 5d935b
    { $fh->print(TTF_Out_Fields($self, \%fields, 28)); }
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 4;
Packit 5d935b
}
Packit 5d935b
Packit 5d935b
Packit 5d935b
=head2 $t->update
Packit 5d935b
Packit 5d935b
Calculates all the maximum values for a font based on the glyphs in the font.
Packit 5d935b
Only those fields which require hinting code interpretation are ignored and
Packit 5d935b
left as they were read.
Packit 5d935b
Packit 5d935b
=cut
Packit 5d935b
Packit 5d935b
sub update
Packit 5d935b
{
Packit 5d935b
    my ($self) = @_;
Packit 5d935b
    my ($i, $num, @n, @m, $j);
Packit 5d935b
    my (@name) = qw(maxPoints maxContours maxCompositePoints maxCompositeContours
Packit 5d935b
                    maxSizeOfInstructions maxComponentElements maxComponentDepth);
Packit 5d935b
Packit 5d935b
    return undef unless ($self->SUPER::update);
Packit 5d935b
    return undef if ($self->{'version'} == 0.5);        # only got numGlyphs
Packit 5d935b
    return undef unless (defined $self->{' PARENT'}{'loca'});
Packit 5d935b
    $self->{' PARENT'}{'loca'}->update;
Packit 5d935b
    $num = $self->{'numGlyphs'};
Packit 5d935b
Packit 5d935b
    for ($i = 0; $i < $num; $i++)
Packit 5d935b
    {
Packit 5d935b
        my ($g) = $self->{' PARENT'}{'loca'}{'glyphs'}[$i] || next;
Packit 5d935b
Packit 5d935b
        @n = $g->maxInfo;
Packit 5d935b
Packit 5d935b
        for ($j = 0; $j <= $#n; $j++)
Packit 5d935b
        { $m[$j] = $n[$j] if $n[$j] > $m[$j]; }
Packit 5d935b
    }
Packit 5d935b
Packit 5d935b
    foreach ('prep', 'fpgm')
Packit 5d935b
    { $m[4] = length($self->{' PARENT'}{$_}{' dat'})
Packit 5d935b
            if (defined $self->{' PARENT'}{$_} 
Packit 5d935b
                && length($self->{' PARENT'}{$_}{' dat'}) > $m[4]);
Packit 5d935b
    }
Packit 5d935b
Packit 5d935b
    for ($j = 0; $j <= $#name; $j++)
Packit 5d935b
    { $self->{$name[$j]} = $m[$j]; }
Packit 5d935b
    $self;
Packit 5d935b
}
Packit 5d935b
1;
Packit 5d935b
Packit 5d935b
Packit 5d935b
=head1 BUGS
Packit 5d935b
Packit 5d935b
None known
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