1 package Font::TTF::Hmtx;
5 Font::TTF::Hmtx - Horizontal Metrics
9 Contains the advance width and left side bearing for each glyph. Given the
10 compressability of the data onto disk, this table uses information from
11 other tables, and thus must do part of its output during the output of
14 =head1 INSTANCE VARIABLES
16 The horizontal metrics are kept in two arrays by glyph id. The variable names
17 do not start with a space
23 An array containing the advance width for each glyph
27 An array containing the left side bearing for each glyph
37 require Font::TTF::Table;
39 @ISA = qw(Font::TTF::Table);
44 Reads the horizontal metrics from the TTF file into memory
53 $numh = $self->{' PARENT'}{'hhea'}->read->{'numberOfHMetrics'};
54 $numg = $self->{' PARENT'}{'maxp'}{'numGlyphs'};
55 $self->_read($numg, $numh, "advance", "lsb");
60 my ($self, $numg, $numh, $tAdv, $tLsb) = @_;
61 my ($fh) = $self->{' INFILE'};
64 $self->SUPER::read or return $self;
66 for ($i = 0; $i < $numh; $i++)
69 ($self->{$tAdv}[$i], $self->{$tLsb}[$i]) = unpack("nn", $dat);
70 $self->{$tLsb}[$i] -= 65536 if ($self->{$tLsb}[$i] >= 32768);
77 $self->{$tAdv}[$i] = $self->{$tAdv}[$numh - 1];
78 $self->{$tLsb}[$i] = unpack("n", $dat);
79 $self->{$tLsb}[$i] -= 65536 if ($self->{$tLsb}[$i] >= 32768);
86 Calculates again the number of long metrics required to store the information
87 here. Returns undef if the table has not been read.
94 my ($numg) = $self->{' PARENT'}{'maxp'}{'numGlyphs'};
97 return undef unless $self->{' read'};
99 for ($i = $numg - 2; $i >= 0; $i--)
100 { last if ($self->{'advance'}[$i] != $self->{'advance'}[$i + 1]); }
108 Writes the metrics to a TTF file. Assumes that the C<hhea> has updated the
109 numHMetrics from here
115 my ($self, $fh) = @_;
116 my ($numg) = $self->{' PARENT'}{'maxp'}{'numGlyphs'};
117 my ($numh) = $self->{' PARENT'}{'hhea'}->read->{'numberOfHMetrics'};
118 $self->_out($fh, $numg, $numh, "advance", "lsb");
123 my ($self, $fh, $numg, $numh, $tAdv, $tLsb) = @_;
126 return $self->SUPER::out($fh) unless ($self->{' read'});
128 for ($i = 0; $i < $numg; $i++)
130 $lsb = $self->{$tLsb}[$i];
131 $lsb += 65536 if $lsb < 0;
133 { $fh->print(pack("n", $lsb)); }
135 { $fh->print(pack("n2", $self->{$tAdv}[$i], $lsb)); }
143 Updates the lsb values from the xMin from the each glyph
150 my ($numg) = $self->{' PARENT'}{'maxp'}{'numGlyphs'};
153 return undef unless ($self->SUPER::update);
154 # lsb & xMin must always be the same, regardless of any flags!
155 # return $self unless ($self->{' PARENT'}{'head'}{'flags'} & 2); # lsb & xMin the same
157 $self->{' PARENT'}{'loca'}->update;
158 for ($i = 0; $i < $numg; $i++)
160 my ($g) = $self->{' PARENT'}{'loca'}{'glyphs'}[$i];
162 { $self->{'lsb'}[$i] = $g->read->update_bbox->{'xMin'}; }
164 { $self->{'lsb'}[$i] = 0; }
166 $self->{' PARENT'}{'head'}{'flags'} |= 2;
171 =head2 $t->out_xml($context, $depth)
173 Outputs the table in XML
179 my ($self, $context, $depth) = @_;
180 my ($fh) = $context->{'fh'};
181 my ($numg) = $self->{' PARENT'}{'maxp'}{'numGlyphs'};
182 my ($addr) = ($self =~ m/\((.+)\)$/o);
185 if ($context->{'addresses'}{$addr})
187 $fh->printf("%s<%s id_ref='%s'/>\n", $depth, $context->{'name'}, $addr);
191 { $fh->printf("%s<%s id='%s'>\n", $depth, $context->{'name'}, $addr); }
195 for ($i = 0; $i < $numg; $i++)
196 { $fh->print("$depth$context->{'indent'}<width adv='$self->{'advance'}[$i]' lsb='$self->{'lsb'}[$i]'/>\n"); }
198 $fh->print("$depth</$context->{'name'}>\n");
210 Martin Hosken Martin_Hosken@sil.org. See L<Font::TTF::Font> for copyright and