X-Git-Url: https://git.mdrn.pl/librarian.git/blobdiff_plain/e9aeedc51047d8d5e9e45c5253c776f8994da965..3a0c83394d5783715fab2be29fa1a9cfc3574e28:/src/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/Glyph.pm diff --git a/src/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/Glyph.pm b/src/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/Glyph.pm deleted file mode 100644 index 28233cf..0000000 --- a/src/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/Glyph.pm +++ /dev/null @@ -1,847 +0,0 @@ -package Font::TTF::Glyph; - -=head1 NAME - -Font::TTF::Glyph - Holds a single glyph's information - -=head1 DESCRIPTION - -This is a single glyph description as held in a TT font. On creation only its -header is read. Thus you can get the bounding box of each glyph without having -to read all the other information. - -=head1 INSTANCE VARIABLES - -In addition to the named variables in a glyph header (C etc.), there are -also all capital instance variables for holding working information, mostly -from the location table. - -The standard attributes each glyph has are: - - numberOfContours - xMin - yMin - xMax - yMax - -There are also other, derived, instance variables for each glyph which are read -when the whole glyph is read (via C): - -=over 4 - -=item instLen - -Number of bytes in the hinting instructions (Warning this variable is deprecated, -use C{'hints'})> instead). - -=item hints - -The string containing the hinting code for the glyph - -=back - -In addition there are other attribute like instance variables for simple glyphs: - -=over 4 - -For each contour there is: - -=over 4 - -=item endPoints - -An array of endpoints for each contour in the glyph. There are -C contours in a glyph. The number of points in a glyph is -equal to the highest endpoint of a contour. - -=back - -There are also a number of arrays indexed by point number - -=over 4 - -=item flags - -The flags associated with reading this point. The flags for a point are -recalculated for a point when it is Cd. Thus the flags are not very -useful. The only important bit is bit 0 which indicates whether the point is -an 'on' curve point, or an 'off' curve point. - -=item x - -The absolute x co-ordinate of the point. - -=item y - -The absolute y co-ordinate of the point - -=back - -=back - -For composite glyphs there are other variables - -=over 4 - -=item metric - -This holds the component number (not its glyph number) of the component from -which the metrics for this glyph should be taken. - -=item comps - -This is an array of hashes for each component. Each hash has a number of -elements: - -=over 4 - -=item glyph - -The glyph number of the glyph which comprises this component of the composite. -NOTE: In some badly generated fonts, C may contain a numerical value -but that glyph might not actually exist in the font file. This could -occur in any glyph, but is particularly likely for glyphs that have -no strokes, such as SPACE, U+00A0 NO-BREAK SPACE, or -U+200B ZERO WIDTH SPACE. - -=item args - -An array of two arguments which may be an x, y co-ordinate or two attachment -points (one on the base glyph the other on the component). See flags for details. - -=item flag - -The flag for this component - -=item scale - -A 4 number array for component scaling. This allows stretching, rotating, etc. -Note that scaling applies to placement co-ordinates (rather than attachment points) -before locating rather than after. - -=back - -=item numPoints - -This is a generated value which contains the number of components read in for this -compound glyph. - -=back - -The private instance variables are: - -=over 4 - -=item INFILE (P) - -The input file form which to read any information - -=item LOC (P) - -Location relative to the start of the glyf table in the read file - -=item BASE (P) - -The location of the glyf table in the read file - -=item LEN (P) - -This is the number of bytes required by the glyph. It should be kept up to date -by calling the C method whenever any of the glyph content changes. - -=item OUTLOC (P) - -Location relative to the start of the glyf table. This variable is only active -whilst the output process is going on. It is used to inform the location table -where the glyph's location is, since the glyf table is output before the loca -table due to alphabetical ordering. - -=item OUTLEN (P) - -This indicates the length of the glyph data when it is output. This more -accurately reflects the internal memory form than the C variable which -only reflects the read file length. The C variable is only set after -calling C or C. - -=back - -=head2 Editing - -If you want to edit a glyph in some way, then you should read_dat the glyph, then -make your changes and then update the glyph or set the $g->{' isdirty'} variable. -It is the application's duty to ensure that the following instance variables are -correct, from which update will calculate the rest, including the bounding box -information. - - numPoints - numberOfContours - endPoints - x, y, flags (only flags bit 0) - instLen - hints - -For components, the numPoints, x, y, endPoints & flags are not required but -the following information is required for each component. - - flag (bits 2, 10, 11, 12) - glyph - args - scale - metric (glyph instance variable) - - -=head1 METHODS - -=cut - -use strict; -use vars qw(%fields @field_info); -use Font::TTF::Utils; -use Font::TTF::Table; - -@field_info = ( - 'numberOfContours' => 's', - 'xMin' => 's', - 'yMin' => 's', - 'xMax' => 's', - 'yMax' => 's'); - -sub init -{ - my ($k, $v, $c, $i); - for ($i = 0; $i < $#field_info; $i += 2) - { - ($k, $v, $c) = TTF_Init_Fields($field_info[$i], $c, $field_info[$i + 1]); - next unless defined $k && $k ne ""; - $fields{$k} = $v; - } -} - - -=head1 Font::TTF::Glyph->new(%parms) - -Creates a new glyph setting various instance variables - -=cut - -sub new -{ - my ($class, %parms) = @_; - my ($self) = {}; - my ($p); - - bless $self, $class; - foreach $p (keys %parms) - { $self->{" $p"} = $parms{$p}; } - init unless defined $fields{'xMin'}; - $self; -} - - -=head2 $g->read - -Reads the header component of the glyph (bounding box, etc.) and also the -glyph content, but into a data field rather than breaking it down into -its constituent structures. Use read_dat for this. - -=cut - -sub read -{ - my ($self) = @_; - my ($fh) = $self->{' INFILE'}; - my ($dat); - - return $self if $self->{' read'}; - $self->{' read'} = 1; - $fh->seek($self->{' LOC'} + $self->{' BASE'}, 0); - $fh->read($self->{' DAT'}, $self->{' LEN'}); - TTF_Read_Fields($self, $self->{' DAT'}, \%fields); - $self; -} - - -=head2 $g->read_dat - -Reads the contents of the glyph (components and curves, etc.) from the memory -store C into structures within the object. Then, to indicate where the -master form of the data is, it deletes the C instance variable. - -=cut - -sub read_dat -{ - my ($self) = @_; - my ($dat, $num, $max, $i, $flag, $len, $val, $val1, $fp); - - return $self if (defined $self->{' read'} && $self->{' read'} > 1); - $self->read unless $self->{' read'}; - $dat = $self->{' DAT'}; - $fp = 10; - $num = $self->{'numberOfContours'}; - if ($num > 0) - { - $self->{'endPoints'} = [unpack("n*", substr($dat, $fp, $num << 1))]; - $fp += $num << 1; - $max = 0; - foreach (@{$self->{'endPoints'}}) - { $max = $_ if $_ > $max; } -# print STDERR join(",", unpack('C*', $self->{" DAT"})); -# printf STDERR ("(%d,%d in %d=%d @ %d)", scalar @{$self->{'endPoints'}}, $max, length($dat), $self->{' LEN'}, $fp); - $max++ if (@{$self->{'endPoints'}}); - $self->{'numPoints'} = $max; - $self->{'instLen'} = unpack("n", substr($dat, $fp)); - $self->{'hints'} = substr($dat, $fp + 2, $self->{'instLen'}); - $fp += 2 + $self->{'instLen'}; -# read the flags array - for ($i = 0; $i < $max; $i++) - { - $flag = unpack("C", substr($dat, $fp++)); - $self->{'flags'}[$i] = $flag; - if ($flag & 8) - { - $len = unpack("C", substr($dat, $fp++)); - while ($len-- > 0) - { - $i++; - $self->{'flags'}[$i] = $flag; - } - } - } -#read the x array - for ($i = 0; $i < $max; $i++) - { - $flag = $self->{'flags'}[$i]; - if ($flag & 2) - { - $val = unpack("C", substr($dat, $fp++)); - $val = -$val unless ($flag & 16); - } elsif ($flag & 16) - { $val = 0; } - else - { - $val = TTF_Unpack("s", substr($dat, $fp)); - $fp += 2; - } - $self->{'x'}[$i] = $i == 0 ? $val : $self->{'x'}[$i - 1] + $val; - } -#read the y array - for ($i = 0; $i < $max; $i++) - { - $flag = $self->{'flags'}[$i]; - if ($flag & 4) - { - $val = unpack("C", substr($dat, $fp++)); - $val = -$val unless ($flag & 32); - } elsif ($flag & 32) - { $val = 0; } - else - { - $val = TTF_Unpack("s", substr($dat, $fp)); - $fp += 2; - } - $self->{'y'}[$i] = $i == 0 ? $val : $self->{'y'}[$i - 1] + $val; - } - } - -# compound glyph - elsif ($num < 0) - { - $flag = 1 << 5; # cheat to get the loop going - for ($i = 0; $flag & 32; $i++) - { - ($flag, $self->{'comps'}[$i]{'glyph'}) = unpack("n2", substr($dat, $fp)); - $fp += 4; - $self->{'comps'}[$i]{'flag'} = $flag; - if ($flag & 1) # ARGS1_AND_2_ARE_WORDS - { - $self->{'comps'}[$i]{'args'} = [TTF_Unpack("s2", substr($dat, $fp))]; - $fp += 4; - } else - { - $self->{'comps'}[$i]{'args'} = [unpack("c2", substr($dat, $fp))]; - $fp += 2; - } - - if ($flag & 8) - { - $val = TTF_Unpack("F", substr($dat, $fp)); - $fp += 2; - $self->{'comps'}[$i]{'scale'} = [$val, 0, 0, $val]; - } elsif ($flag & 64) - { - ($val, $val1) = TTF_Unpack("F2", substr($dat, $fp)); - $fp += 4; - $self->{'comps'}[$i]{'scale'} = [$val, 0, 0, $val1]; - } elsif ($flag & 128) - { - $self->{'comps'}[$i]{'scale'} = [TTF_Unpack("F4", substr($dat, $fp))]; - $fp += 8; - } - $self->{'metric'} = $i if ($flag & 512); - } - $self->{'numPoints'} = $i; - if ($flag & 256) # HAVE_INSTRUCTIONS - { - $self->{'instLen'} = unpack("n", substr($dat, $fp)); - $self->{'hints'} = substr($dat, $fp + 2, $self->{'instLen'}); - $fp += 2 + $self->{'instLen'}; - } - } - return undef if ($fp > length($dat)); - $self->{' read'} = 2; - $self; -} - - -=head2 $g->out($fh) - -Writes the glyph data to outfile - -=cut - -sub out -{ - my ($self, $fh) = @_; - - $self->read unless $self->{' read'}; - $self->update if $self->{' isDirty'}; - $fh->print($self->{' DAT'}); - $self->{' OUTLEN'} = length($self->{' DAT'}); - $self; -} - - -=head2 $g->out_xml($context, $depth) - -Outputs an XML description of the glyph - -=cut - -sub out_xml -{ - my ($self, $context, $depth) = @_; - my ($addr) = ($self =~ m/\((.+)\)$/o); - my ($k, $ndepth); - - if ($context->{'addresses'}{$addr}) - { - $context->{'fh'}->printf("%s\n", $depth, $context->{'gid'}, $addr); - return $self; - } - else - { - $context->{'fh'}->printf("%s\n", $depth, $context->{'gid'}, $addr); - } - - $ndepth = $depth . $context->{'indent'}; - $self->read_dat; - foreach $k (sort grep {$_ !~ m/^\s/o} keys %{$self}) - { - $self->XML_element($context, $ndepth, $k, $self->{$k}); - } - $context->{'fh'}->print("$depth\n"); - delete $context->{'done_points'}; - $self; -} - - -sub XML_element -{ - my ($self, $context, $depth, $key, $val) = @_; - my ($fh) = $context->{'fh'}; - my ($dind) = $depth . $context->{'indent'}; - my ($i); - - if ($self->{'numberOfContours'} >= 0 && ($key eq 'x' || $key eq 'y' || $key eq 'flags')) - { - return $self if ($context->{'done_points'}); - $context->{'done_points'} = 1; - - $fh->print("$depth\n"); - for ($i = 0; $i <= $#{$self->{'flags'}}; $i++) - { $fh->printf("%s\n", $dind, - $self->{'x'}[$i], $self->{'y'}[$i], $self->{'flags'}[$i]); } - $fh->print("$depth\n"); - } - elsif ($key eq 'hints') - { - my ($dat); - $fh->print("$depth\n"); -# Font::TTF::Utils::XML_hexdump($context, $depth . $context->{'indent'}, $self->{'hints'}); - $dat = Font::TTF::Utils::XML_binhint($self->{'hints'}) || ""; - $dat =~ s/\n(?!$)/\n$depth$context->{'indent'}/mg; - $fh->print("$depth$context->{'indent'}$dat"); - $fh->print("$depth\n"); - } - else - { return Font::TTF::Table::XML_element(@_); } - - $self; -} - - -=head2 $g->update - -Generates a C<$self->{'DAT'}> from the internal structures, if the data has -been read into structures in the first place. If you are building a glyph -from scratch you will need to set the instance variable C<' read'> to 2 (or -something > 1) for the update to work. - -=cut - -sub update -{ - my ($self) = @_; - my ($dat, $loc, $len, $flag, $x, $y, $i, $comp, $num); - - return $self unless (defined $self->{' read'} && $self->{' read'} > 1); - $self->update_bbox; - $self->{' DAT'} = TTF_Out_Fields($self, \%fields, 10); - $num = $self->{'numberOfContours'}; - if ($num > 0) - { - $self->{' DAT'} .= pack("n*", @{$self->{'endPoints'}}); - $len = $self->{'instLen'}; - $self->{' DAT'} .= pack("n", $len); - $self->{' DAT'} .= pack("a" . $len, substr($self->{'hints'}, 0, $len)) if ($len > 0); - for ($i = 0; $i < $self->{'numPoints'}; $i++) - { - $flag = $self->{'flags'}[$i] & 1; - if ($i == 0) - { - $x = $self->{'x'}[$i]; - $y = $self->{'y'}[$i]; - } else - { - $x = $self->{'x'}[$i] - $self->{'x'}[$i - 1]; - $y = $self->{'y'}[$i] - $self->{'y'}[$i - 1]; - } - $flag |= 16 if ($x == 0); - $flag |= 32 if ($y == 0); - if (($flag & 16) == 0 && $x < 256 && $x > -256) - { - $flag |= 2; - $flag |= 16 if ($x >= 0); - } - if (($flag & 32) == 0 && $y < 256 && $y > -256) - { - $flag |= 4; - $flag |= 32 if ($y >= 0); - } - $self->{' DAT'} .= pack("C", $flag); # sorry no repeats - $self->{'flags'}[$i] = $flag; - } - for ($i = 0; $i < $self->{'numPoints'}; $i++) - { - $flag = $self->{'flags'}[$i]; - $x = $self->{'x'}[$i] - (($i == 0) ? 0 : $self->{'x'}[$i - 1]); - if (($flag & 18) == 0) - { $self->{' DAT'} .= TTF_Pack("s", $x); } - elsif (($flag & 18) == 18) - { $self->{' DAT'} .= pack("C", $x); } - elsif (($flag & 18) == 2) - { $self->{' DAT'} .= pack("C", -$x); } - } - for ($i = 0; $i < $self->{'numPoints'}; $i++) - { - $flag = $self->{'flags'}[$i]; - $y = $self->{'y'}[$i] - (($i == 0) ? 0 : $self->{'y'}[$i - 1]); - if (($flag & 36) == 0) - { $self->{' DAT'} .= TTF_Pack("s", $y); } - elsif (($flag & 36) == 36) - { $self->{' DAT'} .= pack("C", $y); } - elsif (($flag & 36) == 4) - { $self->{' DAT'} .= pack("C", -$y); } - } - } - - elsif ($num < 0) - { - for ($i = 0; $i <= $#{$self->{'comps'}}; $i++) - { - $comp = $self->{'comps'}[$i]; - $flag = $comp->{'flag'} & 7158; # bits 2,10,11,12 - $flag |= 1 unless ($comp->{'args'}[0] > -129 && $comp->{'args'}[0] < 128 - && $comp->{'args'}[1] > -129 && $comp->{'args'}[1] < 128); - if (defined $comp->{'scale'}) - { - if ($comp->{'scale'}[1] == 0 && $comp->{'scale'}[2] == 0) - { - if ($comp->{'scale'}[0] == $comp->{'scale'}[3]) - { $flag |= 8 unless ($comp->{'scale'}[0] == 0 - || $comp->{'scale'}[0] == 1); } - else - { $flag |= 64; } - } else - { $flag |= 128; } - } - - $flag |= 512 if (defined $self->{'metric'} && $self->{'metric'} == $i); - if ($i == $#{$self->{'comps'}}) - { $flag |= 256 if (defined $self->{'instLen'} && $self->{'instLen'} > 0); } - else - { $flag |= 32; } - - $self->{' DAT'} .= pack("n", $flag); - $self->{' DAT'} .= pack("n", $comp->{'glyph'}); - $comp->{'flag'} = $flag; - - if ($flag & 1) - { $self->{' DAT'} .= TTF_Pack("s2", @{$comp->{'args'}}); } - else - { $self->{' DAT'} .= pack("CC", @{$comp->{'args'}}); } - - if ($flag & 8) - { $self->{' DAT'} .= TTF_Pack("F", $comp->{'scale'}[0]); } - elsif ($flag & 64) - { $self->{' DAT'} .= TTF_Pack("F2", $comp->{'scale'}[0], $comp->{'scale'}[3]); } - elsif ($flag & 128) - { $self->{' DAT'} .= TTF_Pack("F4", @{$comp->{'scale'}}); } - } - if (defined $self->{'instLen'} && $self->{'instLen'} > 0) - { - $len = $self->{'instLen'}; - $self->{' DAT'} .= pack("n", $len); - $self->{' DAT'} .= pack("a" . $len, substr($self->{'hints'}, 0, $len)); - } - } - my ($olen) = length($self->{' DAT'}); - $self->{' DAT'} .= ("\000") x (4 - ($olen & 3)) if ($olen & 3); - $self->{' OUTLEN'} = length($self->{' DAT'}); - $self->{' read'} = 2; # changed from 1 to 2 so we don't read_dat() again -# we leave numPoints and instLen since maxp stats use this - $self; -} - - -=head2 $g->update_bbox - -Updates the bounding box for this glyph according to the points in the glyph - -=cut - -sub update_bbox -{ - my ($self) = @_; - my ($num, $maxx, $minx, $maxy, $miny, $i, $comp, $x, $y, $compg); - - return $self unless $self->{' read'} > 1; # only if read_dat done - $miny = $minx = 65537; $maxx = $maxy = -65537; - $num = $self->{'numberOfContours'}; - if ($num > 0) - { - for ($i = 0; $i < $self->{'numPoints'}; $i++) - { - ($x, $y) = ($self->{'x'}[$i], $self->{'y'}[$i]); - - $maxx = $x if ($x > $maxx); - $minx = $x if ($x < $minx); - $maxy = $y if ($y > $maxy); - $miny = $y if ($y < $miny); - } - } - - elsif ($num < 0) - { - foreach $comp (@{$self->{'comps'}}) - { - my ($gnx, $gny, $gxx, $gxy); - my ($sxx, $sxy, $syx, $syy); - - my $otherg = $self->{' PARENT'}{'loca'}{'glyphs'}[$comp->{'glyph'}]; - # work around bad fonts: see documentation for 'comps' above - next unless (defined $otherg); - $compg = $otherg->read->update_bbox; - ($gnx, $gny, $gxx, $gxy) = @{$compg}{'xMin', 'yMin', 'xMax', 'yMax'}; - if (defined $comp->{'scale'}) - { - ($sxx, $sxy, $syx, $syy) = @{$comp->{'scale'}}; - ($gnx, $gny, $gxx, $gxy) = ($gnx*$sxx+$gny*$syx + $comp->{'args'}[0], - $gnx*$sxy+$gny*$syy + $comp->{'args'}[1], - $gxx*$sxx+$gxy*$syx + $comp->{'args'}[0], - $gxx*$sxy+$gxy*$syy + $comp->{'args'}[1]); - } elsif ($comp->{'args'}[0] || $comp->{'args'}[1]) - { - $gnx += $comp->{'args'}[0]; - $gny += $comp->{'args'}[1]; - $gxx += $comp->{'args'}[0]; - $gxy += $comp->{'args'}[1]; - } - ($gnx, $gxx) = ($gxx, $gnx) if $gnx > $gxx; - ($gny, $gxy) = ($gxy, $gny) if $gny > $gxy; - $maxx = $gxx if $gxx > $maxx; - $minx = $gnx if $gnx < $minx; - $maxy = $gxy if $gxy > $maxy; - $miny = $gny if $gny < $miny; - } - } - $self->{'xMax'} = $maxx; - $self->{'xMin'} = $minx; - $self->{'yMax'} = $maxy; - $self->{'yMin'} = $miny; - $self; -} - - -=head2 $g->maxInfo - -Returns lots of information about a glyph so that the C table can update -itself. Returns array containing contributions of this glyph to maxPoints, maxContours, -maxCompositePoints, maxCompositeContours, maxSizeOfInstructions, maxComponentElements, -and maxComponentDepth. - -=cut - -sub maxInfo -{ - my ($self) = @_; - my (@res, $i, @n); - - $self->read_dat; # make sure we've read some data - $res[4] = length($self->{'hints'}) if defined $self->{'hints'}; - $res[6] = 1; - if ($self->{'numberOfContours'} > 0) - { - $res[0] = $self->{'numPoints'}; - $res[1] = $self->{'numberOfContours'}; - } elsif ($self->{'numberOfContours'} < 0) - { - for ($i = 0; $i <= $#{$self->{'comps'}}; $i++) - { - my $otherg = - $self->{' PARENT'}{'loca'}{'glyphs'} - [$self->{'comps'}[$i]{'glyph'}]; - - # work around bad fonts: see documentation for 'comps' above - next unless (defined $otherg ); - - @n = $otherg->maxInfo; - - $res[2] += $n[2] == 0 ? $n[0] : $n[2]; - $res[3] += $n[3] == 0 ? $n[1] : $n[3]; - $res[5]++; - $res[6] = $n[6] + 1 if ($n[6] >= $res[6]); - } - } - @res; -} - -=head2 $g->empty - -Empties the glyph of all information to the level of not having been read. -Useful for saving memory in apps with many glyphs being read - -=cut - -sub empty -{ - my ($self) = @_; - my (%keep) = map {(" $_" => 1)} ('LOC', 'OUTLOC', 'PARENT', 'INFILE', 'BASE', - 'OUTLEN', 'LEN'); - map {delete $self->{$_} unless $keep{$_}} keys %$self; - - $self; -} - - -=head2 $g->get_points - -This method creates point information for a compound glyph. The information is -stored in the same place as if the glyph was not a compound, but since -numberOfContours is negative, the glyph is still marked as being a compound - -=cut - -sub get_points -{ - my ($self) = @_; - my ($comp, $compg, $nump, $e, $i); - - $self->read_dat; - return undef unless ($self->{'numberOfContours'} < 0); - - foreach $comp (@{$self->{'comps'}}) - { - $compg = $self->{' PARENT'}{'loca'}{'glyphs'}[$comp->{'glyph'}]; - # work around bad fonts: see documentation for 'comps' above - next unless (defined $compg ); - $compg->get_points; - - for ($i = 0; $i < $compg->{'numPoints'}; $i++) - { - my ($x, $y) = ($compg->{'x'}[$i], $compg->{'y'}[$i]); - if (defined $comp->{'scale'}) - { - ($x, $y) = ($x * $comp->{'scale'}[0] + $y * $comp->{'scale'}[2], - $x * $comp->{'scale'}[1] + $y * $comp->{'scale'}[3]); - } - if (defined $comp->{'args'}) - { ($x, $y) = ($x + $comp->{'args'}[0], $y + $comp->{'args'}[1]); } - push (@{$self->{'x'}}, $x); - push (@{$self->{'y'}}, $y); - push (@{$self->{'flags'}}, $compg->{'flags'}[$i]); - } - foreach $e (@{$compg->{'endPoints'}}) - { push (@{$self->{'endPoints'}}, $e + $nump); } - $nump += $compg->{'numPoints'}; - } - $self->{'numPoints'} = $nump; - $self; -} - - -=head2 $g->get_refs - -Returns an array of all the glyph ids that are used to make up this glyph. That -is all the compounds and their references and so on. If this glyph is not a -compound, then returns an empty array. - -Please note the warning about bad fonts that reference nonexistant glyphs -under INSTANCE VARIABLES above. This function will not attempt to -filter out nonexistant glyph numbers. - -=cut - -sub get_refs -{ - my ($self) = @_; - my (@res, $g); - - $self->read_dat; - return unless ($self->{'numberOfContours'} < 0); - foreach $g (@{$self->{'comps'}}) - { - push (@res, $g->{'glyph'}); - my $otherg = $self->{' PARENT'}{'loca'}{'glyphs'}[$g->{'glyph'}]; - # work around bad fonts: see documentation for 'comps' above - next unless (defined $otherg); - my @list = $otherg->get_refs; - push(@res, @list); - } - return @res; -} - -1; - -=head1 BUGS - -=over 4 - -=item * - -The instance variables used here are somewhat clunky and inconsistent with -the other tables. - -=item * - -C doesn't re-calculate the bounding box or C. - -=back - -=head1 AUTHOR - -Martin Hosken Martin_Hosken@sil.org. See L for copyright and -licensing. - -=cut