260 lines
6.3 KiB
Perl
260 lines
6.3 KiB
Perl
package Font::TTF::EBLC;
|
|
|
|
=head1 NAME
|
|
|
|
Font::TTF::EBLC - Embeeded Bitmap Location Table
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
Contains the sizes and glyph ranges of bitmaps, and the offsets to
|
|
glyph bitmap data in indexSubTables for EBDT.
|
|
|
|
Possibly contains glyph metrics information.
|
|
|
|
=head1 INSTANCE VARIABLES
|
|
|
|
The information specified 'B<(R)>ead only' is read only, those
|
|
are calculated from EBDT, when it is 'update'-ed.
|
|
|
|
=over 4
|
|
|
|
=item bitmapSizeTable
|
|
|
|
An array of tables of following information
|
|
|
|
=over 8
|
|
|
|
=item indexSubTableArrayOffset (R)
|
|
|
|
=item indexTablesSize (R)
|
|
|
|
=item numberOfIndexSubTables (R)
|
|
|
|
=item colorRef
|
|
|
|
=item hori
|
|
|
|
=item vert
|
|
|
|
=item startGlyphIndex (R)
|
|
|
|
=item endGlyphIndex (R)
|
|
|
|
=item ppemX
|
|
|
|
=item ppemY
|
|
|
|
=item bitDepth
|
|
|
|
=item flags
|
|
|
|
=back
|
|
|
|
=item indexSubTableArray (R)
|
|
|
|
An array which contains range information.
|
|
|
|
=item indexSubTable (R)
|
|
|
|
An array which contains offsets of EBDT table.
|
|
|
|
=back
|
|
|
|
=head1 METHODS
|
|
|
|
=cut
|
|
|
|
use strict;
|
|
use vars qw(@ISA);
|
|
require Font::TTF::Table;
|
|
|
|
@ISA = qw(Font::TTF::Table);
|
|
|
|
|
|
=head2 $t->read
|
|
|
|
Reads the location information of embedded bitmap from the TTF file into memory
|
|
|
|
=cut
|
|
|
|
sub read
|
|
{
|
|
my ($self) = @_;
|
|
|
|
$self->SUPER::read or return $self;
|
|
|
|
my ($fh) = $self->{' INFILE'};
|
|
my ($i, $dat);
|
|
my ($indexSubTableArrayOffset,
|
|
$indexTablesSize,
|
|
$numberOfIndexSubTables,
|
|
$colorRef);
|
|
my ($startGlyphIndex,
|
|
$endGlyphIndex,
|
|
$ppemX, $ppemY,
|
|
$bitDepth, $flags);
|
|
my (@hori, @vert);
|
|
my ($bst, $ista, $ist);
|
|
my ($j);
|
|
|
|
|
|
# eblcHeader
|
|
$fh->read($dat, 4);
|
|
$self->{'version'} = unpack("N",$dat);
|
|
|
|
$fh->read($dat, 4);
|
|
$self->{'Num'} = unpack("N",$dat);
|
|
|
|
# bitmapSizeTable
|
|
for ($i = 0; $i < $self->{'Num'}; $i++) {
|
|
$fh->read($dat, 16);
|
|
($indexSubTableArrayOffset, $indexTablesSize,
|
|
$numberOfIndexSubTables, $colorRef) = unpack("NNNN", $dat);
|
|
$fh->read($dat, 12); @hori = unpack("cccccccccccc", $dat);
|
|
$fh->read($dat, 12); @vert = unpack("cccccccccccc", $dat);
|
|
|
|
$fh->read($dat, 8);
|
|
($startGlyphIndex, $endGlyphIndex,
|
|
$ppemX, $ppemY, $bitDepth, $flags) = unpack("nnCCCC", $dat);
|
|
|
|
$self->{'bitmapSizeTable'}[$i] = {
|
|
'indexSubTableArrayOffset' => $indexSubTableArrayOffset,
|
|
'indexTablesSize' => $indexTablesSize,
|
|
'numberOfIndexSubTables' => $numberOfIndexSubTables,
|
|
'colorRef' => $colorRef,
|
|
'hori' => [@hori],
|
|
'vert' => [@vert],
|
|
'startGlyphIndex' => $startGlyphIndex,
|
|
'endGlyphIndex' => $endGlyphIndex,
|
|
'ppemX' => $ppemX,
|
|
'ppemY' => $ppemY,
|
|
'bitDepth' => $bitDepth,
|
|
'flags' => $flags
|
|
};
|
|
}
|
|
|
|
for ($i = 0; $i < $self->{'Num'}; $i++) {
|
|
my ($count, $x);
|
|
|
|
$bst = $self->{'bitmapSizeTable'}[$i];
|
|
|
|
for ($j = 0; $j < $bst->{'numberOfIndexSubTables'}; $j++) {
|
|
$ista = {};
|
|
|
|
# indexSubTableArray
|
|
$self->{'indexSubTableArray'}[$i][$j] = $ista;
|
|
$fh->read($dat, 8);
|
|
($ista->{'firstGlyphIndex'},
|
|
$ista->{'lastGlyphIndex'},
|
|
$ista->{'additionalOffsetToIndexSubtable'})
|
|
= unpack("nnN", $dat);
|
|
}
|
|
|
|
# indexSubTable
|
|
# indexSubHeader
|
|
$fh->read($dat, 8);
|
|
($bst->{'indexFormat'},
|
|
$bst->{'imageFormat'},
|
|
$bst->{'imageDataOffset'}) = unpack("nnN", $dat);
|
|
|
|
die "Only indexFormat == 1 is supported" unless ($bst->{'indexFormat'} == 1);
|
|
|
|
for ($j = 0; $j < $bst->{'numberOfIndexSubTables'}; $j++) {
|
|
$ista = $self->{'indexSubTableArray'}[$i][$j];
|
|
$count = $ista->{'lastGlyphIndex'} - $ista->{'firstGlyphIndex'} + 1 + 1;
|
|
$fh->seek($self->{' OFFSET'} + $bst->{'indexSubTableArrayOffset'}
|
|
+ $ista->{'additionalOffsetToIndexSubtable'} + 8, 0);
|
|
|
|
# $count += 2 if $j < $bst->{'numberOfIndexSubTables'} - 1;
|
|
|
|
$fh->read($dat, 4*$count);
|
|
|
|
$self->{'indexSubTable'}[$i][$j] = [unpack("N*", $dat)];
|
|
}
|
|
}
|
|
|
|
$self;
|
|
}
|
|
|
|
=head2 $t->out($fh)
|
|
|
|
Outputs the location information of embedded bitmap for this font.
|
|
|
|
=cut
|
|
|
|
sub out
|
|
{
|
|
my ($self, $fh) = @_;
|
|
my ($i);
|
|
|
|
return $self->SUPER::out($fh) unless $self->{' read'};
|
|
|
|
my ($bst_array) = $self->{'bitmapSizeTable'};
|
|
|
|
$fh->print(pack("N", 0x00020000));
|
|
$fh->print(pack("N", $self->{'Num'}));
|
|
|
|
for ($i = 0; $i < $self->{'Num'}; $i++) {
|
|
my ($bst) = $bst_array->[$i];
|
|
|
|
$fh->print(pack("NNNN",
|
|
$bst->{'indexSubTableArrayOffset'},
|
|
$bst->{'indexTablesSize'},
|
|
$bst->{'numberOfIndexSubTables'},
|
|
$bst->{'colorRef'}));
|
|
$fh->print(pack("cccccccccccc", @{$bst->{'hori'}}));
|
|
$fh->print(pack("cccccccccccc", @{$bst->{'vert'}}));
|
|
$fh->print(pack("nnCCCC", $bst->{'startGlyphIndex'},
|
|
$bst->{'endGlyphIndex'}, $bst->{'ppemX'},
|
|
$bst->{'ppemY'}, $bst->{'bitDepth'}, $bst->{'flags'}));
|
|
}
|
|
|
|
for ($i = 0; $i < $self->{'Num'}; $i++) {
|
|
my ($bst) = $bst_array->[$i];
|
|
my ($j);
|
|
|
|
for ($j = 0; $j < $bst->{'numberOfIndexSubTables'}; $j++) {
|
|
my ($ista) = $self->{'indexSubTableArray'}[$i][$j];
|
|
|
|
$fh->print("nnN",
|
|
$ista->{'firstGlyphIndex'},
|
|
$ista->{'lastGlyphIndex'},
|
|
$ista->{'additionalOffsetToIndexSubtable'});
|
|
}
|
|
|
|
$fh->print(pack("nnN", $bst->{'indexFormat'}, $bst->{'imageFormat'},
|
|
$bst->{'imageDataOffset'}));
|
|
|
|
die "Only indexFormat == 1 is supported" unless ($bst->{'indexFormat'} == 1);
|
|
|
|
for ($j = 0; $j < $bst->{'numberOfIndexSubTables'}; $j++) {
|
|
$fh->print(pack("N*", $self->{'indexSubTable'}[$i][$j]));
|
|
}
|
|
}
|
|
}
|
|
|
|
1;
|
|
|
|
=head1 BUGS
|
|
|
|
Only indexFormat ==1 is implemented. XML output is not supported (yet).
|
|
|
|
=head1 AUTHOR
|
|
|
|
NIIBE Yutaka L<mailto:gniibe@fsij.org>.
|
|
This was written at the CodeFest Akihabara 2006 hosted by FSIJ.
|
|
|
|
Patch sent with licensing requirements??
|
|
|
|
=head1 LICENSING
|
|
|
|
Copyright (c) 1998-2016, SIL International (http://www.sil.org)
|
|
|
|
This module is released under the terms of the Artistic License 2.0.
|
|
For details, see the full text of the license in the file LICENSE.
|
|
|
|
|
|
|
|
=cut
|
|
|