| Font-TTF documentation | Contained in the Font-TTF distribution. |
Font::TTF::Feat - Font Features
An array of hashes of the following form
feature id number
name index in name table
exclusive flag
hash of setting number against name string index
Reads the features from the TTF file into memory
Writes the features to a TTF file
Prints a human-readable representation of the table
None known
Jonathan Kew Jonathan_Kew@sil.org. See Font::TTF::Font for copyright and licensing.
| Font-TTF documentation | Contained in the Font-TTF distribution. |
package Font::TTF::Feat;
use strict; use vars qw(@ISA); use Font::TTF::Utils; require Font::TTF::Table; @ISA = qw(Font::TTF::Table);
sub read { my ($self) = @_; my ($featureCount, $features); $self->SUPER::read_dat or return $self; ($self->{'version'}, $featureCount) = TTF_Unpack("vS", $self->{' dat'}); $features = []; foreach (1 .. $featureCount) { my ($feature, $nSettings, $settingTable, $featureFlags, $nameIndex) = TTF_Unpack("SSLSS", substr($self->{' dat'}, $_ * 12, 12)); push @$features, { 'feature' => $feature, 'name' => $nameIndex, 'exclusive' => (($featureFlags & 0x8000) != 0), 'settings' => { TTF_Unpack("S*", substr($self->{' dat'}, $settingTable, $nSettings * 4)) } }; } $self->{'features'} = $features; delete $self->{' dat'}; # no longer needed, and may become obsolete $self; }
sub out { my ($self, $fh) = @_; my ($features, $numFeatures, $settings, $featuresData, $settingsData); return $self->SUPER::out($fh) unless $self->{' read'}; $features = $self->{'features'}; $numFeatures = @$features; foreach (@$features) { $settings = $_->{'settings'}; $featuresData .= TTF_Pack("SSLSS", $_->{'feature'}, scalar keys %$settings, 12 + 12 * $numFeatures + length $settingsData, ($_->{'exclusive'} ? 0x8000 : 0x0000), $_->{'name'}); foreach (sort {$a <=> $b} keys %$settings) { $settingsData .= TTF_Pack("SS", $_, $settings->{$_}); } } $fh->print(TTF_Pack("vSSL", $self->{'version'}, $numFeatures, 0, 0)); $fh->print($featuresData); $fh->print($settingsData); $self; }
sub print { my ($self, $fh) = @_; my ($names, $features, $settings); $self->read; $names = $self->{' PARENT'}->{'name'}; $names->read; $fh = 'STDOUT' unless defined $fh; $features = $self->{'features'}; foreach (@$features) { $fh->printf("Feature %d, %s, name %d # '%s'\n", $_->{'feature'}, ($_->{'exclusive'} ? "exclusive" : "additive"), $_->{'name'}, $names->{'strings'}[$_->{'name'}][1][0]{0}); $settings = $_->{'settings'}; foreach (sort { $a <=> $b } keys %$settings) { $fh->printf("\tSetting %d, name %d # '%s'\n", $_, $settings->{$_}, $names->{'strings'}[$settings->{$_}][1][0]{0}); } } $self; } sub settingName { my ($self, $feature, $setting) = @_; $self->read; my $names = $self->{' PARENT'}->{'name'}; $names->read; my $features = $self->{'features'}; my ($featureEntry) = grep { $_->{'feature'} == $feature } @$features; my $featureName = $names->{'strings'}[$featureEntry->{'name'}][1][0]{0}; my $settingName = $featureEntry->{'exclusive'} ? $names->{'strings'}[$featureEntry->{'settings'}->{$setting}][1][0]{0} : $names->{'strings'}[$featureEntry->{'settings'}->{$setting & ~1}][1][0]{0} . (($setting & 1) == 0 ? " On" : " Off"); ($featureName, $settingName); } 1;