PDF-API2

 view release on metacpan or  search on metacpan

lib/PDF/API2/Resource/CIDFont/TrueType/FontFile.pm  view on Meta::CPAN

    my $dict = {};
    foreach my $k (qw(CIDCount CIDFontVersion FamilyName FontBBX FullName ROS Weight XUID)) {
        $dict->{$k} = $data->{'topdict'}->[0]->{'VAL'}->{$k} if defined $data->{'topdict'}->[0]->{'VAL'}->{$k};
    }
    return $dict;
}

sub new {
    my ($class, $pdf, $file, %opts) = @_;
    my $data = {};
    my $font;

    # If the file is already a suitable font object, use it.
    if ( UNIVERSAL::isa( $file, 'Font::TTF::Font' ) ) {
	$font = $file;
    }
    else {
	confess "cannot find font '$file'" unless -f $file;
	$font = Font::TTF::Font->open($file);
    }
    $data->{'obj'} = $font;

    $class = ref($class) if ref($class);
    my $self = $class->SUPER::new();

    $self->{'Filter'} = PDFArray(PDFName('FlateDecode'));
    $self->{' font'} = $font;
    $self->{' data'} = $data;

    $data->{'noembed'} = $opts{'embed'} ? 0 : 1;
    $data->{'iscff'} = defined($font->{'CFF '}) ? 1 : 0;

    $self->{'Subtype'} = PDFName('CIDFontType0C') if $data->{'iscff'};

    $data->{'fontfamily'} = $font->{'name'}->read->find_name(1);
    $data->{'fontname'} = $font->{'name'}->read->find_name(4);

    $font->{'OS/2'}->read();
    my @stretch = qw(
        Normal
        UltraCondensed
        ExtraCondensed
        Condensed
        SemiCondensed
        Normal
        SemiExpanded
        Expanded
        ExtraExpanded
        UltraExpanded
    );
    $data->{'fontstretch'} = $stretch[$font->{'OS/2'}->{'usWidthClass'}] || 'Normal';

    $data->{'fontweight'} = $font->{'OS/2'}->{'usWeightClass'};

    $data->{'panose'} = pack('n', $font->{'OS/2'}->{'sFamilyClass'});

    foreach my $p (qw[bFamilyType bSerifStyle bWeight bProportion bContrast bStrokeVariation bArmStyle bLetterform bMidline bXheight]) {
        $data->{'panose'} .= pack('C', $font->{'OS/2'}->{$p});
    }

    $data->{'apiname'} = join('', map { ucfirst(lc(substr($_, 0, 2))) } split m/[^A-Za-z0-9\s]+/, $data->{'fontname'});
    $data->{'fontname'} =~ s/[\x00-\x1f\s]//g;

    $data->{'altname'} = $font->{'name'}->find_name(1);
    $data->{'altname'} =~ s/[\x00-\x1f\s]//g;

    $data->{'subname'} = $font->{'name'}->find_name(2);
    $data->{'subname'} =~ s/[\x00-\x1f\s]//g;

    $font->{'cmap'}->read->find_ms();
    if (defined $font->{'cmap'}->find_ms()) {
        $data->{'issymbol'} = ($font->{'cmap'}->find_ms->{'Platform'} == 3 and $font->{'cmap'}->read->find_ms->{'Encoding'} == 0) || 0;
    }
    else {
        $data->{'issymbol'} = 0;
    }

    $data->{'upem'} = $font->{'head'}->read->{'unitsPerEm'};

    $data->{'fontbbox'} = [
        int($font->{'head'}->{'xMin'} * 1000 / $data->{'upem'}),
        int($font->{'head'}->{'yMin'} * 1000 / $data->{'upem'}),
        int($font->{'head'}->{'xMax'} * 1000 / $data->{'upem'}),
        int($font->{'head'}->{'yMax'} * 1000 / $data->{'upem'}),
    ];

    $data->{'stemv'} = 0;
    $data->{'stemh'} = 0;

    $data->{'missingwidth'} = int($font->{'hhea'}->read->{'advanceWidthMax'} * 1000 / $data->{'upem'}) || 1000;
    $data->{'maxwidth'} = int($font->{'hhea'}->{'advanceWidthMax'} * 1000 / $data->{'upem'});
    $data->{'ascender'} = int($font->{'hhea'}->read->{'Ascender'} * 1000 / $data->{'upem'});
    $data->{'descender'} = int($font->{'hhea'}{'Descender'} * 1000 / $data->{'upem'});

    $data->{'flags'} = 0;
    $data->{'flags'} |= 1 if $font->{'OS/2'}->read->{'bProportion'} == 9;
    $data->{'flags'} |= 2 unless $font->{'OS/2'}{'bSerifStyle'} > 10 and $font->{'OS/2'}{'bSerifStyle'} < 14;
    $data->{'flags'} |= 8 if $font->{'OS/2'}{'bFamilyType'} == 2;
    $data->{'flags'} |= 32; # if $font->{'OS/2'}{'bFamilyType'} > 3;
    $data->{'flags'} |= 64 if $font->{'OS/2'}{'bLetterform'} > 8;

    $data->{'capheight'} = $font->{'OS/2'}->{'CapHeight'} || int($data->{'fontbbox'}->[3] * 0.8);
    $data->{'xheight'} = $font->{'OS/2'}->{'xHeight'} || int($data->{'fontbbox'}->[3] * 0.4);

    if ($data->{'issymbol'}) {
        $data->{'e2u'} = [0xf000 .. 0xf0ff];
    }
    else {
        $data->{'e2u'} = [unpack('U*', decode('cp1252', pack('C*', 0 .. 255)))];
    }

    if ($font->{'post'}->read->{'FormatType'} == 3 and defined $font->{'cmap'}->read->find_ms()) {
        $data->{'g2n'} = [];
        foreach my $u (sort { $a <=> $b } keys %{$font->{'cmap'}->read->find_ms->{'val'}}) {
            my $n = nameByUni($u);
            $data->{'g2n'}->[$font->{'cmap'}->read->find_ms->{'val'}->{$u}] = $n;
        }
    }
    else {
        $data->{'g2n'} = [ map { $_ || '.notdef' } @{$font->{'post'}->read->{'VAL'}} ];
    }



( run in 2.836 seconds using v1.01-cache-2.11-cpan-71847e10f99 )