Introduce src dir.
[librarian.git] / src / librarian / font-optimizer / ext / Font-TTF / lib / Font / TTF / EBLC.pm
diff --git a/src/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/EBLC.pm b/src/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/EBLC.pm
new file mode 100644 (file)
index 0000000..7ba6e68
--- /dev/null
@@ -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<gniibe@fsij.org>.  See L<Font::TTF::Font> for copyright and
+licensing.
+
+This was written at the CodeFest Akihabara 2006 hosted by FSIJ.
+
+=cut
+