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