Codebase list libfont-ttf-perl / ac180d1
[svn-upgrade] Integrating new upstream version, libfont-ttf-perl (0.42) Gregor Herrmann 16 years ago
17 changed file(s) with 975 addition(s) and 109 deletion(s). Raw diff Collapse all Expand all
5353 lib/Font/TTF/PSNames.pm
5454 lib/Font/TTF/Segarr.pm
5555 lib/Font/TTF/Table.pm
56 lib/Font/TTF/Tags.pm
5657 lib/Font/TTF/Ttc.pm
5758 lib/Font/TTF/Ttopen.pm
5859 lib/Font/TTF/Useall.pm
6768 MANIFEST.SKIP
6869 META.yml
6970 README.TXT
71 TODO
33 \.bak
44 CVS/
55 \.tar
6 \.tgz
7 \.old
68 misc/
79 Build/
810 exes/
1618 pm_to_blib
1719 \~$
1820 dev/
21 build/
22 dists/
23 ^libfont-
24 description-pak
25 ^doc
00 # http://module-build.sourceforge.net/META-spec.html
11 #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX#
22 name: Font-TTF
3 version: 0.41
3 version: 0.42
44 version_from: lib/Font/TTF.pm
55 installdirs: site
66 requires:
00 use ExtUtils::MakeMaker;
1 use Getopt::Std;
2
3 getopts('d:rv:');
4
5 %pbuilderopts = (
6 'gutsy' => '--bindmounts /media/hosk_1'
7 );
8
9 $opt_v ||= 1;
10
11 if ($^O eq 'linux' && !defined $opt_d)
12 {
13 $opt_d = `lsb_release -c`;
14 $opt_d =~ s/^.*?(\w+)\s*$/$1/o;
15 }
116
217 @theselibs = (grep {-f } glob("lib/Font/TTF/*"), "lib/Font/TTF.pm");
318
823 @extras = ('dist' => { 'TO_UNIX' => 'perl -Mtounix -e "tounix(\"$(DISTVNAME)\")"' });
924 }
1025
11 WriteMakefile (
12 NAME => "Font::TTF",
26 %makeinfo = (
27 NAME => 'Font::TTF',
1328 VERSION_FROM => 'lib/Font/TTF.pm',
1429 # VERSION => "0.38",
1530 # HTMLLIBPODS => {map {my $t = $_; $t=~s/\..*?$/.html/o; $t='blib/Html/'.$t; $_ => $t;} @theselibs},
1833 ABSTRACT => "TTF font support for Perl",
1934 @extras
2035 );
36
37 WriteMakefile(%makeinfo);
2138
2239 if ($^O eq 'MSWin32') {
2340 # incantation to solve the problem of everyone's $Config{make} being 'nmake'
4057 }
4158
4259 }
60 elsif ($^O eq 'linux')
61 {
4362
63 sub MY::postamble
64 {
65 my ($self) = @_;
66 my ($res);
67 my ($package) = lc($self->{'NAME'});
68 my ($pversion) = $self->{'VERSION'};
69 my ($svn) = `svnversion`;
70 my ($sign) = '--auto-debsign' if ($opt_r);
71 my ($fpackage);
72
73 $svn =~ s/[0-9]*://og;
74 $svn =~ s/\s+$//o;
75 $package =~ s/::/-/;
76 $package = "lib${package}-perl";
77 $pversion .= "+$svn" unless ($opt_r);
78 $fpackage = "$package-$pversion";
79
80 $res = <<"EOT";
81 deb-base: dist
82 rm -fr $self->{'DISTVNAME'}
83 rm -fr $fpackage
84 tar xvzf $self->{'DISTVNAME'}.tar.gz
85 mv $self->{'DISTVNAME'} $fpackage
86 tar cfz "${package}_$pversion.orig.tar.gz" $fpackage
87 cp -a debian $fpackage
88 cd $fpackage && find . -name .svn | xargs rm -rf
89
90 # make deb builds an interim deb from svn source for release
91 deb: deb-base
92 EOT
93
94 foreach $d (split(' ', $opt_d))
95 {
96 $res .= <<"EOT";
97 mkdir -p dists/$d
98 dch -D $d -v $pversion-$opt_v -m -b -c $fpackage/debian/changelog "Auto build from perl for $d"
99 cd $fpackage && pdebuild --buildresult ../dists/$d -- --basetgz /var/cache/pbuilder/base-$d.tgz $pbuilderopts{$d}
100 EOT
101 }
102
103 return $res;
104 }
105
106 }
107
0
1 * update() is a mess. What is needed is a mark sweep clean algorithm where the
2 dirty is used only for tables that have changed. Thus if a table is updated
3 it could well become dirty! Also need to be able to pass a force parameter
4 to force a table to update and all the tables in its dependency tree.
4848 =cut
4949
5050 use strict;
51 use Font::TTF::Utils;
5152
5253
5354 =head2 new
7576 sub read
7677 {
7778 my ($self, $fh) = @_;
78 my ($dat, $loc, $fmt, $x, $y, $p, $xoff, $yoff);
79 my ($dat, $loc, $fmt, $p, $xoff, $yoff);
7980
8081 $fh->read($dat, 6);
81 ($fmt, $x, $y) = unpack('n*', $dat);
82 $fmt = unpack('n', $dat);
8283 if ($fmt == 4)
83 { ($self->{'xid'}, $self->{'yid'}) = ($x, $y); }
84 { ($self->{'xid'}, $self->{'yid'}) = TTF_Unpack('S2', substr($dat,2)); }
8485 else
85 { ($self->{'x'}, $self->{'y'}) = ($x, $y); }
86 { ($self->{'x'}, $self->{'y'}) = TTF_Unpack('s2', substr($dat,2)); }
8687
8788 if ($fmt == 2)
8889 {
111112 =head2 out($fh, $style)
112113
113114 Outputs the Anchor to the given file handle at this point also addressing issues
114 of deltas. If $style is set, then no output is set to the file handle. The return
115 of deltas. If $style is set, then no output is sent to the file handle. The return
115116 value is the output string.
116117
117118 =cut
122123 my ($xoff, $yoff, $fmt, $out);
123124
124125 if (defined $self->{'xid'} || defined $self->{'yid'})
125 { $out = pack('n*', 4, $self->{'xid'}, $self->{'yid'}); }
126 { $out = TTF_Pack('SSS', 4, $self->{'xid'}, $self->{'yid'}); }
126127 elsif (defined $self->{'p'})
127 { $out = pack('n*', 2, @{$self}{'x', 'y', 'p'}); }
128 { $out = TTF_Pack('Ssss', 2, @{$self}{'x', 'y', 'p'}); }
128129 elsif (defined $self->{'xdev'} || defined $self->{'ydev'})
129130 {
130 $out = pack('n*', 3, @{$self}{'x', 'y'});
131 $out = TTF_Pack('Sss', 3, @{$self}{'x', 'y'});
131132 if (defined $self->{'xdev'})
132133 {
133134 $out .= pack('n2', 10, 0);
143144 $out .= $self->{'ydev'}->out($fh, 1);
144145 }
145146 } else
146 { $out = pack('n3', 1, @{$self}{'x', 'y'}); }
147 { $out = TTF_Pack('Sss', 1, @{$self}{'x', 'y'}); }
147148 $fh->print($out) unless $style;
148149 $out;
150 }
151
152
153 sub signature
154 {
155 my ($self) = @_;
156 return join (",", map {"${_}=$self->{$_}"} qw(x y p xdev ydev xid yid));
149157 }
150158
151159
133133 {
134134 $fmt = 2;
135135 last;
136 } elsif ($gids[$i] == $gids[$i-1] + 1)
136 } elsif ($gids[$i] == $gids[$i-1] + 1 && ($self->{'cover'} || $self->{'val'}{$gids[$i]} == $self->{'val'}{$gids[$i-1]}))
137137 { $eff++; }
138138 else
139 { $grp++; }
140 }
141 if ($self->{'cover'})
142 { $fmt = 2 if ($eff / $grp > 4); }
143 else
144 { $fmt = 2 if ($grp > 1); }
139 {
140 $grp++;
141 $eff += $gids[$i] - $gids[$i-1] if (!$self->{'cover'});
142 }
143 }
144 # if ($self->{'cover'})
145 { $fmt = 2 if ($eff / $grp > 3); }
146 # else
147 # { $fmt = 2 if ($grp > 1); }
145148
146149 if ($fmt == 1 && $self->{'cover'})
147150 {
155158 foreach $g (@gids)
156159 {
157160 if ($g > $last + 1)
158 { &$shipout(pack('n*', 0 x ($g - $last - 1))); }
161 { &$shipout(pack('n*', (0) x ($g - $last - 1))); }
159162 &$shipout(pack('n', $self->{'val'}{$g}));
160163 $last = $g;
161164 }
200203 }
201204
202205
203 =head2 $c->add($glyphid)
206 =head2 $c->add($glyphid[, $class])
204207
205208 Adds a glyph id to the coverage table incrementing the count so that each subsequent addition
206209 has the next sequential number. Returns the index number of the glyphid added
209212
210213 sub add
211214 {
212 my ($self, $gid) = @_;
215 my ($self, $gid, $class) = @_;
213216
214217 return $self->{'val'}{$gid} if (defined $self->{'val'}{$gid});
215 $self->{'val'}{$gid} = $self->{'count'};
216 return $self->{'count'}++;
217 }
218
218 if ($self->{'cover'})
219 {
220 $self->{'val'}{$gid} = $self->{'count'};
221 return $self->{'count'}++;
222 }
223 else
224 {
225 $self->{'val'}{$gid} = $class || '0';
226 $self->{'max'} = $class if ($class > $self->{'max'});
227 return $class;
228 }
229 }
230
231
232 =head2 $c->signtaure
233
234 Returns a vector of all the glyph ids covered by this coverage table or class
235
236 =cut
237
238 sub signature
239 {
240 my ($self) = @_;
241 my ($vec, $range, $size);
242
243 if (0)
244 {
245 if ($self->{'cover'})
246 { $range = 1; $size = 1; }
247 else
248 {
249 $range = $self->{'max'};
250 $size = 1;
251 while ($range > 1)
252 {
253 $size = $size << 1;
254 $range = $range >> 1;
255 }
256 $range = $self->{'max'} + 1;
257 }
258 foreach (keys %{$self->{'val'}})
259 { vec($vec, $_, $size) = $self->{'val'}{$_} > $range ? $range : $self->{'val'}{$_}; }
260 length($vec) . ":" . $vec;
261 }
262 $vec = join(";", map{"$_,$self->{'val'}{$_}"} keys %{$self->{'val'}});
263 }
264
265 =head2 @map=$c->sort
266
267 Sorts the coverage table so that indexes are in ascending order of glyphid.
268 Returns a map such that $map[$new_index]=$old_index.
269
270 =cut
271
272 sub sort
273 {
274 my ($self) = @_;
275 my (@res, $i);
276
277 foreach (sort {$a <=> $b} keys %{$self->{'val'}})
278 {
279 push(@res, $self->{'val'}{$_});
280 $self->{'val'}{$_} = $i++;
281 }
282 @res;
283 }
219284
220285 =head2 $c->out_xml($context)
221286
249249 my ($class) = @_;
250250 my ($t);
251251
252 foreach $t (keys %tables)
252 foreach $t (values %tables)
253253 {
254254 $t =~ s|::|/|oig;
255255 require "$t.pm";
256256 for ($i = 0; $i < $mcount; $i++)
257257 { push (@{$lookup->{'RULES'}}, [{'ACTION' =>
258258 [$self->read_value($count, $loc, $lookup, $fh)]}]); }
259 $self->{'ACTION_TYPE'} = 'v';
259 $lookup->{'ACTION_TYPE'} = 'v';
260260 } elsif ($type == 2 && $fmt == 1)
261261 {
262262 $lookup->{'VFMT'} = $count;
388388
389389 sub out_sub
390390 {
391 my ($self, $fh, $main_lookup, $index) = @_;
391 my ($self, $fh, $main_lookup, $index, $ctables, $base) = @_;
392392 my ($type) = $main_lookup->{'TYPE'};
393393 my ($lookup) = $main_lookup->{'SUB'}[$index];
394394 my ($fmt) = $lookup->{'FORMAT'};
395395 my ($out, $r, $s, $t, $i, $j, $vfmt, $vfmt2, $loc1);
396396 my ($num) = $#{$lookup->{'RULES'}} + 1;
397 my ($ctables) = {};
398397 my ($mtables) = {};
399398 my (@reftables);
400399
401400 if ($type == 1 && $fmt == 1)
402401 {
403 $out = pack('n2', $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2));
402 $out = pack('n2', $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2 + $base));
404403 $vfmt = $self->fmt_value($lookup->{'ADJUST'});
405 $out .= pack('n', $vfmt) . $self->out_value($lookup->{'ADJUST'}, $vfmt, $ctables, 6);
404 $out .= pack('n', $vfmt) . $self->out_value($lookup->{'ADJUST'}, $vfmt, $ctables, 6 + $base);
406405 } elsif ($type == 1 && $fmt == 2)
407406 {
408407 $vfmt = 0;
409408 foreach $r (@{$lookup->{'RULES'}})
410409 { $vfmt |= $self->fmt_value($r->[0]{'ACTION'}[0]); }
411 $out = pack('n4', $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2),
410 $out = pack('n4', $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2 + $base),
412411 $vfmt, $#{$lookup->{'RULES'}} + 1);
413412 foreach $r (@{$lookup->{'RULES'}})
414 { $out .= $self->out_value($r->[0]{'ACTION'}[0], $vfmt, $ctables, length($out)); }
413 { $out .= $self->out_value($r->[0]{'ACTION'}[0], $vfmt, $ctables, length($out) + $base); }
415414 } elsif ($type == 2 && $fmt < 3)
416415 {
417416 $vfmt = 0;
429428 # start PairPosFormat1 subtable
430429 $out = pack('n5',
431430 $fmt,
432 Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2),
431 Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2 + $base),
433432 $vfmt,
434433 $vfmt2,
435434 $#{$lookup->{'RULES'}} + 1); # PairSetCount
437436 $off += length($out);
438437 $off += 2 * ($#{$lookup->{'RULES'}} + 1); # there will be PairSetCount offsets here
439438 my $pairsets = '';
439 my (%cache);
440440 foreach $r (@{$lookup->{'RULES'}}) # foreach PairSet table
441441 {
442442 # write offset to this PairSet at end of PairPosFormat1 table
443 $out .= pack('n', $off);
444
445 # generate PairSet itself (using $off as eventual offset within PairPos subtable)
446 my $pairset = pack('n', $#{$r} + 1); # PairValueCount
447 foreach $t (@$r) # foreach PairValueRecord
443 if (defined $cache{"$r"})
444 { $out .= pack('n', $cache{"$r"}); }
445 else
448446 {
449 $pairset .= pack('n', $t->{'MATCH'}[0]); # SecondGlyph - MATCH has only one entry
450 $pairset .=
451 $self->out_value($t->{'ACTION'}[0], $vfmt, $ctables, $off + length($pairset));
452 $pairset .=
453 $self->out_value($t->{'ACTION'}[1], $vfmt2, $ctables, $off + length($pairset));
447 $out .= pack('n', $off);
448 $cache{"$r"} = $off;
449
450 # generate PairSet itself (using $off as eventual offset within PairPos subtable)
451 my $pairset = pack('n', $#{$r} + 1); # PairValueCount
452 foreach $t (@$r) # foreach PairValueRecord
453 {
454 $pairset .= pack('n', $t->{'MATCH'}[0]); # SecondGlyph - MATCH has only one entry
455 $pairset .=
456 $self->out_value($t->{'ACTION'}[0], $vfmt, $ctables, $off + length($pairset) + $base);
457 $pairset .=
458 $self->out_value($t->{'ACTION'}[1], $vfmt2, $ctables, $off + length($pairset) + $base);
459 }
460 $off += length($pairset);
461 $pairsets .= $pairset;
454462 }
455 $off += length($pairset);
456 $pairsets .= $pairset;
457463 }
458464 $out .= $pairsets;
459465 die "internal error: PairPos size not as calculated" if (length($out) != $off);
460466 } else
461467 {
462 $out = pack('n8', $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2),
468 $out = pack('n8', $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2 + $base),
463469 $vfmt, $vfmt2,
464 Font::TTF::Ttopen::ref_cache($lookup->{'CLASS'}, $ctables, 1),
465 Font::TTF::Ttopen::ref_cache($lookup->{'MATCH'}[0], $ctables, 1),
466 $#{$lookup->{'RULES'}} + 1, $#{$lookup->{'RULES'}[0]} + 1);
467
468 foreach $r (@{$lookup->{'RULES'}})
469 {
470 foreach $t (@$r)
470 Font::TTF::Ttopen::ref_cache($lookup->{'CLASS'}, $ctables, 8 + $base),
471 Font::TTF::Ttopen::ref_cache($lookup->{'MATCH'}[0], $ctables, 10 + $base),
472 $lookup->{'CLASS'}{'max'} + 1, $lookup->{'MATCH'}[0]{'max'} + 1);
473
474 for ($i = 0; $i <= $lookup->{'CLASS'}{'max'}; $i++)
475 {
476 for ($j = 0; $j <= $lookup->{'MATCH'}[0]{'max'}; $j++)
471477 {
472 $out .= $self->out_value($t->{'ACTION'}[0], $vfmt, $ctables, length($out));
473 $out .= $self->out_value($t->{'ACTION'}[1], $vfmt2, $ctables, length($out));
478 $out .= $self->out_value($lookup->{'RULES'}[$i][$j]{'ACTION'}[0], $vfmt, $ctables, length($out) + $base);
479 $out .= $self->out_value($lookup->{'RULES'}[$i][$j]{'ACTION'}[1], $vfmt2, $ctables, length($out) + $base);
474480 }
475481 }
476482 }
477483 } elsif ($type == 3 && $fmt == 1)
478484 {
479 $out = pack('n3', $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2),
485 $out = pack('n3', $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2 + $base),
480486 $#{$lookup->{'RULES'}} + 1);
481487 foreach $r (@{$lookup->{'RULES'}})
482488 {
483 $out .= pack('n2', Font::TTF::Ttopen::ref_cache($r->[0]{'ACTION'}[0], $ctables, length($out)),
484 Font::TTF::Ttopen::ref_cache($r->[0]{'ACTION'}[1], $ctables, length($out) + 2));
489 $out .= pack('n2', Font::TTF::Ttopen::ref_cache($r->[0]{'ACTION'}[0], $ctables, length($out) + $base),
490 Font::TTF::Ttopen::ref_cache($r->[0]{'ACTION'}[1], $ctables, length($out) + 2 + $base));
485491 }
486492 } elsif ($type == 4 || $type == 5 || $type == 6)
487493 {
488494 my ($loc_off, $loc_t, $ltables);
489495
490 $out = pack('n7', $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'MATCH'}[0], $ctables, 2),
491 Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 4),
496 $out = pack('n7', $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'MATCH'}[0], $ctables, 2 + $base),
497 Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 4 + $base),
492498 $#{$lookup->{'RULES'}[0][0]{'ACTION'}} + 1, 12, ($#{$lookup->{'MARKS'}} + 4) << 2,
493499 $#{$lookup->{'MARKS'}} + 1);
494500 foreach $r (@{$lookup->{'MARKS'}})
523529 push (@reftables, [$ltables, $loc_t]) if ($type == 5);
524530 }
525531 push (@reftables, [$ltables, $loc_t]) unless ($type == 5);
532 $out = Font::TTF::Ttopen::out_final($fh, $out, \@reftables, 1);
526533 } elsif ($type == 7 || $type == 8)
527 { $out = $self->out_context($lookup, $fh, $type - 2, $fmt, $ctables, $out, $num); }
528 push (@reftables, [$ctables, 0]);
529 Font::TTF::Ttopen::out_final($fh, $out, \@reftables);
530 $lookup;
534 { $out = $self->out_context($lookup, $fh, $type - 2, $fmt, $ctables, $out, $num, $base); }
535 # push (@reftables, [$ctables, 0]);
536 $out;
531537 }
532538
533539
196196
197197 sub out_sub
198198 {
199 my ($self, $fh, $main_lookup, $index) = @_;
199 my ($self, $fh, $main_lookup, $index, $ctables, $base) = @_;
200200 my ($type) = $main_lookup->{'TYPE'};
201201 my ($lookup) = $main_lookup->{'SUB'}[$index];
202202 my ($fmt) = $lookup->{'FORMAT'};
203203 my ($out, $r, $t, $i, $j, $offc, $offd, $numd);
204204 my ($num) = $#{$lookup->{'RULES'}} + 1;
205 my ($ctables) = {};
206205
207206 if ($type == 1)
208207 {
209 $out = pack("nn", $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2));
208 $out = pack("nn", $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2 + $base));
210209 if ($fmt == 1)
211210 { $out .= pack("n", $lookup->{'ADJUST'}); }
212211 else
217216 }
218217 } elsif ($type == 2 || $type == 3)
219218 {
220 $out = pack("nnn", $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2),
219 $out = pack("nnn", $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2 + $base),
221220 $num);
222221 $out .= pack('n*', (0) x $num);
223222 $offc = length($out);
229228 $offc = length($out);
230229 }
231230 } elsif ($type == 4 || $type == 5 || $type == 6)
232 { $out = $self->out_context($lookup, $fh, $type, $fmt, $ctables, $out, $num); }
233 Font::TTF::Ttopen::out_final($fh, $out, [[$ctables, 0]]);
234 $lookup;
231 { $out = $self->out_context($lookup, $fh, $type, $fmt, $ctables, $out, $num, $base); }
232 # Font::TTF::Ttopen::out_final($fh, $out, [[$ctables, 0]]);
233 $out;
235234 }
236235
237236 =head1 AUTHOR
603603 $self->{' DAT'} .= pack("a" . $len, substr($self->{'hints'}, 0, $len));
604604 }
605605 }
606 $self->{' DAT'} .= "\000" if (length($self->{' DAT'}) & 1);
606 my ($olen) = length($self->{' DAT'});
607 $self->{' DAT'} .= ("\000") x (4 - ($olen & 3)) if ($olen & 3);
607608 $self->{' OUTLEN'} = length($self->{' DAT'});
608609 $self->{' read'} = 2; # changed from 1 to 2 so we don't read_dat() again
609610 # we leave numPoints and instLen since maxp stats use this
774775 { ($x, $y) = ($x + $comp->{'args'}[0], $y + $comp->{'args'}[1]); }
775776 push (@{$self->{'x'}}, $x);
776777 push (@{$self->{'y'}}, $y);
778 push (@{$self->{'flags'}}, $compg->{'flags'}[$i]);
777779 }
778780 foreach $e (@{$compg->{'endPoints'}})
779781 { push (@{$self->{'endPoints'}}, $e + $nump); }
145145 {
146146 my ($g) = $self->{' PARENT'}{'loca'}{'glyphs'}[$i] || next;
147147
148 @n = $g->maxInfo($self->{' PARENT'}{'loca'}{'glyphs'});
148 @n = $g->maxInfo;
149149
150150 for ($j = 0; $j <= $#n; $j++)
151151 { $m[$j] = $n[$j] if $n[$j] > $m[$j]; }
105105 else
106106 { $win_langs{$i + 0x400} = $ms_langids[$i][0]; }
107107 }
108 %langs_win = map {$win_langs{$_} => $_} keys %win_langs;
108 %langs_win = map {my ($t) = $win_langs{$_}; my (@res) = ($t => $_); push (@res, $t => $_) if ($t =~ s/-.*$//o && ($_ & 0xFC00) == 0x400); @res} keys %win_langs;
109109 $i = 0;
110110 %langs_mac = map {$_ => $i++} @mac_langs;
111111 }
332332 }
333333
334334
335 =head2 set_name($nid, $str, $lang)
335 =head2 set_name($nid, $str[, $lang[, @cover]])
336336
337337 Sets the given name id string to $str for all platforms and encodings that
338338 this module can handle. If $lang is set, it is interpretted as a language
339339 tag and if the particular language of a string is found to match, then
340340 that string is changed, otherwise no change occurs.
341341
342 Notice that this function does not add any names to the table.
342 If supplied, @cover should be a list of references to two-element arrays
343 containing pid,eid pairs that should added to the name table if not already present.
344
345 This function does not add any names to the table unless @cover is supplied.
343346
344347 =cut
345348
346349 sub set_name
347350 {
348 my ($self, $nid, $str, $lang) = @_;
349 my ($pid, $eid, $lid);
351 my ($self, $nid, $str, $lang, @cover) = @_;
352 my ($pid, $eid, $lid, $c);
350353
351354 foreach $pid (0 .. $#{$self->{'strings'}[$nid]})
352355 {
356 my $strNL = $str;
357 $strNL =~ s/\n/\r\n/og if $pid == 3;
358 $strNL =~ s/\n/\r/og if $pid == 1;
353359 foreach $eid (0 .. $#{$self->{'strings'}[$nid][$pid]})
354360 {
355361 foreach $lid (keys %{$self->{'strings'}[$nid][$pid][$eid]})
356362 {
357363 next unless (!defined $lang || $self->match_lang($pid, $lid, $lang));
358 $self->{'strings'}[$nid][$pid][$eid]{$lid} = $str;
364 $self->{'strings'}[$nid][$pid][$eid]{$lid} = $strNL;
365 foreach $c (0 .. scalar @cover)
366 {
367 next unless ($cover[$c][0] == $pid && $cover[$c][1] == $eid);
368 delete $cover[$c];
369 last;
370 }
359371 }
360372 }
373 }
374 foreach $c (@cover)
375 {
376 my ($pid, $eid) = @{$c};
377 my ($lid) = $self->find_lang($pid, $lang);
378 my $strNL = $str;
379 $strNL =~ s/\n/\r\n/og if $pid == 3;
380 $strNL =~ s/\n/\r/og if $pid == 1;
381 $self->{'strings'}[$nid][$pid][$eid]{$lid} = $strNL;
361382 }
362383 return $self;
363384 }
557578 );
558579 #'
559580
560 @ms_langids = ( [],
581 @ms_langids = ( [""],
561582 ['ar', ["-SA", "-IQ", "-EG", "-LY", "-DZ", "-MA", "-TN",
562583 "-OM", "-YE", "-SY", "-JO", "-LB", "-KW", "-AE",
563584 "-BH", "-QA"]],
316316
317317 Releases ALL of the memory used by this table, and all of its component/child
318318 objects. This method is called automatically by
319 'C<Font::TTF::Font-E<gt>release>' (so you don't have to call it yourself).
319 'Font::TTF::Font-E<gt>release' (so you don't have to call it yourself).
320320
321321 B<NOTE>, that it is important that this method get called at some point prior
322322 to the actual destruction of the object. Internally, we track things in a
0 package Font::TTF::Tags;
1
2 =head1 NAME
3
4 Font::TTF::Tags - Utilities for TrueType/OpenType tags
5
6 =head1 SYNOPSIS
7
8 use Font::TTF::Tags qw( %tttags %ttnames readtagsfile );
9
10 # Look at built-in stuff:
11 $script_tag = %tttags{'SCRIPT'}{'Cypriot Syllabary'};
12 $lang_name = %ttnames{'LANGUAGE'}{'Afrikaans'}
13
14 # Read latest tags file to add to built-in definitions
15 readtagsfile ("C:\\Program Files\\Microsoft VOLT\\TAGS.txt");
16
17 First-level keys to %tttags and %ttnames are:
18
19 =over
20
21 'SCRIPT' -- retrieve script tag or name
22
23 'LANGUAGE' -- retrieve language tag or name
24
25 'FEATURE' -- retrieve feature tag or name
26
27 =back
28
29 =head1 METHODS
30
31 =cut
32
33 use strict;
34 use vars qw( %tttags %ttnames @EXPORT_OK );
35 use Exporter qw( import );
36 @EXPORT_OK = qw( %tttags %ttnames readtagsfile);
37
38
39 %tttags = (
40 'SCRIPT' => {
41 "Arabic" => "arab",
42 "Armenian" => "armn",
43 "Balinese" => "bali",
44 "Bengali" => "beng",
45 "Bopomofo" => "bopo",
46 "Braille" => "brai",
47 "Buginese" => "bugi",
48 "Buhid" => "buhd",
49 "Byzantine Music" => "byzm",
50 "Canadian Syllabics" => "cans",
51 "Cherokee" => "cher",
52 "CJK Ideographic" => "hani",
53 "Coptic" => "copt",
54 "Cypriot Syllabary" => "cprt",
55 "Cyrillic" => "cyrl",
56 "Default" => "dflt",
57 "Deseret" => "dsrt",
58 "Devanagari" => "deva",
59 "Ethiopic" => "ethi",
60 "Georgian" => "geor",
61 "Glagolitic" => "glag",
62 "Gothic" => "goth",
63 "Greek" => "grek",
64 "Gujarati" => "gujr",
65 "Gurmukhi" => "guru",
66 "Hangul Jamo" => "jamo",
67 "Hangul" => "hang",
68 "Hanunoo" => "hano",
69 "Hebrew" => "hebr",
70 "Hiragana" => "kana",
71 "Javanese" => "java",
72 "Kannada" => "knda",
73 "Katakana" => "kana",
74 "Kharosthi" => "khar",
75 "Khmer" => "khmr",
76 "Lao" => "lao ",
77 "Latin" => "latn",
78 "Limbu" => "limb",
79 "Linear B" => "linb",
80 "Malayalam" => "mlym",
81 "Mathematical Alphanumeric Symbols" => "math",
82 "Mongolian" => "mong",
83 "Musical Symbols" => "musc",
84 "Myanmar" => "mymr",
85 "N'ko" => "nko ",
86 "Ogham" => "ogam",
87 "Old Italic" => "ital",
88 "Old Persian Cuneiform" => "xpeo",
89 "Oriya" => "orya",
90 "Osmanya" => "osma",
91 "Phags-pa" => "phag",
92 "Phoenician" => "phnx",
93 "Runic" => "runr",
94 "Shavian" => "shaw",
95 "Sinhala" => "sinh",
96 "Sumero-Akkadian Cuneiform" => "xsux",
97 "Syloti Nagri" => "sylo",
98 "Syriac" => "syrc",
99 "Tagalog" => "tglg",
100 "Tagbanwa" => "tagb",
101 "Tai Le" => "tale",
102 "New Tai Lue" => "talu",
103 "Tamil" => "taml",
104 "Telugu" => "telu",
105 "Thaana" => "thaa",
106 "Thai" => "thai",
107 "Tibetan" => "tibt",
108 "Tifinagh" => "tfng",
109 "Ugaritic Cuneiform" => "ugar",
110 "Yi" => "yi ",
111 },
112
113 'LANGUAGE' => {
114 "Abaza" => "ABA ",
115 "Abkhazian" => "ABK ",
116 "Adyghe" => "ADY ",
117 "Afrikaans" => "AFK ",
118 "Afar" => "AFR ",
119 "Agaw" => "AGW ",
120 "Altai" => "ALT ",
121 "Amharic" => "AMH ",
122 "Arabic" => "ARA ",
123 "Aari" => "ARI ",
124 "Arakanese" => "ARK ",
125 "Assamese" => "ASM ",
126 "Athapaskan" => "ATH ",
127 "Avar" => "AVR ",
128 "Awadhi" => "AWA ",
129 "Aymara" => "AYM ",
130 "Azeri" => "AZE ",
131 "Badaga" => "BAD ",
132 "Baghelkhandi" => "BAG ",
133 "Balkar" => "BAL ",
134 "Baule" => "BAU ",
135 "Berber" => "BBR ",
136 "Bench" => "BCH ",
137 "Bible Cree" => "BCR ",
138 "Belarussian" => "BEL ",
139 "Bemba" => "BEM ",
140 "Bengali" => "BEN ",
141 "Bulgarian" => "BGR ",
142 "Bhili" => "BHI ",
143 "Bhojpuri" => "BHO ",
144 "Bikol" => "BIK ",
145 "Bilen" => "BIL ",
146 "Blackfoot" => "BKF ",
147 "Balochi" => "BLI ",
148 "Balante" => "BLN ",
149 "Balti" => "BLT ",
150 "Bambara" => "BMB ",
151 "Bamileke" => "BML ",
152 "Breton" => "BRE ",
153 "Brahui" => "BRH ",
154 "Braj Bhasha" => "BRI ",
155 "Burmese" => "BRM ",
156 "Bashkir" => "BSH ",
157 "Beti" => "BTI ",
158 "Catalan" => "CAT ",
159 "Cebuano" => "CEB ",
160 "Chechen" => "CHE ",
161 "Chaha Gurage" => "CHG ",
162 "Chattisgarhi" => "CHH ",
163 "Chichewa" => "CHI ",
164 "Chukchi" => "CHK ",
165 "Chipewyan" => "CHP ",
166 "Cherokee" => "CHR ",
167 "Chuvash" => "CHU ",
168 "Comorian" => "CMR ",
169 "Coptic" => "COP ",
170 "Cree" => "CRE ",
171 "Carrier" => "CRR ",
172 "Crimean Tatar" => "CRT ",
173 "Church Slavonic" => "CSL ",
174 "Czech" => "CSY ",
175 "Danish" => "DAN ",
176 "Dargwa" => "DAR ",
177 "Woods Cree" => "DCR ",
178 "German" => "DEU ",
179 "Default" => "dflt",
180 "Dogri" => "DGR ",
181 "Divehi" => "DIV ",
182 "Djerma" => "DJR ",
183 "Dangme" => "DNG ",
184 "Dinka" => "DNK ",
185 "Dungan" => "DUN ",
186 "Dzongkha" => "DZN ",
187 "Ebira" => "EBI ",
188 "Eastern Cree" => "ECR ",
189 "Edo" => "EDO ",
190 "Efik" => "EFI ",
191 "Greek" => "ELL ",
192 "English" => "ENG ",
193 "Erzya" => "ERZ ",
194 "Spanish" => "ESP ",
195 "Estonian" => "ETI ",
196 "Basque" => "EUQ ",
197 "Evenki" => "EVK ",
198 "Even" => "EVN ",
199 "Ewe" => "EWE ",
200 "French Antillean" => "FAN ",
201 "Farsi" => "FAR ",
202 "Finnish" => "FIN ",
203 "Fijian" => "FJI ",
204 "Flemish" => "FLE ",
205 "Forest Nenets" => "FNE ",
206 "Fon" => "FON ",
207 "Faroese" => "FOS ",
208 "French" => "FRA ",
209 "Frisian" => "FRI ",
210 "Friulian" => "FRL ",
211 "Futa" => "FTA ",
212 "Fulani" => "FUL ",
213 "Ga" => "GAD ",
214 "Gaelic" => "GAE ",
215 "Gagauz" => "GAG ",
216 "Galician" => "GAL ",
217 "Garshuni" => "GAR ",
218 "Garhwali" => "GAW ",
219 "Ge'ez" => "GEZ ",
220 "Gilyak" => "GIL ",
221 "Gumuz" => "GMZ ",
222 "Gondi" => "GON ",
223 "Greenlandic" => "GRN ",
224 "Garo" => "GRO ",
225 "Guarani" => "GUA ",
226 "Gujarati" => "GUJ ",
227 "Haitian" => "HAI ",
228 "Halam" => "HAL ",
229 "Harauti" => "HAR ",
230 "Hausa" => "HAU ",
231 "Hawaiin" => "HAW ",
232 "Hammer-Banna" => "HBN ",
233 "Hiligaynon" => "HIL ",
234 "Hindi" => "HIN ",
235 "High Mari" => "HMA ",
236 "Hindko" => "HND ",
237 "Ho" => "HO ",
238 "Harari" => "HRI ",
239 "Croatian" => "HRV ",
240 "Hungarian" => "HUN ",
241 "Armenian" => "HYE ",
242 "Igbo" => "IBO ",
243 "Ijo" => "IJO ",
244 "Ilokano" => "ILO ",
245 "Indonesian" => "IND ",
246 "Ingush" => "ING ",
247 "Inuktitut" => "INU ",
248 "Irish" => "IRI ",
249 "Irish Traditional" => "IRT ",
250 "Icelandic" => "ISL ",
251 "Inari Sami" => "ISM ",
252 "Italian" => "ITA ",
253 "Hebrew" => "IWR ",
254 "Javanese" => "JAV ",
255 "Yiddish" => "JII ",
256 "Japanese" => "JAN ",
257 "Judezmo" => "JUD ",
258 "Jula" => "JUL ",
259 "Kabardian" => "KAB ",
260 "Kachchi" => "KAC ",
261 "Kalenjin" => "KAL ",
262 "Kannada" => "KAN ",
263 "Karachay" => "KAR ",
264 "Georgian" => "KAT ",
265 "Kazakh" => "KAZ ",
266 "Kebena" => "KEB ",
267 "Khutsuri Georgian" => "KGE ",
268 "Khakass" => "KHA ",
269 "Khanty-Kazim" => "KHK ",
270 "Khmer" => "KHM ",
271 "Khanty-Shurishkar" => "KHS ",
272 "Khanty-Vakhi" => "KHV ",
273 "Khowar" => "KHW ",
274 "Kikuyu" => "KIK ",
275 "Kirghiz" => "KIR ",
276 "Kisii" => "KIS ",
277 "Kokni" => "KKN ",
278 "Kalmyk" => "KLM ",
279 "Kamba" => "KMB ",
280 "Kumaoni" => "KMN ",
281 "Komo" => "KMO ",
282 "Komso" => "KMS ",
283 "Kanuri" => "KNR ",
284 "Kodagu" => "KOD ",
285 "Korean Old Hangul" => "KOH ",
286 "Konkani" => "KOK ",
287 "Kikongo" => "KON ",
288 "Komi-Permyak" => "KOP ",
289 "Korean" => "KOR ",
290 "Komi-Zyrian" => "KOZ ",
291 "Kpelle" => "KPL ",
292 "Krio" => "KRI ",
293 "Karakalpak" => "KRK ",
294 "Karelian" => "KRL ",
295 "Karaim" => "KRM ",
296 "Karen" => "KRN ",
297 "Koorete" => "KRT ",
298 "Kashmiri" => "KSH ",
299 "Khasi" => "KSI ",
300 "Kildin Sami" => "KSM ",
301 "Kui" => "KUI ",
302 "Kulvi" => "KUL ",
303 "Kumyk" => "KUM ",
304 "Kurdish" => "KUR ",
305 "Kurukh" => "KUU ",
306 "Kuy" => "KUY ",
307 "Koryak" => "KYK ",
308 "Ladin" => "LAD ",
309 "Lahuli" => "LAH ",
310 "Lak" => "LAK ",
311 "Lambani" => "LAM ",
312 "Lao" => "LAO ",
313 "Latin" => "LAT ",
314 "Laz" => "LAZ ",
315 "L-Cree" => "LCR ",
316 "Ladakhi" => "LDK ",
317 "Lezgi" => "LEZ ",
318 "Lingala" => "LIN ",
319 "Low Mari" => "LMA ",
320 "Limbu" => "LMB ",
321 "Lomwe" => "LMW ",
322 "Lower Sorbian" => "LSB ",
323 "Lule Sami" => "LSM ",
324 "Lithuanian" => "LTH ",
325 "Luba" => "LUB ",
326 "Luganda" => "LUG ",
327 "Luhya" => "LUH ",
328 "Luo" => "LUO ",
329 "Latvian" => "LVI ",
330 "Majang" => "MAJ ",
331 "Makua" => "MAK ",
332 "Malayalam Traditional" => "MAL ",
333 "Mansi" => "MAN ",
334 "Marathi" => "MAR ",
335 "Marwari" => "MAW ",
336 "Mbundu" => "MBN ",
337 "Manchu" => "MCH ",
338 "Moose Cree" => "MCR ",
339 "Mende" => "MDE ",
340 "Me'en" => "MEN ",
341 "Mizo" => "MIZ ",
342 "Macedonian" => "MKD ",
343 "Male" => "MLE ",
344 "Malagasy" => "MLG ",
345 "Malinke" => "MLN ",
346 "Malayalam Reformed" => "MLR ",
347 "Malay" => "MLY ",
348 "Mandinka" => "MND ",
349 "Mongolian" => "MNG ",
350 "Manipuri" => "MNI ",
351 "Maninka" => "MNK ",
352 "Manx Gaelic" => "MNX ",
353 "Moksha" => "MOK ",
354 "Moldavian" => "MOL ",
355 "Mon" => "MON ",
356 "Moroccan" => "MOR ",
357 "Maori" => "MRI ",
358 "Maithili" => "MTH ",
359 "Maltese" => "MTS ",
360 "Mundari" => "MUN ",
361 "Naga-Assamese" => "NAG ",
362 "Nanai" => "NAN ",
363 "Naskapi" => "NAS ",
364 "N-Cree" => "NCR ",
365 "Ndebele" => "NDB ",
366 "Ndonga" => "NDG ",
367 "Nepali" => "NEP ",
368 "Newari" => "NEW ",
369 "Norway House Cree" => "NHC ",
370 "Nisi" => "NIS ",
371 "Niuean" => "NIU ",
372 "Nkole" => "NKL ",
373 "N'ko" => "NK0 ",
374 "Dutch" => "NLD ",
375 "Nogai" => "NOG ",
376 "Norwegian" => "NOR ",
377 "Northern Sami" => "NSM ",
378 "Northern Tai" => "NTA ",
379 "Esperanto" => "NTO ",
380 "Nynorsk" => "NYN ",
381 "Oji-Cree" => "OCR ",
382 "Ojibway" => "OJB ",
383 "Oriya" => "ORI ",
384 "Oromo" => "ORO ",
385 "Ossetian" => "OSS ",
386 "Palestinian Aramaic" => "PAA ",
387 "Pali" => "PAL ",
388 "Punjabi" => "PAN ",
389 "Palpa" => "PAP ",
390 "Pashto" => "PAS ",
391 "Polytonic Greek" => "PGR ",
392 "Pilipino" => "PIL ",
393 "Palaung" => "PLG ",
394 "Polish" => "PLK ",
395 "Provencal" => "PRO ",
396 "Portuguese" => "PTG ",
397 "Chin" => "QIN ",
398 "Rajasthani" => "RAJ ",
399 "R-Cree" => "RCR ",
400 "Russian Buriat" => "RBU ",
401 "Riang" => "RIA ",
402 "Rhaeto-Romanic" => "RMS ",
403 "Romanian" => "ROM ",
404 "Romany" => "ROY ",
405 "Rusyn" => "RSY ",
406 "Ruanda" => "RUA ",
407 "Russian" => "RUS ",
408 "Sadri" => "SAD ",
409 "Sanskrit" => "SAN ",
410 "Santali" => "SAT ",
411 "Sayisi" => "SAY ",
412 "Sekota" => "SEK ",
413 "Selkup" => "SEL ",
414 "Sango" => "SGO ",
415 "Shan" => "SHN ",
416 "Sibe" => "SIB ",
417 "Sidamo" => "SID ",
418 "Silte Gurage" => "SIG ",
419 "Skolt Sami" => "SKS ",
420 "Slovak" => "SKY ",
421 "Slavey" => "SLA ",
422 "Slovenian" => "SLV ",
423 "Somali" => "SML ",
424 "Samoan" => "SMO ",
425 "Sena" => "SNA ",
426 "Sindhi" => "SND ",
427 "Sinhalese" => "SNH ",
428 "Soninke" => "SNK ",
429 "Sodo Gurage" => "SOG ",
430 "Sotho" => "SOT ",
431 "Albanian" => "SQI ",
432 "Serbian" => "SRB ",
433 "Saraiki" => "SRK ",
434 "Serer" => "SRR ",
435 "South Slavey" => "SSL ",
436 "Southern Sami" => "SSM ",
437 "Suri" => "SUR ",
438 "Svan" => "SVA ",
439 "Swedish" => "SVE ",
440 "Swadaya Aramaic" => "SWA ",
441 "Swahili" => "SWK ",
442 "Swazi" => "SWZ ",
443 "Sutu" => "SXT ",
444 "Syriac" => "SYR ",
445 "Tabasaran" => "TAB ",
446 "Tajiki" => "TAJ ",
447 "Tamil" => "TAM ",
448 "Tatar" => "TAT ",
449 "TH-Cree" => "TCR ",
450 "Telugu" => "TEL ",
451 "Tongan" => "TGN ",
452 "Tigre" => "TGR ",
453 "Tigrinya" => "TGY ",
454 "Thai" => "THA ",
455 "Tahitian" => "THT ",
456 "Tibetan" => "TIB ",
457 "Turkmen" => "TKM ",
458 "Temne" => "TMN ",
459 "Tswana" => "TNA ",
460 "Tundra Nenets" => "TNE ",
461 "Tonga" => "TNG ",
462 "Todo" => "TOD ",
463 "Turkish" => "TRK ",
464 "Tsonga" => "TSG ",
465 "Turoyo Aramaic" => "TUA ",
466 "Tulu" => "TUL ",
467 "Tuvin" => "TUV ",
468 "Twi" => "TWI ",
469 "Udmurt" => "UDM ",
470 "Ukrainian" => "UKR ",
471 "Urdu" => "URD ",
472 "Upper Sorbian" => "USB ",
473 "Uyghur" => "UYG ",
474 "Uzbek" => "UZB ",
475 "Venda" => "VEN ",
476 "Vietnamese" => "VIT ",
477 "Wa" => "WA ",
478 "Wagdi" => "WAG ",
479 "West-Cree" => "WCR ",
480 "Welsh" => "WEL ",
481 "Wolof" => "WLF ",
482 "Tai Lue" => "XBD ",
483 "Xhosa" => "XHS ",
484 "Yakut" => "YAK ",
485 "Yoruba" => "YBA ",
486 "Y-Cree" => "YCR ",
487 "Yi Classic" => "YIC ",
488 "Yi Modern" => "YIM ",
489 "Chinese Hong Kong" => "ZHH ",
490 "Chinese Phonetic" => "ZHP ",
491 "Chinese Simplified" => "ZHS ",
492 "Chinese Traditional" => "ZHT ",
493 "Zande" => "ZND ",
494 "Zulu" => "ZUL ",
495 },
496
497 'FEATURE' => {
498 "Access All Alternates" => "aalt",
499 "Above-Base Forms" => "abvf",
500 "Above-Base Mark Positioning" => "abvm",
501 "Above-Base Substitutions" => "abvs",
502 "Alternative Fractions" => "afrc",
503 "Akhands" => "akhn",
504 "Below-Base Forms" => "blwf",
505 "Below-Base Mark Positioning" => "blwm",
506 "Below-Base Substitutions" => "blws",
507 "Petite Capitals From Capitals" => "c2pc",
508 "Small Capitals From Capitals" => "c2sc",
509 "Contextual Alternates" => "calt",
510 "Case-Sensitive Forms" => "case",
511 "Glyph Composition/Decomposition" => "ccmp",
512 "Conjunct form after ro" => "cfar",
513 "Contextual Ligatures" => "clig",
514 "Conjuncts" => "cjct",
515 "Capital Spacing" => "cpsp",
516 "Contextual Swash" => "cswh",
517 "Cursive Positioning" => "curs",
518 "Default Processing" => "dflt",
519 "Distances" => "dist",
520 "Discretionary Ligatures" => "dlig",
521 "Denominators" => "dnom",
522 "Diphthongs" => "dpng",
523 "Expert Forms" => "expt",
524 "Final glyph Alternates" => "falt",
525 "Terminal Forms" => "fina",
526 "Terminal Forms #2" => "fin2",
527 "Terminal Forms #3" => "fin3",
528 "Fractions" => "frac",
529 "Full Width" => "fwid",
530 "Half Forms" => "half",
531 "Halant Forms" => "haln",
532 "Alternate Half Width" => "halt",
533 "Historical Forms" => "hist",
534 "Horizontal Kana Alternates" => "hkna",
535 "Historical Ligatures" => "hlig",
536 "Hangul" => "hngl",
537 "Half Width" => "hwid",
538 "Hojo Kanji Forms" => "hojo",
539 "Initial Forms" => "init",
540 "Isolated Forms" => "isol",
541 "Italics" => "ital",
542 "Japanese Forms" => "jajp",
543 "Justification Alternatives" => "jalt",
544 "JIS04 Forms" => "jp04",
545 "JIS78 Forms" => "jp78",
546 "JIS83 Forms" => "jp83",
547 "JIS90 Forms" => "jp90",
548 "Kerning" => "kern",
549 "Left Bounds" => "lfbd",
550 "Standard Ligatures" => "liga",
551 "Leading Jamo Forms" => "ljmo",
552 "Lining Figures" => "lnum",
553 "Localized Forms" => "locl",
554 "Mark Positioning" => "mark",
555 "Medial Forms" => "medi",
556 "Medial Forms #2" => "med2",
557 "Mathematical Greek" => "mgrk",
558 "Mark to Mark Positioning" => "mkmk",
559 "Mark Positioning via Substitution" => "mset",
560 "Alternate Annotation Forms" => "nalt",
561 "NLC Kanji Forms" => "nlck",
562 "Nukta Forms" => "nukt",
563 "Numerators" => "numr",
564 "Old Style Figures" => "onum",
565 "Optical Bounds" => "opbd",
566 "Ordinals" => "ordn",
567 "Ornaments" => "ornm",
568 "Proportional Alternate Width" => "palt",
569 "Petite Capitals" => "pcap",
570 "Proportional Figures" => "pnum",
571 "Pre-base Forms" => "pref",
572 "Pre-base Substitutions" => "pres",
573 "Post-base Forms" => "pstf",
574 "Post-base Substitutions" => "psts",
575 "Proportional Widths" => "pwid",
576 "Quarter Widths" => "qwid",
577 "Randomize" => "rand",
578 "Rakar Forms" => "rkrf",
579 "Required Ligatures" => "rlig",
580 "Reph Form" => "rphf",
581 "Right Bounds" => "rtbd",
582 "Right-To-Left Alternates" => "rtbd",
583 "Ruby Notation Forms" => "ruby",
584 "Stylistic Alternates" => "salt",
585 "Scientific Inferiors" => "sinf",
586 "Optical Size" => "size",
587 "Small Capitals" => "smcp",
588 "Simplified Forms" => "smpl",
589 "Sylistic Set 1" => "ss01",
590 "Sylistic Set 2" => "ss02",
591 "Sylistic Set 3" => "ss03",
592 "Sylistic Set 4" => "ss04",
593 "Sylistic Set 5" => "ss05",
594 "Sylistic Set 6" => "ss06",
595 "Sylistic Set 7" => "ss07",
596 "Sylistic Set 8" => "ss08",
597 "Sylistic Set 9" => "ss09",
598 "Sylistic Set 10" => "ss10",
599 "Sylistic Set 11" => "ss11",
600 "Sylistic Set 12" => "ss12",
601 "Sylistic Set 13" => "ss13",
602 "Sylistic Set 14" => "ss14",
603 "Sylistic Set 15" => "ss15",
604 "Sylistic Set 16" => "ss16",
605 "Sylistic Set 17" => "ss17",
606 "Sylistic Set 18" => "ss18",
607 "Sylistic Set 19" => "ss19",
608 "Sylistic Set 20" => "ss20",
609 "Subscript" => "subs",
610 "Superscript" => "sups",
611 "Swash" => "swsh",
612 "Titling" => "titl",
613 "Trailing Jamo Forms" => "tjmo",
614 "Traditional Name Forms" => "tnam",
615 "Tabular Figures" => "tnum",
616 "Traditional Forms" => "trad",
617 "Third Widths" => "twid",
618 "Unicase" => "unic",
619 "Alternate Vertical Metrics" => "valt",
620 "Vattu Variants" => "vatu",
621 "Vertical Writing" => "vert",
622 "Alternate Vertical Half Metrics" => "vhal",
623 "Vowel Jamo Forms" => "vjmo",
624 "Vertical Kana Alternates" => "vkna",
625 "Vertical Kerning" => "vkrn",
626 "Proportional Alternate Vertical Metrics" => "vpal",
627 "Vertical Rotation" => "vrt2",
628 "Slashed Zero" => "zero",
629 }
630 );
631
632 {
633 foreach my $s (qw ( SCRIPT LANGUAGE FEATURE ) )
634 {
635 map { $ttnames{$s}{$tttags{$s}{$_}} = $_ } keys %{$tttags{$s}};
636 }
637 }
638
639
640 =head2 readtagsfile ( filename )
641
642 Read a file in the syntax of Tags.txt (included with Microsoft VOLT) to obtain additional/replacement tag definitions.
643
644 Returns 0 if can't open the file; else 1.
645
646 =cut
647
648 sub readtagsfile
649 {
650 my $fname = shift;
651 open (TAGS, $fname) or return 0;
652 my ($what, $name, $tag);
653 while (<TAGS>)
654 {
655 ($what, $name, $tag) = (m/"([^"]*)", "([^"]*)", "([^"]*)"/); #"
656 $ttnames{$what}{$tag} = $name;
657 $tttags{$what}{$name} = $tag;
658 }
659 close TAGS;
660 return 1;
661 }
662
663
664
665 1;
412412 $fh->read($dat, $nSub * 2);
413413 $j = 0;
414414 my @offsets = unpack("n*", $dat);
415 my $isExtension = ($l->{'TYPE'} == $self->extension());
415416 for ($j = 0; $j < $nSub; $j++)
416417 {
417 $l->{'SUB'}[$j]{' OFFSET'} = $offsets[$j];
418 $fh->seek($moff + $oLook + $l->{' OFFSET'} + $l->{'SUB'}[$j]{' OFFSET'}, 0);
418 $l->{'SUB'}[$j]{' OFFSET'} = $offsets[$j];
419 $fh->seek($moff + $oLook + $l->{' OFFSET'} + $l->{'SUB'}[$j]{' OFFSET'}, 0);
420 if ($isExtension)
421 {
422 $fh->read($dat, 8);
423 my $longOff;
424 (undef, $l->{'TYPE'}, $longOff) = unpack("nnN", $dat);
425 $l->{'SUB'}[$j]{' OFFSET'} += $longOff;
426 $fh->seek($moff + $oLook + $l->{' OFFSET'} + $l->{'SUB'}[$j]{' OFFSET'}, 0);
427 }
419428 $self->read_sub($fh, $l, $j);
420429 }
421430 }
459468 {
460469 my ($self, $fh) = @_;
461470 my ($i, $j, $base, $off, $tag, $t, $l, $lTag, $oScript, @script, @tags);
462 my ($end, $nTags, @offs, $oFeat, $oLook, $nSub, $nSubs, $big);
471 my ($end, $nTags, @offs, $oFeat, $oLook, $nSub, $nSubs, $big, $out);
463472
464473 return $self->SUPER::out($fh) unless $self->{' read'};
465474
599608 }
600609 else
601610 { $end = $tag->{' EXT_OFFSET'}; }
602 @offs = ();
611 my (@offs, $out, @refs);
603612 for ($j = 0; $j < $nSub; $j++)
604613 {
605 push(@offs, tell($fh) - $end);
606 $self->out_sub($fh, $tag, $j);
607 }
614 my ($ctables) = {};
615 my ($base) = length($out);
616 push(@offs, tell($fh) - $end + $base);
617 $out .= $self->out_sub($fh, $tag, $j, $ctables, $base);
618 push (@refs, [$ctables, $base]);
619 }
620 out_final($fh, $out, \@refs);
608621 $end = $fh->tell();
609622 if (!defined $big)
610623 {
746759 my ($fh, $out, $cache_list, $state) = @_;
747760 my ($len) = length($out || '');
748761 my ($base_loc) = $state ? 0 : $fh->tell();
749 my ($loc, $t, $r, $s, $master_cache, $offs, $str);
762 my ($loc, $t, $r, $s, $master_cache, $offs, $str, %vecs);
750763
751764 $fh->print($out || '') unless $state; # first output the current attempt
752765 foreach $r (@$cache_list)
757770 $str = "$t";
758771 if (!defined $master_cache->{$str})
759772 {
760 $master_cache->{$str} = ($state ? length($out) : $fh->tell())
761 - $base_loc;
762 if ($state)
763 { $out .= $r->[0]{$str}[0]->out($fh, 1); }
773 my ($vec) = $r->[0]{$str}[0]->signature();
774 if ($vecs{$vec})
775 { $master_cache->{$str} = $master_cache->{$vecs{$vec}}; }
764776 else
765 { $r->[0]{$str}[0]->out($fh, 0); }
777 {
778 $vecs{$vec} = $str;
779 $master_cache->{$str} = ($state ? length($out) : $fh->tell())
780 - $base_loc;
781 if ($state)
782 { $out .= $r->[0]{$str}[0]->out($fh, 1); }
783 else
784 { $r->[0]{$str}[0]->out($fh, 0); }
785 }
766786 }
767787 foreach $s (@{$r->[0]{$str}[1]})
768788 { substr($out, $s, 2) = pack('n', $master_cache->{$str} - $offs); }
963983
964984 sub out_context
965985 {
966 my ($self, $lookup, $fh, $type, $fmt, $ctables, $out, $num) = @_;
986 my ($self, $lookup, $fh, $type, $fmt, $ctables, $out, $num, $base) = @_;
967987 my ($offc, $offd, $i, $j, $r, $t, $numd);
968988
969989 $out ||= '';
973993
974994 if ($fmt == 1)
975995 {
976 $out = pack("nnn", $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2),
996 $out = pack("nnn", $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2 + $base),
977997 $num);
978998 $base_off = 6;
979999 } elsif ($type == 5)
9801000 {
981 $out = pack("nnnn", $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2),
982 Font::TTF::Ttopen::ref_cache($lookup->{'CLASS'}, $ctables, 4), $num);
1001 $out = pack("nnnn", $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2 + $base),
1002 Font::TTF::Ttopen::ref_cache($lookup->{'CLASS'}, $ctables, 4 + $base), $num);
9831003 $base_off = 8;
9841004 } elsif ($type == 6)
9851005 {
986 $out = pack("n6", $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2),
987 Font::TTF::Ttopen::ref_cache($lookup->{'PRE_CLASS'}, $ctables, 4),
988 Font::TTF::Ttopen::ref_cache($lookup->{'CLASS'}, $ctables, 6),
989 Font::TTF::Ttopen::ref_cache($lookup->{'POST_CLASS'}, $ctables, 8),
1006 $out = pack("n6", $fmt, Font::TTF::Ttopen::ref_cache($lookup->{'COVERAGE'}, $ctables, 2 + $base),
1007 Font::TTF::Ttopen::ref_cache($lookup->{'PRE_CLASS'}, $ctables, 4 + $base),
1008 Font::TTF::Ttopen::ref_cache($lookup->{'CLASS'}, $ctables, 6 + $base),
1009 Font::TTF::Ttopen::ref_cache($lookup->{'POST_CLASS'}, $ctables, 8 + $base),
9901010 $num);
9911011 $base_off = 12;
9921012 }
10331053 $out .= pack('n3', $fmt, $#{$lookup->{'RULES'}[0][0]{'MATCH'}} + 1,
10341054 $#{$lookup->{'RULES'}[0][0]{'ACTION'}} + 1);
10351055 foreach $t (@{$lookup->{'RULES'}[0][0]{'MATCH'}})
1036 { $out .= pack('n', Font::TTF::Ttopen::ref_cache($t, $ctables, length($out))); }
1056 { $out .= pack('n', Font::TTF::Ttopen::ref_cache($t, $ctables, length($out) + $base)); }
10371057 foreach $t (@{$lookup->{'RULES'}[0][0]{'ACTION'}})
10381058 { $out .= pack('n2', @$t); }
10391059 } elsif ($type == 6 && $fmt == 3)
10421062 no strict 'refs'; # temp fix - more code needed (probably "if" statements in the event 'PRE' or 'POST' are empty)
10431063 $out .= pack('n2', $fmt, defined $r->{'PRE'} ? scalar @{$r->{'PRE'}} : 0);
10441064 foreach $t (@{$r->{'PRE'}})
1045 { $out .= pack('n', Font::TTF::Ttopen::ref_cache($t, $ctables, length($out))); }
1065 { $out .= pack('n', Font::TTF::Ttopen::ref_cache($t, $ctables, length($out) + $base)); }
10461066 $out .= pack('n', defined $r->{'MATCH'} ? scalar @{$r->{'MATCH'}} : 0);
10471067 foreach $t (@{$r->{'MATCH'}})
1048 { $out .= pack('n', Font::TTF::Ttopen::ref_cache($t, $ctables, length($out))); }
1068 { $out .= pack('n', Font::TTF::Ttopen::ref_cache($t, $ctables, length($out) + $base)); }
10491069 $out .= pack('n', defined $r->{'POST'} ? scalar @{$r->{'POST'}} : 0);
10501070 foreach $t (@{$r->{'POST'}})
1051 { $out .= pack('n', Font::TTF::Ttopen::ref_cache($t, $ctables, length($out))); }
1071 { $out .= pack('n', Font::TTF::Ttopen::ref_cache($t, $ctables, length($out) + $base)); }
10521072 $out .= pack('n', defined $r->{'ACTION'} ? scalar @{$r->{'ACTION'}} : 0);
10531073 foreach $t (@{$r->{'ACTION'}})
10541074 { $out .= pack('n2', @$t); }
00 package Font::TTF;
11
2 $VERSION = '0.41'; # MJPH 27-MAR-2007 Remove warnings from font copy
2 $VERSION = '0.42'; # MJPH 11-OCT-2007 Add Volt2ttf support
3 # $VERSION = '0.41'; # MJPH 27-MAR-2007 Remove warnings from font copy
34 # Bug fixes in Ttopen, GDEF
45 # Remove redundant head and maxp ->reads
56 # $VERSION = '0.40'; # MJPH 31-JUL-2006 Add EBDT, EBLC tables