X-Git-Url: https://git.mdrn.pl/librarian.git/blobdiff_plain/e9aeedc51047d8d5e9e45c5253c776f8994da965..3a0c83394d5783715fab2be29fa1a9cfc3574e28:/src/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/OS_2.pm diff --git a/src/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/OS_2.pm b/src/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/OS_2.pm deleted file mode 100644 index 0092732..0000000 --- a/src/librarian/font-optimizer/ext/Font-TTF/lib/Font/TTF/OS_2.pm +++ /dev/null @@ -1,354 +0,0 @@ -package Font::TTF::OS_2; - -=head1 NAME - -Font::TTF::OS_2 - the OS/2 table in a TTF font - -=head1 DESCRIPTION - -The OS/2 table has two versions and forms, one an extension of the other. This -module supports both forms and the switching between them. - -=head1 INSTANCE VARIABLES - -No other variables than those in table and those in the standard: - - Version - xAvgCharWidth - usWeightClass - usWidthClass - fsType - ySubscriptXSize - ySubScriptYSize - ySubscriptXOffset - ySubscriptYOffset - ySuperscriptXSize - ySuperscriptYSize - ySuperscriptXOffset - ySuperscriptYOffset - yStrikeoutSize - yStrikeoutPosition - sFamilyClass - bFamilyType - bSerifStyle - bWeight - bProportion - bContrast - bStrokeVariation - bArmStyle - bLetterform - bMidline - bXheight - ulUnicodeRange1 - ulUnicodeRange2 - ulUnicodeRange3 - ulUnicodeRange4 - achVendID - fsSelection - usFirstCharIndex - usLastCharIndex - sTypoAscender - sTypoDescender - sTypoLineGap - usWinAscent - usWinDescent - ulCodePageRange1 - ulCodePageRange2 - xHeight - CapHeight - defaultChar - breakChar - maxLookups - -Notice that versions 0, 1, 2 & 3 of the table are supported. Notice also that the -Panose variable has been broken down into its elements. - -=head1 METHODS - -=cut - -use strict; -use vars qw(@ISA @fields @lens @field_info @weights); -use Font::TTF::Table; - -@ISA = qw(Font::TTF::Table); -@field_info = ( - 'xAvgCharWidth' => 's', - 'usWeightClass' => 'S', - 'usWidthClass' => 'S', - 'fsType' => 's', - 'ySubscriptXSize' => 's', - 'ySubScriptYSize' => 's', - 'ySubscriptXOffset' => 's', - 'ySubscriptYOffset' => 's', - 'ySuperscriptXSize' => 's', - 'ySuperscriptYSize' => 's', - 'ySuperscriptXOffset' => 's', - 'ySuperscriptYOffset' => 's', - 'yStrikeoutSize' => 's', - 'yStrikeoutPosition' => 's', - 'sFamilyClass' => 's', - 'bFamilyType' => 'C', - 'bSerifStyle' => 'C', - 'bWeight' => 'C', - 'bProportion' => 'C', - 'bContrast' => 'C', - 'bStrokeVariation' => 'C', - 'bArmStyle' => 'C', - 'bLetterform' => 'C', - 'bMidline' => 'C', - 'bXheight' => 'C', - 'ulUnicodeRange1' => 'L', - 'ulUnicodeRange2' => 'L', - 'ulUnicodeRange3' => 'L', - 'ulUnicodeRange4' => 'L', - 'achVendID' => 'L', - 'fsSelection' => 'S', - 'usFirstCharIndex' => 'S', - 'usLastCharIndex' => 'S', - 'sTypoAscender' => 'S', - 'sTypoDescender' => 's', - 'sTypoLineGap' => 'S', - 'usWinAscent' => 'S', - 'usWinDescent' => 'S', - '' => '', - 'ulCodePageRange1' => 'L', - 'ulCodePageRange2' => 'L', - '' => '', - 'xHeight' => 's', - 'CapHeight' => 's', - 'defaultChar' => 'S', - 'breakChar' => 'S', - 'maxLookups' => 's', - '' => '', # i.e. v3 is basically same as v2 - ); - -@weights = qw(64 14 27 35 100 20 14 42 63 3 6 35 20 56 56 17 4 49 56 71 31 10 18 3 18 2 166); - -use Font::TTF::Utils; - -sub init -{ - my ($k, $v, $c, $n, $i, $t, $j); - - $n = 0; - @lens = (76, 84, 94, 94); - for ($j = 0; $j < $#field_info; $j += 2) - { - if ($field_info[$j] eq '') - { - $n++; - next; - } - ($k, $v, $c) = TTF_Init_Fields($field_info[$j], $c, $field_info[$j+1]); - next unless defined $k && $k ne ""; - for ($i = $n; $i < 4; $i++) - { $fields[$i]{$k} = $v; } - } -} - - -=head2 $t->read - -Reads in the various values from disk (see details of OS/2 table) - -=cut - -sub read -{ - my ($self) = @_; - my ($dat, $ver); - - $self->SUPER::read or return $self; - - init unless defined $fields[2]{'xAvgCharWidth'}; - $self->{' INFILE'}->read($dat, 2); - $ver = unpack("n", $dat); - $self->{'Version'} = $ver; - if ($ver < 4) - { - $self->{' INFILE'}->read($dat, $lens[$ver]); - TTF_Read_Fields($self, $dat, $fields[$ver]); - } - $self; -} - - -=head2 $t->out($fh) - -Writes the table to a file either from memory or by copying. - -=cut - -sub out -{ - my ($self, $fh) = @_; - my ($ver); - - return $self->SUPER::out($fh) unless $self->{' read'}; - - $ver = $self->{'Version'}; - $fh->print(pack("n", $ver)); - $fh->print(TTF_Out_Fields($self, $fields[$ver], $lens[$ver])); - $self; -} - - -=head2 $t->XML_element($context, $depth, $key, $value) - -Tidies up the hex values to output them in hex - -=cut - -sub XML_element -{ - my ($self) = shift; - my ($context, $depth, $key, $value) = @_; - my ($fh) = $context->{'fh'}; - - if ($key =~ m/^ul(?:Unicode|CodePage)Range\d$/o) - { $fh->printf("%s<%s>%08X\n", $depth, $key, $value, $key); } - elsif ($key eq 'achVendID') - { $fh->printf("%s<%s name='%s'/>\n", $depth, $key, pack('N', $value)); } - else - { return $self->SUPER::XML_element(@_); } - $self; -} - - -=head2 $t->XML_end($context, $tag, %attrs) - -Now handle them on the way back in - -=cut - -sub XML_end -{ - my ($self) = shift; - my ($context, $tag, %attrs) = @_; - - if ($tag =~ m/^ul(?:Unicode|CodePage)Range\d$/o) - { return hex($context->{'text'}); } - elsif ($tag eq 'achVendID') - { return unpack('N', $attrs{'name'}); } - else - { return $self->SUPER::XML_end(@_); } -} - -=head2 $t->update - -Updates the OS/2 table by getting information from other sources: - -Updates the C and C values based on the MS table in the -cmap. - -Updates the sTypoAscender, sTypoDescender & sTypoLineGap to be the same values -as Ascender, Descender and Linegap from the hhea table (assuming it is dirty) -and also sets usWinAscent to be the sum of Ascender+Linegap and usWinDescent to -be the negative of Descender. - -=cut - -sub update -{ - my ($self) = @_; - my ($map, @keys, $table, $i, $avg, $hmtx); - - return undef unless ($self->SUPER::update); - - $self->{' PARENT'}{'cmap'}->update; - $map = $self->{' PARENT'}{'cmap'}->find_ms || return undef; - $hmtx = $self->{' PARENT'}{'hmtx'}->read; - - @keys = sort {$a <=> $b} grep {$_ < 0x10000} keys %{$map->{'val'}}; - - $self->{'usFirstCharIndex'} = $keys[0]; - $self->{'usLastCharIndex'} = $keys[-1]; - - $table = $self->{' PARENT'}{'hhea'}->read; - - # try any way we can to get some real numbers passed around! - if (($self->{'fsSelection'} & 128) != 0) - { - # assume the user knows what they are doing and has sensible values already - } - elsif ($table->{'Ascender'} != 0 || $table->{'Descender'} != 0) - { - $self->{'sTypoAscender'} = $table->{'Ascender'}; - $self->{'sTypoDescender'} = $table->{'Descender'}; - $self->{'sTypoLineGap'} = $table->{'LineGap'}; - $self->{'usWinAscent'} = $self->{'sTypoAscender'} + $self->{'sTypoLineGap'}; - $self->{'usWinDescent'} = -$self->{'sTypoDescender'}; - } - elsif ($self->{'sTypoAscender'} != 0 || $self->{'sTypoDescender'} != 0) - { - $table->{'Ascender'} = $self->{'sTypoAscender'}; - $table->{'Descender'} = $self->{'sTypoDescender'}; - $table->{'LineGap'} = $self->{'sTypoLineGap'}; - $self->{'usWinAscent'} = $self->{'sTypoAscender'} + $self->{'sTypoLineGap'}; - $self->{'usWinDescent'} = -$self->{'sTypoDescender'}; - } - elsif ($self->{'usWinAscent'} != 0 || $self->{'usWinDescent'} != 0) - { - $self->{'sTypoAscender'} = $table->{'Ascender'} = $self->{'usWinAscent'}; - $self->{'sTypoDescender'} = $table->{'Descender'} = -$self->{'usWinDescent'}; - $self->{'sTypoLineGap'} = $table->{'LineGap'} = 0; - } - - if ($self->{'Version'} < 3) - { - for ($i = 0; $i < 26; $i++) - { $avg += $hmtx->{'advance'}[$map->{'val'}{$i + 0x0061}] * $weights[$i]; } - $avg += $hmtx->{'advance'}[$map->{'val'}{0x0020}] * $weights[-1]; - $self->{'xAvgCharWidth'} = $avg / 1000; - } - elsif ($self->{'Version'} > 2) - { - $i = 0; $avg = 0; - foreach (@{$hmtx->{'advance'}}) - { - next unless ($_); - $i++; - $avg += $_; - } - $avg /= $i if ($i); - $self->{'xAvgCharWidth'} = $avg; - } - - foreach $i (keys %{$map->{'val'}}) - { - if ($i >= 0x10000) - { - $self->{'ulUnicodeRange2'} |= 0x2000000; - last; - } - } - - $self->{'Version'} = 1 if (defined $self->{'ulCodePageRange1'} && $self->{'Version'} < 1); - $self->{'Version'} = 2 if (defined $self->{'maxLookups'} && $self->{'Version'} < 2); - - if ((exists $self->{' PARENT'}{'GPOS'} && $self->{' PARENT'}{'GPOS'}{' read'}) || - (exists $self->{' PARENT'}{'GSUB'} && $self->{' PARENT'}{'GSUB'}{' read'})) - { - # one or both of GPOS & GSUB exist and have been read or modified; so update usMaxContexts - my ($lp, $ls); - $lp = $self->{' PARENT'}{'GPOS'}->maxContext if exists $self->{' PARENT'}{'GPOS'}; - $ls = $self->{' PARENT'}{'GSUB'}->maxContext if exists $self->{' PARENT'}{'GSUB'}; - $self->{'maxLookups'} = $lp > $ls ? $lp : $ls; - } - - $self; -} - -1; - -=head1 BUGS - -None known - -=head1 AUTHOR - -Martin Hosken Martin_Hosken@sil.org. See L for copyright and -licensing. - -=cut