X-Git-Url: https://git.mdrn.pl/librarian.git/blobdiff_plain/e316fc14bef26f958937aec0e6854b61f71a3b34..09dded3d8606e8e4406fffcf477ceb4a1c97fee2:/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/EBLC.pm diff --git a/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/EBLC.pm b/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/EBLC.pm new file mode 100644 index 0000000..7ba6e68 --- /dev/null +++ b/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/EBLC.pm @@ -0,0 +1,228 @@ +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) = @_; + 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); + + $self->SUPER::read or return $self; + + # 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); + 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. See L for copyright and +licensing. + +This was written at the CodeFest Akihabara 2006 hosted by FSIJ. + +=cut +