summaryrefslogtreecommitdiff
path: root/Build/source/texk
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2012-04-16 23:15:11 +0000
committerKarl Berry <karl@freefriends.org>2012-04-16 23:15:11 +0000
commite8a389a2d60b6ff53118a05f72c266fc3bd725b0 (patch)
treea684b2e593b0f7cede10362be9fe321f733e1acc /Build/source/texk
parentc3c415e17085b0a75a89e652d576f6a943a41649 (diff)
fontools (6mar12)
git-svn-id: svn://tug.org/texlive/trunk@25995 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk')
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/fontools/afm2afm458
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/fontools/autoinst2267
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/fontools/cmap2enc5307
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/fontools/font2afm190
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/fontools/ot2kpx1102
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/fontools/pfm2kpx299
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/fontools/showglyphs184
7 files changed, 2237 insertions, 7570 deletions
diff --git a/Build/source/texk/texlive/linked_scripts/fontools/afm2afm b/Build/source/texk/texlive/linked_scripts/fontools/afm2afm
index 80ca105ed90..87d6ef1bbb4 100755
--- a/Build/source/texk/texlive/linked_scripts/fontools/afm2afm
+++ b/Build/source/texk/texlive/linked_scripts/fontools/afm2afm
@@ -1,115 +1,291 @@
-#!/usr/bin/perl
+#! /usr/bin/env perl
-use Getopt::Std;
-use integer;
-use warnings; no warnings qw(uninitialized);
+=begin COPYRIGHT
-getopts "e:o:", \%options;
+----------------------------------------------------------------------------
-$0 =~ s!.*/!!;
-die "Usage: $0 -e encoding [-o output] afmfile\n" if
- @ARGV != 1 or !$options{e};
+ Copyright (C) 2005-2012 Marc Penninga.
-if ($options{o} and -e $options{o}) {
- die "$0: output file exists\n";
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to
+ Free Software Foundation, Inc.,
+ 59 Temple Place,
+ Suite 330,
+ Boston, MA 02111-1307,
+ USA
+
+----------------------------------------------------------------------------
+
+=end COPYRIGHT
+
+=cut
+
+use strict;
+use warnings;
+
+use File::Basename;
+use Getopt::Long;
+use Pod::Usage;
+
+use v5.10;
+
+parse_commandline();
+
+my $afm = read_afm($ARGV[0]);
+
+# If user specified encoding, use that; else, use encoding from .afm file
+my $enc = $ARGV{encoding} ? read_enc($ARGV{encoding})
+ : get_enc($afm)
+ ;
+# Make lookup table to quickly see if a character is present in the encoding
+my %char_in_enc = map { ($_ => 1) } @{$enc->{vector}};
+
+print_fontinfo($afm->{fontinfo}, $enc->{scheme});
+print_charmetrics($afm->{metrics}, $enc->{vector});
+print_kerndata($afm->{kernpairs}, $afm->{trackkerns}, \%char_in_enc);
+print_composites($afm->{composites}, \%char_in_enc);
+print "EndFontMetrics\n";
+
+close select *STDOUT if $ARGV{output};
+
+print_mapentry($afm->{fontinfo}, , $enc->{scheme})
+ if $ARGV{encoding} && $ARGV{output};
+
+#-----------------------------------------------------------------------
+#
+#-----------------------------------------------------------------------
+sub parse_commandline {
+ Getopt::Long::GetOptions(
+ 'help|?' => sub { pod2usage(-verbose => 1) },
+ 'encoding=s' => \$ARGV{encoding},
+ 'output=s' => \$ARGV{output},
+ )
+ or pod2usage(-verbose => 0);
+
+ pod2usage(-verbose => 0) if @ARGV != 1;
+
+ if ($ARGV{output}) {
+ $ARGV{output} .= '.afm' unless $ARGV{output} =~ m/[.]afm\z/xms;
+ open my $output, '>', $ARGV{output}
+ or die "[ERROR] can't open '$ARGV{output}': $!";
+ select $output;
+ }
+
+ return;
}
-if ((chop($fn = `kpsewhich $ARGV[0] 2>&1`) and -e $fn) or
- (chop($fn = `findtexmf $ARGV[0] 2>&1`) and -e $fn))
-{
- open AFM, "<$fn" or die "Error: can't open `$fn' - $!\n";
-}
-else {
- open AFM, "<$ARGV[0]" or
- die "Error: can't open `$ARGV[0]' - $!\n";
+#-----------------------------------------------------------------------
+#
+#-----------------------------------------------------------------------
+sub read_afm {
+ my $filename = shift;
+ open my $afmfile, '<', $filename
+ or die "[ERROR] can't open '$filename': $!";
+
+ my %afm = (
+ fontinfo => [],
+ metrics => [],
+ kernpairs => [],
+ trackkerns => [],
+ composites => [],
+ );
+
+ until ((my $line = <$afmfile>) =~ m/StartCharMetrics/xms) {
+ push @{$afm{fontinfo}}, $line;
+ }
+
+ for (<$afmfile>) {
+ when (m/\A\s* C \s/xms) { push @{$afm{metrics}}, $_ }
+ when (m/\A\s* KPX \s/xms) { push @{$afm{kernpairs}}, $_ }
+ when (m/\A\s* TrackKern \s/xms) { push @{$afm{trackkerns}}, $_ }
+ when (m/\A\s* CC \s/xms) { push @{$afm{composites}}, $_ }
+ }
+
+ close $afmfile;
+
+ return \%afm;
}
-{
- local $/;
- $_ = <AFM>;
+
+#-----------------------------------------------------------------------
+# Get encoding name and vector from the specified .enc file
+#-----------------------------------------------------------------------
+sub read_enc {
+ my $filename = shift;
+
+ open my $encfile, '<', $filename
+ or die "[ERROR] can't open '$filename': $!";
+ my $data = join ' ', map { s/%.+|\n//xmsg; $_ } <$encfile>;
+ close $encfile;
+
+ my ($scheme, $encoding)
+ = $data =~ m{ /([-\w]+) \s* [[] (.+) []] \s* def }xms
+ or die "[ERROR] parsing encoding file '$filename' failed";
+
+ return { scheme => $scheme,
+ vector => [ $encoding =~ m{ /([.\w]+) }xmsg ],
+ };
}
-$Time = localtime;
-$FontInfo = /(.*)StartCharMetrics/s ? $1 : "";
-$FontInfo =~ s/(?<=Comment ).*?$/Reencoded at $Time by $0 from $ARGV[0]/m;
-$FontInfo =~ s/(?<=ItalicAngle )([\d.]+)/{$1 >= 32768 ? $1 - 65536 : $1}/me;
-$FontInfo =~ s/\r+\n/\n/g;
-if ($FontInfo =~ /FontName\s+([\w-]+)/) {$FontName = $1}
-else {warn "Warning: no FontName found in file `$ARGV[0]'\n"}
-
-for (/(WX.*?$)/gm) {/N\s+([\w.]+)/ and $WX{$1} = $_}
-for (/(KPX.*?$)/gm) {/\s+([\w.]+)\s+([\w.]+)\s+(-?\d+)/ and $KPX{$1}{$2} = $3}
-
-if ((chop($fn = `kpsewhich $options{e} 2>&1`) and -e $fn) or
- (chop($fn = `findtexmf $options{e} 2>&1`) and -e $fn))
-{
- open ENC, "<$fn" or die "Error: can't open `$fn' - $!\n";
-}
-else {
- open ENC, "<$options{e}" or
- die "Error: can't open `$options{e}' - $!\n";
+#-----------------------------------------------------------------------
+# Get encoding from the input .afm file
+#-----------------------------------------------------------------------
+sub get_enc {
+ my $afm = shift;
+
+ my %enc = ( scheme => 'FontSpecific', vector => [ ('/.undef') x 256 ] );
+
+ for my $line (@{$afm->{fontinfo}}) {
+ if ($line =~ m/EncodingScheme \s+ ([-\w]+)/xms) {
+ $enc{scheme} = $1;
+ last;
+ }
+ }
+ for my $line (@{$afm->{metrics}}) {
+ my ($pos, $name)
+ = $line =~ m/C \s+ ([-]?\d+) .+? N \s+ ([.\w]+)/xms
+ or die;
+ $enc{vector}[$pos] = $name unless $pos == -1;
+ }
+
+ return \%enc;
}
-chop(@lines = <ENC>);
-map s!%.*!!, @lines;
-$_ = join "", @lines;
-($n, $_) = m!/([\w-]+) \s* \[(.*)\] \s+ def!x;
-@vector = m!([\w.]+)!g;
-
-for $i (0 .. $#vector) {
- next if $vector[$i] eq ".notdef";
- if ($WX{$vector[$i]} =~ /WX\s+(-?\d+).*?N\s+([\w.]+).*?B\s+(.*?)\s+;/) {
- ($WX, $N, $B) = ($1, $2, $3);
- push @WX, "C $i ; WX $WX ; N $N ; B $B ;\n";
+
+#-----------------------------------------------------------------------
+#
+#-----------------------------------------------------------------------
+sub print_fontinfo {
+ my ($fontinfo, $scheme) = @_;
+
+ for my $line (@$fontinfo) {
+ $line = "EncodingScheme $scheme\n"
+ if $line =~ m/EncodingScheme/xms;
+ print $line;
}
- for $j (0 .. $#vector) {
- next if $vector[$j] eq ".notdef";
- next unless $KPX{$vector[$i]}{$vector[$j]};
- push @KPX,
- "KPX $vector[$i] $vector[$j] $KPX{$vector[$i]}{$vector[$j]}\n";
+
+ return;
+}
+
+#-----------------------------------------------------------------------
+# Print character metrics for characters in specified encoding
+#-----------------------------------------------------------------------
+sub print_charmetrics {
+ my ($metrics, $vector) = @_;
+
+ my %metrics = map { m/(WX .+? N \s+ ([.\w]+) .+)/xms; ($2 => $1) }
+ @$metrics;
+
+ print "StartCharMetrics @{[ scalar grep { $metrics{$_} } @$vector ]}\n";
+ for my $i (0 .. 255) {
+ next unless $metrics{$vector->[$i]};
+ print "C $i ; $metrics{$vector->[$i]}";
}
+ print "EndCharMetrics\n";
+
+ return;
}
-if ($options{o}) {
- ($e = $options{e}) =~ s!.*/!!;
- ($f = $ARGV[0]) =~ s!.*/|\.afm!!g;
- ($o = $options{o}) =~ s!.*/|\.afm!!g;
-
- $x = "pfb";
- for (qw(pfb pfa ttf otf)) {
- if (-e "$f.$_" or
- (chop($fn = `kpsewhich "$f.$_" 2>&1`) and -e $fn) or
- (chop($fn = `findtexmf "$f.$_" 2>&1`) and -e $fn))
- {
- $x = $_;
- last;
- }
+#-----------------------------------------------------------------------
+# Print kerning data for characters in specified encoding
+#-----------------------------------------------------------------------
+sub print_kerndata {
+ my ($kernpairs, $trackkerns, $char_in_enc) = @_;
+
+ my @kernpairs = grep { m/\A\s* KPX \s+ ([.\w]+) \s+ ([.\w]+)/xms
+ and $char_in_enc->{$1}
+ and $char_in_enc->{$2}
+ }
+ @$kernpairs;
+
+ if (@kernpairs || @$trackkerns) {
+ print "StartKernData\n";
+ if (@kernpairs) {
+ print "StartKernPairs @{[ scalar @kernpairs ]}\n";
+ print @kernpairs;
+ print "EndKernPairs\n";
+ }
+ if (@$trackkerns) {
+ print "StartTrackKern @{[ scalar @$trackkerns ]}\n";
+ print @$trackkerns;
+ print "EndTrackKern\n";
+ }
+ print "EndKernData\n";
}
- print qq($o $FontName <$f.$x <[$e "$n ReEncodeFont"\n);
-
- if (open OUT, ">$options{o}") {
- select OUT;
+
+ return;
+}
+
+#-----------------------------------------------------------------------
+# Print "composite" info for characters in specified encoding
+#-----------------------------------------------------------------------
+sub print_composites {
+ my ($composites, $char_in_enc) = @_;
+
+ # Each line mentions several characters: the composite and two or more
+ # 'base' characters. We only print the line if all characters are
+ # present in the specified encoding
+ my @composites;
+ COMPOSITE:
+ for my $composite (@$composites) {
+ my @chars = $composite =~ m/(?:CC \s+ ([.\w]+))/xmsg;
+ for my $char (@chars) {
+ next COMPOSITE unless $char_in_enc->{$char};
+ }
+ push @composites, $composite;
}
- else {
- warn "Warning: can't create `$options{o}' - $!\n",
- " printing to <STDOUT> instead\n";
+
+ if (@composites) {
+ print "StartComposites @{[ scalar @composites ]}\n";
+ print @composites;
+ print "EndComposites\n";
}
+
+ return;
}
-$WX = @WX;
-$KPX = @KPX;
-print <<EOF;
-$FontInfo
-StartCharMetrics $WX
- @{WX}EndCharMetrics
+#-----------------------------------------------------------------------
+#
+#-----------------------------------------------------------------------
+sub print_mapentry {
+ my ($fontinfo, $scheme) = @_;
+
+ my $fontname = '';
+ (my $fontfile = basename($ARGV[0] // '')) =~ s/[.]afm\z//xms;
+ (my $output = basename($ARGV{output} // '')) =~ s/[.]afm\z//xms;
+
+ for my $line (@$fontinfo) {
+ if ($line =~ m/FontName \s+ ([-\w]+)/xms) {
+ $fontname = $1;
+ last;
+ }
+ }
-StartKernData
-StartKernPairs $KPX
- @{KPX}EndKernPairs
-EndKernData
-EndFontMetrics
-EOF
+ print {*STDOUT} qq(${output} ${fontname} <${fontfile}.pfb ),
+ qq(<[$ARGV{encoding} "${scheme} ReEncodeFont"\n);
+
+ return;
+
+}
__END__
+
+############################################################################
+
+ To create the documentation:
+
+ pod2man --center="Marc Penninga" --release="fontools" --section=1 \
+ afm2afm - | groff -Tps -man - | ps2pdf - afm2afm.pdf
+
=pod
=head1 NAME
@@ -118,53 +294,103 @@ afm2afm - reencode an F<afm> file
=head1 SYNOPSIS
-afm2afm B<-e> I<encoding> [B<-o> I<output>] I<afmfile>
+=over 8
+
+=item B<afm2afm>
+
+[B<-help>]
+[B<-encoding> I<encodingfile>]
+[B<-output> I<outputfile>]
+B<afmfile>
+
+=back
+
=head1 DESCRIPTION
-This program reencodes an F<afm> file. It's mainly intended to be used with
-F<afm> files that were extracted from TrueType or OpenType fonts, since these
-are often too big to be handled with tools like F<fontinst> (Adobe's
-CaflischScriptPro-Regular font, for example, contains 1289 glyphs and
-278678 kerning pairs, leading to an F<afm> file of nearly 9MB).
+B<afm2afm> re-encodes an F<afm> file.
+
+Metrics (including kerning data) for characters not present in the
+chosen encoding are excluded from the output, which resuls in
+much smaller files.
-Glyphs that are absent from the chosen encoding aren't written to the output,
-which yields much smaller output files.
+Note that if you don't specify an encoding file, the F<afm> file
+isn't re-encoded, but the unused data is still pruned.
-The program also generates an entry for a F<dvips>-style map file.
+The program also generates an entry for a F<dvips>-style map file,
+but only if the F<afm> file has been re-encoded and
+the output was written to file
+(i.e., if both the I<-encoding> and I<-output> options were specified).
-=head1 OPTIONS
-Option names were chosen to match those of F<ttf2afm>.
+=head1 OPTIONS AND ARGUMENTS
=over 4
-=item B<-e> I<encoding>
+=item B<-help>
-Reencode using the encoding given in file I<encoding>.
+Print a short description of the syntax
-=item B<-o> I<output>
+=item B<-encoding> I<encodingfile>
-Write the reencoded F<afm> to file I<output> instead of C<stdout>.
-The mapfile entry will still be written to C<stdout>.
+Re-encode to the enconding in I<encodingfile>
-=back
+=item B<-output> I<outputfile>
+
+Write the result to I<outputfile> instead of C<stdout>.
-=head1 FILES
+=item B<afmfile>
-All input files are searched using B<kpsewhich> or B<findtexmf> when these
-commands are available; otherwise only the current working directory
-is searched.
+The F<afm> file to be re-encoded.
-=head1 SEE ALSO
+=back
+
+Option names may be shortened to a unique prefix.
-F<autoinst>, F<cmap2enc>, F<font2afm>, F<ot2kpx>, F<pfm2kpx>.
=head1 AUTHOR
-Marc Penninga <marc@penninga.info>
+Marc Penninga <marcpenninga@gmail.com>
+
+
+=head1 COPYRIGHT
+
+Copyright (C) 2005-2012 Marc Penninga.
+
+
+=head1 LICENSE
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published
+by the Free Software Foundation, either version 2 of the License,
+or (at your option) any later version.
+A copy of the GNU General Public License is included with B<autoinst>;
+see the file F<GPLv2.txt>.
+
+
+=head1 DISCLAIMER
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU General Public License for more details.
+
+
+=head1 RECENT CHANGES
+
+(See the source code for the rest of the story.)
+
+=over 12
+
+=item I<2012-02-01>
+
+Refactored the code; added the "no re-encoding, only pruning"
+functionality.
+
+=back
+
-=head1 HISTORY
+=begin Really_old_history
=over 12
@@ -190,8 +416,8 @@ Input files searched using B<kpsewhich> or B<findtexmf> (if available)
=item I<2005-04-15>
-Updated creation of mapfile entry; look for font file to deduce the correct
-font file format (pfb, pfa, ttf). If no font file is found,
+Updated creation of mapfile entry; look for font file to deduce the correct
+font file format (pfb, pfa, ttf). If no font file is found,
pfb is assumed.
=item I<2005-04-20>
diff --git a/Build/source/texk/texlive/linked_scripts/fontools/autoinst b/Build/source/texk/texlive/linked_scripts/fontools/autoinst
index d9b0665ebf1..52fe14b65b4 100755
--- a/Build/source/texk/texlive/linked_scripts/fontools/autoinst
+++ b/Build/source/texk/texlive/linked_scripts/fontools/autoinst
@@ -4,13 +4,12 @@
----------------------------------------------------------------------------
- Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011 Marc Penninga.
+ Copyright (C) 2005-2012 Marc Penninga.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License
- as published by the Free Software Foundation,
- either version 2 of the License, or (at your option)
- any later version.
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 2
+ of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -18,11 +17,11 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to
- Free Software Foundation, Inc.,
- 59 Temple Place,
- Suite 330,
- Boston, MA 02111-1307,
+ along with this program; if not, write to
+ Free Software Foundation, Inc.,
+ 59 Temple Place,
+ Suite 330,
+ Boston, MA 02111-1307,
USA
----------------------------------------------------------------------------
@@ -34,114 +33,107 @@
use strict;
use warnings;
-use Getopt::Long;
+use File::Path ();
+use File::Spec ();
+use Getopt::Long ();
+my ($d, $m, $y) = (localtime time)[3 .. 5];
+my $TODAY = sprintf "%04d/%02d/%02d", $y + 1900, $m + 1, $d;
-my $USAGE =<<'END_USAGE';
-
-'autoinst' is a wrapper around Eddie Kohler's TypeTools
-(http://www.lcdf.org/type/), for installing OpenType fonts in LaTeX.
-
-Usage: autoinst [options] font[s]
-
-Possible options:
- --encoding=ENC[,ENC] Use ENC as text encoding(s) (default: LY1)
-
- --(no)ts1 Toggle creation of TS1 fonts
- --(no)smallcaps Toggle creation of smallcaps shape
- --(no)swash Toggle creation of swash shape
- --(no)titling Toggle creation of titling shape
- --(no)superiors Toggle creation of fonts with superior characters
- --(no)inferiors Toggle creation of fonts with inferior characters
- --(no)ornaments Toggle creation of ornament fonts
- --(no)fractions Toggle creation of fonts with digits for fractions
-
- --sanserif Install font as sanserif font
- --typewriter Install font as typewriter font
- --manual Manual mode (see documentation)
- --extra="TEXT" Add TEXT to the command line for 'otftotfm'
-
- --help Print this text
- --verbose Make some noise
-
- font[s] The fonts (either .otf or .ttf) to install.
-
-Please report any bugs or suggestions to <marc@penninga.info>.
-END_USAGE
+=begin Comment
+ The next three tables map the names of weights, widths and shapes
+ to NFSS codes. New entries can be added, but the names should be
+ all lowercase. Also make sure that the NFSS 'series' attribute
+ (the concatenation of weight and width) is unique!
-=begin Comment
+ The 'book' and 'regular' weights and the 'regular' width are mapped
+ to an empty string rather than 'm', because the 'm' disappears when
+ weight and width are combined into the NFSS series (unless *both* are
+ 'regular', but we deal with that case separately).
- The next three tables map the names of weights, widths and shapes
- to NFSS codes. New entries can be added without problems,
- as long as the name is in all lowercase.
- The 'book' and 'regular' weights and the 'regular' width are mapped
- to an empty string rather than 'm', because the 'm' disappears when
- weight and width are combined into the NFSS series (unless both are
- 'regular', but we deal with that case later on).
The 'oblique' (aka 'slanted') shape is mapped to 'it' to make things
- easier for ourselves. This means the program will fail for font
- families that have both italic and oblique shapes, but I doubt
+ easier for ourselves. This means the program will fail for
+ font families that have both italic and oblique shapes, but I doubt
whether these exist (apart from Computer Modern, of course).
-
+
=end Comment
=cut
my %FD_WEIGHT = (
- thin => 't',
- ultralight => 'ul',
- extralight => 'el',
- light => 'l',
- book => '',
- regular => '',
- medium => 'mb',
- demibold => 'db',
- semibold => 'sb',
- bold => 'b',
- extrabold => 'eb',
- black => 'a', # Not 'k': that means 'book' in fontname
- extrablack => 'ea',
- heavy => 'h',
- ultra => 'ub',
- ultrabold => 'ub',
- ultrablack => 'ua',
+ thin => 't',
+ ultralight => 'ul',
+ extralight => 'el',
+ light => 'l',
+ book => '',
+ regular => '',
+ medium => 'mb',
+ demibold => 'db',
+ demi => 'db',
+ semibold => 'sb',
+ bold => 'b',
+ extrabold => 'eb',
+ ultra => 'ub',
+ ultrabold => 'ub',
+ black => 'k',
+ extrablack => 'ek',
+ ultrablack => 'uk',
+ heavy => 'h',
+ poster => 'r',
);
my %FD_WIDTH = (
- ultracondensed => 'uc',
- extracondensed => 'ec',
- condensed => 'c',
- cond => 'c',
- semicondensed => 'sc',
- regular => '',
- semiextended => 'sx',
- extended => 'x',
+ ultracompressed => 'up',
+ extracompressed => 'ep',
+ compressed => 'p',
+ comp => 'p',
+ cmp => 'p',
+ compact => 'p',
+ ultracondensed => 'uc',
+ extracondensed => 'ec',
+ condensed => 'c',
+ cond => 'c',
+ narrow => 'n',
+ semicondensed => 'sc',
+ regular => '',
+ semiextended => 'sx',
+ extended => 'x',
+ expanded => 'e',
+ wide => 'w',
);
my %FD_SHAPE = (
- roman => 'n',
- italic => 'it',
- it => 'it', # Fix for (at least) some Linotype fonts
- oblique => 'it',
- slanted => 'it',
- romani => 'n',
- romanii => 'it', # Map one of Silentium Pro's two roman shapes to 'it'
+ roman => 'n',
+ upright => 'n',
+ italic => 'it',
+ ita => 'it',
+ it => 'it',
+ cursive => 'it',
+ kursiv => 'it',
+ inclined => 'it',
+ incline => 'it',
+ oblique => 'it',
+ slanted => 'it',
+ slant => 'it',
+ romani => 'n', # Adobe Silentium Pro has two roman shapes;
+ romanii => 'it', # we map the second one to 'it'
);
+
=begin Comment
- The following tables are used for deciding which font families and shapes
+ The following tables are used in deciding which font families and shapes
to generate. Each hash governs one of these aspects:
- 'figure style' (lining, oldstyle, tabular, proportional, superior,
inferior etc.); each of these will become a separate font family.
- - 'variant' shape (normal, small caps, swash, titling or textcomp).
-
+ - 'shape' (normal, small caps, swash, titling or textcomp).
- Each key in the %FIGURE_STYLE hash names a figure style; the corresponding
+
+ Each key in the %STYLE hash names a figure style; the corresponding
value is an anonymous hash with four key/value pairs:
- reqd A list of required OpenType features;
- this style is built if the font supports at least one
+ reqd A list of required OpenType features;
+ this style is built if the font supports at least *one*
of these features.
nice A list of optional OpenType features;
these are used if the font supports them, but don't
@@ -149,35 +141,35 @@ my %FD_SHAPE = (
extra Extra options passed to otftotfm when creating this style.
shape An anonymous array of 'variant' shapes to build with
this figure style.
-
- Ornaments are treated as a separate 'figure style'.
- This may seem a bit funny, but is actually the easiest way to do it.
-
-
- Each key in the %SHAPE hash names a 'variant' shape; the corresponding
- value is (again) an anonymous hash with several key/value pairs:
+
+ Ornaments are treated as a separate 'figure style'.
+ This may seem a bit weird, but is actually the easiest way to do it.
+
+
+ Each key in the %SHAPE hash names a shape; the corresponding value
+ is (again) an anonymous hash with several key/value pairs:
code An anonymous hash with two possible keys:
'n' -> the NFSS code to use for this variant shape
- if the basic shape is upright;
+ if the 'basic shape' is upright;
'it' -> the NFSS code to use for this variant shape
- if the basic shape is italic, slanted or oblique;
- If the 'n' ('it') entry is missing, the upright (italic)
+ if the 'basic shape' is italic, slanted or oblique;
+ If the 'n' or 'it' entry is missing, the upright or italic
version of this variant shape will not be built.
- reqd A list of required OpenType features;
- this shape is built if the font supports at least one
+ reqd A list of required OpenType features;
+ this shape is built if the font supports at least *one*
of these features.
nice A list of optional OpenType features;
these are used if the font supports them, but don't
prevent this shape from being built when missing.
extra Extra options passed to otftotfm when creating this shape.
- name A string added to the name of the generated font,
+ name A string added to the name of the generated font,
to make it unique.
-
+
=end Comment
=cut
-my %FIGURE_STYLE = (
+my %STYLE = (
TLF => {
reqd => [],
nice => ['lnum', 'tnum'],
@@ -273,329 +265,329 @@ my %SHAPE = (
);
-# The official names
-my %CODING_SCHEME = (
- fontools_ly1 => 'TEX TYPEWRITER AND WINDOWS ANSI',
- fontools_t1 => 'EXTENDED TEX FONT ENCODING - LATIN',
- fontools_ot1 => 'TEX TEXT',
- fontools_ts1 => 'TEX TEXT COMPANION SYMBOLS 1---TS1',
-);
+############################################################################
-# Default values for the command line arguments
-%ARGV = (
- encoding => 'LY1',
- textcomp => '2', # 0 = no, 1 = yes, 2 = (enc eq 'T1' ? yes : no)
- manual => '0', # 0 = no, 1 = yes
- verbose => '0', # 0 = no, 1 = yes
- extra => '',
- nfss => 'rm',
- smallcaps => '1', # 0 = no, 1 = yes
- swash => '1', # 0 = no, 1 = yes
- titling => '0', # 0 = no, 1 = yes
- superiors => '1', # 0 = no, 1 = yes
- inferiors => '0', # 0 = no, 1 = yes
- ornaments => '1', # 0 = no, 1 = yes
- fractions => '0', # 0 = no, 1 = yes
-);
-my @time = localtime;
-my $date = sprintf "%04d/%02d/%02d", $time[5] + 1900, $time[4] + 1, $time[3];
+#-----------------------------------------------------------------------
+# The main routine. What else?
+#-----------------------------------------------------------------------
+sub main {
+ ARGV::parse_options();
+
+ my @fonts = map { Fontinfo::parse_fontinfo($_) } @ARGV;
+ Fontinfo::assert_unique(@fonts);
+
+ # For each font, figure out the shapes, styles and encodings to generate
+ my @worklist
+ = cleanup(expand_encodings(expand_shapes(expand_styles(@fonts))));
+
+ # Organize the worklist by family, encoding, style, series and shape
+ my %fddata;
+ for my $item (@worklist) {
+ my $family = $item->{font}{family};
+ my $encoding = $item->{encoding}[1];
+ my $style = $item->{style};
+ my $series = $item->{font}{fdseries};
+ my $shape = $item->{fdshape};
+ my $minsize = $item->{font}{minsize};
+ my $maxsize = $item->{font}{maxsize};
+
+ push @{$fddata{$family}{$encoding}{$style}{$series}{$shape}},
+ [ $minsize, $maxsize, $item->{fontname} ];
+ }
+ while (my ($fam, $famdata) = each %fddata) {
+ LaTeX::write_stylefile($fam, $famdata);
+ while (my ($enc, $encdata) = each %$famdata) {
+ while (my ($sty, $stydata) = each %$encdata) {
+ LaTeX::write_fdfile($fam, $enc, $sty, $stydata);
+ }
+ }
+ }
-# ----------------------- subroutine definitions -----------------------
+ make_commands(@worklist);
+ return;
+}
-sub main {
- parse_options();
-
- my (%already_seen, %commands, @fd_data, $err_msg);
-
- FONTFILE:
- for my $filename (@ARGV) {
- my %fontinfo = read_font_info($filename);
- my $unique
- = join ',', @fontinfo{qw(family width weight shape min max)};
- if ( $already_seen{$unique}
- and $already_seen{$unique} ne $filename) {
- $err_msg .= <<"END_PARSE_ERROR";
-
-ERROR: I've parsed both '$already_seen{$unique}'
- and '$filename' as
-
- Family $fontinfo{family}
- Width $fontinfo{width}
- Weight $fontinfo{weight}
- Shape $fontinfo{shape}
- Size $fontinfo{min}-$fontinfo{max}
-END_PARSE_ERROR
- }
- else {
- $already_seen{$unique} = $filename;
- }
+#-----------------------------------------------------------------------
+# Determine which figure styles to create for each font;
+# return a list of (font, style) tuples
+#-----------------------------------------------------------------------
+sub expand_styles {
+ return map { my $font = $_;
+ map { { font => $font, style => $_ } }
+ grep { has_reqd($font, $STYLE{$_}) }
+ keys %STYLE
+ }
+ @_;
+}
- FIGURE_STYLE:
- for my $figure_style (keys %FIGURE_STYLE) {
-
- # Does the font support this figure style?
- if ( @{$FIGURE_STYLE{$figure_style}{reqd}}
- and not grep { exists $fontinfo{features}{$_} }
- @{$FIGURE_STYLE{$figure_style}{reqd}} ) {
- next FIGURE_STYLE;
- }
-
- # If so, create all corresponding shapes
- my $basic = $FD_SHAPE{$fontinfo{shape}};
-
- SHAPE:
- for my $shape (@{$FIGURE_STYLE{$figure_style}{shapes}}) {
- next SHAPE if not exists $SHAPE{$shape};
- next SHAPE if not exists $SHAPE{$shape}{code}{$basic};
-
- # Does the font support this shape?
- if ( @{$SHAPE{$shape}{reqd}}
- and not grep { exists $fontinfo{features}{$_} }
- @{$SHAPE{$shape}{reqd}}) {
- next SHAPE;
- }
-
- # Decide which features to use
- my @features = grep { exists $fontinfo{features}{$_} }
- (
- @{$FIGURE_STYLE{$figure_style}{reqd}},
- @{$FIGURE_STYLE{$figure_style}{nice}},
- @{$SHAPE{$shape}{reqd}},
- @{$SHAPE{$shape}{nice}},
- );
-
- # Remove duplicate features
- my %tmp_features;
- for my $f (@features) {
- $tmp_features{$f} = 1;
- }
- if ($tmp_features{onum} && $tmp_features{lnum}) {
- delete $tmp_features{lnum};
- }
- @features = keys %tmp_features;
-
- # Figure out the name and NFSS code for the encodings
- my @encodings;
- if ($shape eq 'textcomp') {
- @encodings = (['fontools_ts1', 'ts1']);
- }
- elsif ($figure_style eq 'Orn') {
- @encodings = ([make_ornament_encoding(%fontinfo), 'u']);
- }
- else {
- @encodings = map { [lc $_, lc $_] } @{$ARGV{encoding}};
- }
+#-----------------------------------------------------------------------
+# Determine which shapes to create for each (font, style) combination;
+# return a list of (font, style, shape) tuples
+#-----------------------------------------------------------------------
+sub expand_shapes {
+ return map { my ($font, $style) = @{$_}{qw(font style)};
+ map { { font => $font, style => $style, shape => $_ } }
+ grep { has_reqd($font, $SHAPE{$_}) }
+ @{$STYLE{$style}{shapes}};
+ }
+ @_;
+}
- ENCODING:
- for my $enc_ref (@encodings) {
- my ($enc_name, $enc_code) = @{$enc_ref};
- $enc_name =~ s/\A (ly1|ot1|t1) \z/fontools_$1/xms;
-
- # Create unique name for this font
- my $fontname = join '-',
- $fontinfo{name},
- lc $figure_style,
- $SHAPE{$shape}{name},
- $enc_code,
- ;
- $fontname =~ s/[-]{2,}/-/xmsg;
-
- # Create the command line for otftotfm
- my $command
- = join ' ',
- 'otftotfm',
- "--encoding=$enc_name",
- ($ARGV{manual} ? '--pl' : '--automatic'),
- "--map-file=$fontinfo{family}.map --no-updmap",
- ($filename =~ m/[.]ttf\z/xms
- ? '--no-type1'
- : ''),
- ($CODING_SCHEME{$enc_name}
- ? "--coding-scheme="
- . "\"$CODING_SCHEME{$enc_name}\""
- : ''),
- (map { "--feature=$_" } @features),
- # if there's no 'liga' feature,
- # add ligkern commands for common ligatures
- ((grep { $_ eq 'liga' } @features)
- ? ''
- : '--ligkern="f i =: fi" '
- . '--ligkern="f l =: fl" '
- . '--ligkern="f f =: ff" '
- . '--ligkern="ff i =: ffi" '
- . '--ligkern="ff l =: ffl" '),
- $FIGURE_STYLE{$figure_style}{extra},
- $SHAPE{$shape}{extra},
- $ARGV{extra},
- '"' . $filename . '"',
- $fontname,
- ;
-
- # Save the command and the necessary data for .fd files
- push @{$commands{$fontinfo{family}}}, $command;
- push @fd_data,
- join '|',
- $fontinfo{family},
- uc $enc_code,
- $figure_style,
- $FD_WEIGHT{$fontinfo{weight}}
- . $FD_WIDTH{$fontinfo{width}}
- || 'm',
- $SHAPE{$shape}{code}{$basic},
- sprintf("%04.1f",$fontinfo{min}),
- sprintf("%04.1f",$fontinfo{max}),
- $fontname,
- ;
-
- if ($ARGV{verbose}) {
- printf " %-42s %4s/%s-%s/%s/%s\n",
- $fontname,
- uc $enc_code,
- $fontinfo{family},
- $figure_style,
- $FD_WEIGHT{$fontinfo{weight}}
- .$FD_WIDTH{$fontinfo{width}}
- || 'm',
- $SHAPE{$shape}{code}{$basic},
- ;
- }
- }
- }
- }
- }
+#-----------------------------------------------------------------------
+# Check if $font has (at least one of the) features mentioned in the
+# 'reqd' subtable of $target
+#-----------------------------------------------------------------------
+sub has_reqd {
+ my ($font, $target) = @_;
- # If parsing failed, flush STDOUT, print the error messages and die
- if (defined $err_msg) {
- close STDOUT;
- die $err_msg . <<'END_GENERAL_PARSE_ERROR';
-
-
-I suspect your font family contains some unusual weights or widths.
-You might try adding missing widths and weights to the tables
-'%FD_WIDTH' and '%FD_WEIGHT' at the beginning of the source code;
-otherwise, please send a bug report to <marc@penninga.info>.
-END_GENERAL_PARSE_ERROR
- }
-
- @fd_data = sort @fd_data;
-
- for my $fd_line (@fd_data) {
- my @fd_line = split /[|]/, $fd_line;
- $fd_line[5] += 0;
- $fd_line[6] += 0;
- $fd_line = \@fd_line;
- }
-
- # Adjust size ranges
- $fd_data[0][5] = '';
- for my $i (0 .. $#fd_data - 1) {
- if (grep { $fd_data[$i][$_] ne $fd_data[$i + 1][$_] } 0 .. 4) {
- $fd_data[$i][6] = $fd_data[$i + 1][5] = '';
- }
- else {
- $fd_data[$i][6] = $fd_data[$i + 1][5];
- }
- }
- $fd_data[-1][6] = '';
-
- # Generate .fd files
- my @fd_prev = ('') x 8;
- my $FD;
- for my $fd_line_ref (@fd_data) {
- my @fd_line = @{$fd_line_ref};
-
- my $safe = $fd_line[0];
- $safe =~ s/1/One/xmsg;
- $safe =~ s/2/Two/xmsg;
- $safe =~ s/3/Three/xmsg;
- $safe =~ s/4/Four/xmsg;
- $safe =~ s/5/Five/xmsg;
- $safe =~ s/6/Six/xmsg;
- $safe =~ s/7/Seven/xmsg;
- $safe =~ s/8/Eight/xmsg;
- $safe =~ s/9/Nine/xmsg;
- $safe =~ s/0/Zero/xmsg;
-
- write_style_file($fd_line[0], $safe, @fd_data)
- if $fd_line[0] ne $fd_prev[0];
-
- if (grep { $fd_line[$_] ne $fd_prev[$_] } 0 .. 2) {
- end_fd_file($FD) if $fd_prev[0];
- $FD = start_fd_file(@fd_line[0 .. 2], $safe);
- }
-
- if (grep { $fd_line[$_] ne $fd_prev[$_] } 0 .. 4) {
- # Start new fontshape
- if (not grep { $fd_line[$_] ne $fd_prev[$_] } 0 .. 2) {
- print {$FD} "}{}\n\n";
+ return 0 unless defined $target;
+ return 1 unless @{$target->{reqd}};
+ return grep { $font->{feature}{$_} } @{$target->{reqd}};
+}
+
+#-----------------------------------------------------------------------
+# Determine which encodings to use for each (font, style, shape) combi;
+# return a list of (font, style, shape, encoding) tuples
+#-----------------------------------------------------------------------
+sub expand_encodings {
+ return
+ map { my ($font, $style, $shape) = @{$_}{qw(font style shape)};
+ my @encodings
+ = $shape eq 'textcomp' ? (['fontools_ts1', 'ts1'])
+ : $style eq 'Orn' ? ([Fontinfo::get_orn($font), 'u'])
+ : map { [lc $_, lc $_] } @{$ARGV{encoding}}
+ ;
+ map { { font => $font,
+ style => $style,
+ shape => $shape,
+ encoding => $_,
+ }
+ }
+ @encodings;
}
- printf {$FD} "\\DeclareFontShape{%s}{%s-%s}{%s}{%s}{\n",
- @fd_line[1, 0, 2, 3, 4];
+ @_;
+}
+
+#-----------------------------------------------------------------------
+# Add some finishing touches to the work list
+#-----------------------------------------------------------------------
+sub cleanup {
+ my @worklist = @_;
+
+ for my $item (@worklist) {
+ my ($font, $style, $shape, $encoding)
+ = @{$item}{qw(font style shape encoding)};
+
+ # generate unique name for this font
+ $item->{fontname} = join '-', grep { $_ } $font->{name},
+ lc $style,
+ lc $SHAPE{$shape}{name},
+ lc $encoding->[1];
+
+ # look up NFSS code for font's shape
+ $item->{fdshape}
+ = $SHAPE{$shape}{code}{$font->{basicshape}};
+
+ # compile list of OpenType features to use with this font
+ my %feature = map { ($_ => 1) }
+ grep { $font->{feature}{$_} }
+ ( @{$STYLE{$style}{reqd}},
+ @{$STYLE{$style}{nice}},
+ @{$SHAPE{$shape}{reqd}},
+ @{$SHAPE{$shape}{nice}},
+ );
+ if ($feature{lnum} && $feature{onum}) {
+ delete $feature{lnum};
}
-
- # Write fontshape entry
- printf {$FD} " %s \\%s\@\@scale %s\n",
- sprintf("%5s-%-5s", '<' . $fd_line[5], $fd_line[6] . '>'),
- $safe,
- $fd_line[7],
- ;
-
- @fd_prev = @fd_line;
+ $item->{features} = [ sort keys %feature ];
+
+ # add finishing touches to name and NFSS code of encoding
+ $item->{encoding}[0] =~ s/\A (ot1|t1|ly1) \z/fontools_$1/xms;
+ $item->{encoding}[1] = uc $item->{encoding}[1];
}
-
- end_fd_file($FD) if $fd_prev[0];
- # Print or execute the generated commands
+ return @worklist;
+}
+
+#-----------------------------------------------------------------------
+# Generate all otftotfm commands, and either save or execute them
+#-----------------------------------------------------------------------
+sub make_commands {
+ my @worklist = @_;
+
+ my @commands = map { make_cmdline($_) } @worklist;
+
+ # make sure the last command *does* call updmap
+ $commands[-1] =~ s/--no-updmap//xms;
+
if ($ARGV{manual}) {
- while (my ($fam, $cmds_ref) = each %commands) {
- open my $BAT, '>', "$fam.bat"
- or die "ERROR: can't create '$fam.bat' - $!";
- print {$BAT} "$_\n" for @{$cmds_ref};
- close $BAT;
- }
+ open my $BAT, '>', 'autoinst.bat'
+ or die "[ERROR] Can't create 'autoinst.bat': $!";
+ print {$BAT} "$_\n" for @commands;
+ close $BAT;
}
else {
- # Remove the --no-updmap option from the last command for each family
- map { $_->[-1] =~ s/--no-updmap//xms } values %commands;
-
- for my $cmds_ref (values %commands) {
- for my $cmd (@{$cmds_ref}) {
- print "$cmd\n";
- system $cmd and warn <<'END_OTFTOTFM_WARNING';
-
-WARNING: 'otftotfm' finished with a non-zero return code;
- I'm afraid something went wrong!
-
-END_OTFTOTFM_WARNING
- }
+ if (grep { system $_ } @commands) {
+ warn "[WARNING] 'otftotfm' returned non-zero; something's wrong!";
}
}
+
+ return;
+}
+
+# The official names for various coding schemes
+my %SCHEME = (
+ fontools_ly1 => 'TEX TYPEWRITER AND WINDOWS ANSI',
+ fontools_t1 => 'EXTENDED TEX FONT ENCODING - LATIN',
+ fontools_ot1 => 'TEX TEXT',
+ fontools_ts1 => 'TEX TEXT COMPANION SYMBOLS 1---TS1',
+);
+
+#-----------------------------------------------------------------------
+# Generate a command line for otftotfm
+#-----------------------------------------------------------------------
+sub make_cmdline {
+ my $item = shift;
+
+ return join ' ', 'otftotfm',
+ ($ARGV{manual} ? '--pl' : '--automatic'),
+ "--encoding=$item->{encoding}[0]",
+ set_targetdirs($item->{font}{family}),
+ '--no-updmap',
+ ($item->{font}{filename} =~ m/[.]ttf\z/xms
+ ? '--no-type1'
+ : ''),
+ ($SCHEME{$item->{encoding}[0]}
+ ? qq(--coding-scheme="$SCHEME{$item->{encoding}[0]}")
+ : ''),
+ (map { "--feature=$_" } @{$item->{features}}),
+ ((grep { $_ eq 'liga' } @{$item->{features}})
+ ? ''
+ : ( '--ligkern="f i =: fi"',
+ '--ligkern="f l =: fl"',
+ '--ligkern="f f =: ff"',
+ '--ligkern="ff i =: ffi"',
+ '--ligkern="ff l =: ffl"' )),
+ $STYLE{$item->{style}}{extra},
+ $SHAPE{$item->{shape}}{extra},
+ $ARGV{extra},
+ qq("$item->{font}{filename}"),
+ $item->{fontname},
+ ;
+}
+
+#-----------------------------------------------------------------------
+# Return a string with all "directory" options for otftotfm set
+#-----------------------------------------------------------------------
+sub set_targetdirs {
+ my $family = shift;
+
+ my %dir = map { ($_ => File::Spec->catdir(
+ $ARGV{target}, 'fonts', $_, 'lcdftools', $family))
+ }
+ qw(tfm vf pl vpl type1 truetype type42);
+
+ $dir{$_} = File::Spec->catdir(
+ $ARGV{target}, 'fonts', $_, 'dvips', 'lcdftools')
+ for qw(enc map);
+
+ File::Path::make_path(values %dir);
+
+ my $result = join ' ', map { "--${_}-directory=$dir{$_}" }
+ qw(tfm vf pl vpl type1 truetype type42);
+ $result .= " --encoding-directory=$dir{enc} --map-file="
+ . File::Spec->catfile($dir{map}, "${family}.map");
+
+ return $result;
}
-# ------------------------------------------------------------------------
+############################################################################
+
+
+package ARGV;
+
+my $USAGE =<<'END_USAGE';
+
+'autoinst' is a wrapper around Eddie Kohler's TypeTools
+(http://www.lcdf.org/type/), for installing OpenType fonts in LaTeX.
+
+Usage: autoinst [options] font[s]
+
+Possible options:
+ -encoding=ENC[,ENC]* Specify text encoding(s) (default: OT1,T1,LY1)
+
+ -(no)ts1 Toggle creation of TS1 fonts
+ -(no)smallcaps Toggle creation of smallcaps shape
+ -(no)swash Toggle creation of swash shape
+ -(no)titling Toggle creation of titling shape
+ -(no)superiors Toggle creation of fonts with superior characters
+ -(no)inferiors Toggle creation of fonts with inferior characters
+ -(no)ornaments Toggle creation of ornament fonts
+ -(no)fractions Toggle creation of fonts with digits for fractions
+
+ -sanserif Install font as sanserif font
+ -typewriter Install font as typewriter font
+ -extra="TEXT" Add TEXT to the command line for 'otftotfm'
+ -target="DIRECTORY" Install files into specified TEXMF tree
+ -manual Manual mode (see documentation)
+
+ -(no)figurekern Keep or remove kerns between tabular figures
+
+ -help Print this text
+ -verbose Make some noise
+
+ font[s] The fonts (either .otf or .ttf) to install.
+
+Please report any bugs or suggestions to <marcpenninga@gmail.com>.
+END_USAGE
+
+# Default values for the command-line arguments
+%ARGV = (
+ encoding => 'OT1,T1,LY1',
+ textcomp => '2', # 0 = no, 1 = yes, 2 = (enc eq 'T1' ? yes : no)
+ smallcaps => '1', # 0 = no, 1 = yes
+ swash => '1', # 0 = no, 1 = yes
+ titling => '1', # 0 = no, 1 = yes
+ superiors => '1', # 0 = no, 1 = yes
+ inferiors => '0', # 0 = no, 1 = yes
+ ornaments => '1', # 0 = no, 1 = yes
+ fractions => '0', # 0 = no, 1 = yes
+ nfss => 'rm',
+ extra => '',
+ target => '',
+ manual => '0', # 0 = no, 1 = yes
+ verbose => '0', # 0 = no, 1 = yes
+ figurekern => '1', # 0 = no, 1 = yes
+);
+
+#-----------------------------------------------------------------------
+# Process command-line arguments
+#-----------------------------------------------------------------------
sub parse_options {
my $cmdline = "$0 " . join ' ', @ARGV;
-
- GetOptions(
- 'help' => sub { print $USAGE; exit },
- 'encoding=s' => \$ARGV{encoding},
- 'ts1!' => \$ARGV{textcomp},
- 'manual' => \$ARGV{manual},
- 'verbose' => \$ARGV{verbose},
- 'extra=s' => \$ARGV{extra},
- 'sanserif' => sub { $ARGV{nfss} = 'sf' },
- 'typewriter' => sub { $ARGV{nfss} = 'tt' },
- 'smallcaps!' => \$ARGV{smallcaps},
- 'swash!' => \$ARGV{swash},
- 'titling!' => \$ARGV{titling},
- 'superiors!' => \$ARGV{superiors},
- 'inferiors!' => \$ARGV{inferiors},
- 'ornaments!' => \$ARGV{ornaments},
- 'fractions!' => \$ARGV{fractions},
+
+ Getopt::Long::GetOptions(
+ 'help|?' => sub { print $USAGE; exit; },
+ 'encoding=s' => \$ARGV{encoding},
+ 'ts1!' => \$ARGV{textcomp},
+ 'smallcaps!' => \$ARGV{smallcaps},
+ 'swash!' => \$ARGV{swash},
+ 'titling!' => \$ARGV{titling},
+ 'superiors!' => \$ARGV{superiors},
+ 'inferiors!' => \$ARGV{inferiors},
+ 'ornaments!' => \$ARGV{ornaments},
+ 'fractions!' => \$ARGV{fractions},
+ 'sanserif' => sub { $ARGV{nfss} = 'sf' },
+ 'typewriter' => sub { $ARGV{nfss} = 'tt' },
+ 'extra=s' => \$ARGV{extra},
+ 'target=s' => \$ARGV{target},
+ 'manual' => \$ARGV{manual},
+ 'figurekern!' => \$ARGV{figurekern},
+ 'verbose' => \$ARGV{verbose},
)
or die "$USAGE";
@@ -605,33 +597,57 @@ sub parse_options {
if (!$ARGV{swash} ) { delete $SHAPE{swash} }
if (!$ARGV{titling} ) { delete $SHAPE{titling} }
- if (!$ARGV{superiors}) { delete $FIGURE_STYLE{Sup} }
- if (!$ARGV{inferiors}) { delete $FIGURE_STYLE{Inf} }
- if (!$ARGV{ornaments}) { delete $FIGURE_STYLE{Orn} }
- if (!$ARGV{fractions}) { delete @FIGURE_STYLE{qw(Numr Dnom)} }
-
+ if (!$ARGV{superiors}) { delete $STYLE{Sup} }
+ if (!$ARGV{inferiors}) { delete $STYLE{Inf} }
+ if (!$ARGV{ornaments}) { delete $STYLE{Orn} }
+ if (!$ARGV{fractions}) { delete @STYLE{qw(Numr Dnom)} }
+
$ARGV{encoding} =~ s/\s+//xmsg;
my @textencodings = grep { $_ ne 'TS1' }
- map { uc }
+ map { uc }
split /,/, $ARGV{encoding};
$ARGV{encoding} = \@textencodings;
# TS1-encoded fonts are generated if:
- # - text encoding is T1 and the user didn't turn off TS1, or
- # - the user explicitly asked for TS1
- if (
- !( (grep { $_ eq 'T1' } @{$ARGV{encoding}} and $ARGV{textcomp})
- or $ARGV{textcomp} == 1
- )) {
+ # - the user explicitly asked for TS1, or
+ # - the text encodings contain T1 and the user didn't turn off TS1
+ unless ( (grep { $_ eq 'T1' } @{$ARGV{encoding}} and $ARGV{textcomp})
+ or $ARGV{textcomp} == 1)
+ {
delete $SHAPE{textcomp};
}
-
+
+ if ($ARGV{manual}) {
+ warn "[WARNING] option '--target' overridden by '--manual'!"
+ if $ARGV{target};
+ $ARGV{target} = File::Spec->curdir();
+ }
+ elsif (not $ARGV{target}) {
+ my @dirs = grep { -w $_ }
+ map { split m/:/xms, substr $_, 0, -1 }
+ ( `kpsewhich --expand-path='\$TEXMFLOCAL'`,
+ `kpsewhich --expand-path='\$TEXMFHOME'`, );
+ $ARGV{target} = $dirs[0] || File::Spec->curdir();
+ }
+
+ if (!$ARGV{figurekern}) {
+ my @digits = qw(zero one two three four five six seven eight nine);
+ my $tkern
+ = join ' ', map { my $left = $_;
+ map { qq(--ligkern="$left {} $_") } @digits
+ }
+ @digits;
+
+ $STYLE{TLF}{extra} = $tkern;
+ $STYLE{TOsF}{extra} = $tkern;
+ }
+
if ($ARGV{verbose}) {
print <<"END_ARGUMENTS";
$cmdline
-
+
I'm using the following options:
encoding(s): @{[ join ', ', @{$ARGV{encoding}} ]}
@@ -639,279 +655,379 @@ I'm using the following options:
: $ARGV{nfss} eq 'sf' ? '(sanserif)'
: $ARGV{nfss} eq 'tt' ? '(typewriter)'
: '(unknown)'
- ]}
+ ]}
+
+ (no)ts1: @{[ $SHAPE{textcomp} ? 'ts1' : 'nots1' ]}
+ (no)smallcaps: @{[ $ARGV{smallcaps} ? 'smallcaps' : 'nosmallcaps' ]}
+ (no)swash: @{[ $ARGV{swash} ? 'swash' : 'noswash' ]}
+ (no)titling: @{[ $ARGV{titling} ? 'titling' : 'notitling' ]}
+ (no)superiors: @{[ $ARGV{superiors} ? 'superiors' : 'nosuperiors' ]}
+ (no)inferiors: @{[ $ARGV{inferiors} ? 'inferiors' : 'noinferiors' ]}
+ (no)ornaments: @{[ $ARGV{ornaments} ? 'ornaments' : 'noornaments' ]}
+ (no)fractions: @{[ $ARGV{fractions} ? 'fractions' : 'nofractions' ]}
- (no)ts1: @{[ $SHAPE{textcomp} ? 'ts1' : 'nots1' ]}
- (no)smallcaps: @{[ $ARGV{smallcaps} ? 'smallcaps' : 'nosmallcaps' ]}
- (no)swash: @{[ $ARGV{swash} ? 'swash' : 'noswash' ]}
- (no)titling: @{[ $ARGV{titling} ? 'titling' : 'notitling' ]}
- (no)superiors: @{[ $ARGV{superiors} ? 'superiors' : 'nosuperiors' ]}
- (no)inferiors: @{[ $ARGV{inferiors} ? 'inferiors' : 'noinferiors' ]}
- (no)ornaments: @{[ $ARGV{ornaments} ? 'ornaments' : 'noornaments' ]}
- (no)fractions: @{[ $ARGV{fractions} ? 'fractions' : 'nofractions' ]}
+ verbosity: @{[ $ARGV{verbose} ? 'verbose' : 'quiet' ]}
+ target: $ARGV{target}
+ auto/manual: @{[ $ARGV{manual} ? 'manual' : 'automatic' ]}
extra: @{[ $ARGV{extra} || 'empty' ]}
- auto/manual: @{[ $ARGV{manual} ? 'manual' : 'automatic' ]}
- verbosity: @{[ $ARGV{verbose} ? 'verbose' : 'silent' ]}
+ figurekern: @{[ $ARGV{figurekern} ? 'keep' : 'discard' ]}
END_ARGUMENTS
}
}
-# ------------------------------------------------------------------------
-
-sub read_font_info {
- my ($fontfile) = @_;
-
- my %info = ();
-
- # Read some general info about the font
- open my $OTFINFO, '-|', "otfinfo --info \"$fontfile\""
- or die "ERROR: 'otfinfo --info \"$fontfile\"' failed";
-
- LINE:
- for my $line (<$OTFINFO>) {
- my ($key, $val) = $line =~ m/([^:]+) :\s* ([^\n]+)/xms
- or next LINE;
- $val =~ s/[^-\w]//xmsg;
- $info{$key} = $val;
- }
- close $OTFINFO;
- if ($info{Family} =~ m/\A (.+ (?: OT | Pro))/xms) {
- $info{Family} = $1;
+############################################################################
+
+
+package Fontinfo;
+
+#-----------------------------------------------------------------------
+# Return ref to hash with all relevant info about this font
+#-----------------------------------------------------------------------
+sub parse_fontinfo {
+ my ($filename) = @_;
+
+ my $info = {
+ filename => $filename,
+ width => 'regular',
+ weight => 'regular',
+ shape => 'roman',
+ minsize => 0,
+ maxsize => 0,
+ };
+
+ parse_basicinfo($info);
+ parse_sizeinfo($info);
+ parse_features($info);
+
+ if ($ARGV{verbose}) {
+ print <<"END_FONTINFO";
+$info->{filename}
+ Name: $info->{name}
+ Family: $info->{family}
+ Subfamily: $info->{subfamily}
+ Width: $info->{width}
+ Weight: $info->{weight}
+ Shape: $info->{shape}
+ Size: $info->{minsize}-$info->{maxsize}
+ Features: @{[ join ', ', sort keys %{$info->{feature}} ]}
+
+END_FONTINFO
}
-
- $info{'Full name'} =~ s/$info{Family}//xmsg;
- $info{'Full name'} = lc $info{'Full name'};
- $info{Family} =~ s/\A (?: Adobe | ITC ) | LT | MT//xmsg;
-
- # Set default
- my %fontinfo = (
- filename => $fontfile,
- name => $info{'PostScript name'},
- family => $info{Family},
- width => 'regular',
- weight => 'regular',
- shape => 'roman',
- min => 0,
- max => 0,
- features => {},
- );
-
- # Try to match width, weight and (basic) shape
- WIDTH:
- for my $width (map { quotemeta }
- reverse sort
- { length($a) <=> length($b) || $a cmp $b }
- keys %FD_WIDTH)
- {
- if ($info{'Full name'} =~ s/$width//xmsi) {
- $fontinfo{width} = $width;
- last WIDTH;
+
+ return $info;
+}
+
+# table for converting digits in font names to text (safer for LaTeX)
+my @DIGITS = qw(Zero One Two Three Four Five Six Seven Eight Nine);
+
+#-----------------------------------------------------------------------
+# Get some basic info (family, weight, width, shape) about this font
+#-----------------------------------------------------------------------
+sub parse_basicinfo {
+ my $info = shift;
+
+ open my $otfinfo, '-|', qq(otfinfo --info "$info->{filename}")
+ or die "[ERROR] 'otfinfo --info $info->{filename}' failed";
+ my %data = map { my ($k,$v) = m/\A\s* ([^:]+?) \s*:\s* ([^\r\n]+)/xms;
+ $k =~ s/\s+//xmsg;
+ $v =~ s/\s+//xmsg;
+ (lc $k => $v);
+ }
+ grep { m/\A\s* [^:]+? \s*:\s* [^\r\n]+/xms } <$otfinfo>;
+ close $otfinfo;
+
+ $data{family} = $data{preferredfamily} || $data{family};
+ $data{subfamily} = $data{preferredsubfamily} || $data{subfamily};
+ $data{fullname} =~ s/\A$data{family}//xms;
+ $data{fullname} = lc $data{fullname};
+ $data{family} =~ s/\A(?: Adobe | ITC | LT | MT)//xms;
+ $data{family} =~ s/(\d)/$DIGITS[$1]/xmsge;
+
+ for my $width (mqrs(keys %FD_WIDTH)) {
+ if ($data{fullname} =~ s/${width}//xmsi) {
+ $info->{width} = $width;
+ last;
}
}
-
- WEIGHT:
- for my $weight (map { quotemeta }
- reverse sort
- { length($a) <=> length($b) || $a cmp $b }
- keys %FD_WEIGHT)
- {
- if ($info{'Full name'} =~ s/$weight//xmsi) {
- $fontinfo{weight} = $weight;
- last WEIGHT;
+
+ for my $weight (mqrs(keys %FD_WEIGHT)) {
+ if ($data{fullname} =~ s/${weight}//xmsi) {
+ $info->{weight} = $weight;
+ last;
}
}
- SHAPE:
- for my $shape (map { quotemeta }
- reverse sort
- { length($a) <=> length($b) || $a cmp $b }
- keys %FD_SHAPE)
- {
- if ($info{'Full name'} =~ s/$shape//xmsi) {
- $fontinfo{shape} = $shape;
- last SHAPE;
+
+ for my $shape (mqrs(keys %FD_SHAPE)) {
+ if ($data{fullname} =~ s/${shape}//xmsi) {
+ $info->{shape} = $shape;
+ last;
}
}
-
- # Read optical size info
- open $OTFINFO, '-|',"otfinfo --optical-size \"$fontfile\""
- or die "ERROR: 'otfinfo --optical-size \"$fontfile\"' failed";
- if (my ($fm, $to)
- = <$OTFINFO> =~ m/
- [(]
- ( [\d.]+ ) \s* pt, \s*
- ( [\d.]+ ) \s* pt \s*
- []]
- /xms) {
- # Work around some known bugs
- if ($fontinfo{name} eq 'GaramondPremrPro-It'
- && $fm == 6
- && $to == 8.9) {
- @fontinfo{qw(min max)} = (8.9, 14.9);
- }
- elsif ($fontinfo{family} eq 'KeplerStd'
- && $info{Subfamily} =~ m/Caption/xms
- && $fm == 8.9
- && $to == 13.9) {
- @fontinfo{qw(min max)} = (6, 8.9);
- }
- elsif ($fontinfo{family} eq 'KeplerStd'
- && $info{Subfamily} =~ m/Subhead/xms
- && $fm == 8.9
- && $to == 13.9) {
- @fontinfo{qw(min max)} = (13.9, 23);
- }
- elsif ($fontinfo{family} eq 'KeplerStd'
- && $info{Subfamily} =~ m/Display/xms
- && $fm == 8.9
- && $to == 13.9) {
- @fontinfo{qw(min max)} = (23, 72);
- }
- else {
- @fontinfo{qw(min max)} = ($fm, $to);
+
+ $data{subfamily} =~ s/$info->{width}//xmsi;
+ $data{subfamily} =~ s/$info->{weight}//xmsi;
+ $data{subfamily} =~ s/$info->{shape}//xmsi;
+
+ $info->{name} = $data{postscriptname};
+ $info->{family} = $data{family};
+ $info->{subfamily} = $data{subfamily};
+
+ $info->{basicshape} = $FD_SHAPE{$info->{shape}};
+ $info->{fdseries}
+ = ($FD_WEIGHT{$info->{weight}} . $FD_WIDTH{$info->{width}}) || 'm';
+
+ return $info;
+}
+
+#-----------------------------------------------------------------------
+# When matching against data, try longer strings before shorter ones
+#-----------------------------------------------------------------------
+sub mqrs {
+ return map { quotemeta } reverse sort { length($a) <=> length($b) } @_;
+}
+
+#-----------------------------------------------------------------------
+# Get all features this font supports
+#-----------------------------------------------------------------------
+sub parse_features {
+ my $info = shift;
+
+ open my $otfinfo, '-|', qq(otfinfo --features "$info->{filename}")
+ or die "[ERROR] 'otfinfo --features $info->{filename}' failed";
+ %{$info->{feature}} = map { (substr($_, 0, 4) => 1) } <$otfinfo>;
+ close $otfinfo;
+
+ open $otfinfo, '-|', qq(otfinfo --tables "$info->{filename}")
+ or die "[ERROR] 'otfinfo --tables $info->{filename}' failed";
+ $info->{feature}{kern} = 1 if grep { m/\d+ \s+ kern/xms } <$otfinfo>;
+ close $otfinfo;
+
+ return $info;
+}
+
+#-----------------------------------------------------------------------
+# Get the optical sizes for this font
+#-----------------------------------------------------------------------
+sub parse_sizeinfo {
+ my $info = shift;
+
+ open my $otfinfo, '-|', qq(otfinfo --optical-size "$info->{filename}")
+ or die "[ERROR] 'otfinfo --optical-size $info->{filename}' failed";
+
+ if (my ($minsize, $maxsize) = <$otfinfo> =~ m/[(] ([\d.]+) \s* pt, \s*
+ ([\d.]+) \s* pt \s* []]/xms )
+ {
+ # fix some known bugs
+ if ($info->{name} eq 'GaramondPremrPro-It'
+ && $minsize == 6 && $maxsize == 8.9)
+ {
+ ($minsize, $maxsize) = (8.9, 14.9);
}
- }
- close $OTFINFO;
-
- # See what features this font provides
- open $OTFINFO, '-|',"otfinfo --features \"$fontfile\""
- or die "ERROR: 'otfinfo --features \"$fontfile\"' failed";
- for my $line (<$OTFINFO>) {
- if ($line =~ m/\A (\w{4}) \s+/xms) {
- $fontinfo{features}{$1} = 1;
+ elsif ($info->{family} eq 'KeplerStd'
+ && $info->{subfamily} =~ m/Caption/xms
+ && $minsize == 8.9 && $maxsize == 13.9)
+ {
+ ($minsize, $maxsize) = (6, 8.9);
}
- }
- close $OTFINFO;
-
- # Check if there's a "kern" table
- open $OTFINFO, '-|',"otfinfo --tables \"$fontfile\""
- or die "ERROR: 'otfinfo --tables \"$fontfile\"' failed";
- for my $line (<$OTFINFO>) {
- if ($line =~ m/\d+ \s+ (\w{4}) \s+/xms && $1 eq 'kern') {
- $fontinfo{features}{kern} = 1;
- last;
+ elsif ($info->{family} eq 'KeplerStd'
+ && $info->{subfamily} =~ m/Subhead/xms
+ && $minsize == 8.9 && $maxsize == 13.9)
+ {
+ ($minsize, $maxsize) = (13.9, 23);
}
- }
- close $OTFINFO;
-
- if ($ARGV{verbose}) {
- print <<"END_FONT_INFO";
-
-$fontfile:
- Family $fontinfo{family}
- Width $fontinfo{width}
- Weight $fontinfo{weight}
- Shape $fontinfo{shape}
- Size @{[ $fontinfo{min} || '']}-@{[ $fontinfo{max} || '' ]}
-END_FONT_INFO
-
- my @features = sort keys %{$fontinfo{features}};
- my $prefix = ' Features ';
- while (@features) {
- print $prefix, join(' ', splice @features, 0, 10), "\n";
- $prefix = ' ' x length $prefix;
+ elsif ($info->{family} eq 'KeplerStd'
+ && $info->{subfamily} =~ m/Display/xms
+ && $minsize == 8.9 && $maxsize == 13.9)
+ {
+ ($minsize, $maxsize) = (23, 72);
}
- print "\n";
+
+ @{$info}{qw(minsize maxsize)} = ($minsize, $maxsize);
}
-
- return %fontinfo;
+ close $otfinfo;
+
+ return $info;
}
-=begin Comment
+# Error messages, used in assert_unique()
+my $WARN_PARSE =<<'END_WARN_PARSE';
+[WARNING] I failed to parse all fonts in a unique way, so I will split
+ your font family into multiple subfamilies and try again:
- Ornament glyph names vary across fonts, so we generate font-specific
- encoding vectors.
- This is skipped if a file `<family>_orn.enc' is found in the current
- directory, so the user can provide her own vector if she wants to.
+ %s
-=end Comment
+ Please check the output!
-=cut
+END_WARN_PARSE
-sub make_ornament_encoding {
- my (%fontinfo) = @_;
+my $ERR_PARSE =<<'END_ERR_PARSE';
+[ERROR] I failed to parse all fonts in a unique way;
+ presumably some fonts have unusual widths, weights or shapes.
- my $fontfile = $fontinfo{filename};
- my $enc_name = $fontinfo{family} . '_orn';
-
- if (not -e "$enc_name.enc") {
+ Try one of the following:
+ - Run 'autoinst' on a smaller set of fonts,
+ omitting the ones that weren't parsed correctly;
+ - Add the missing widths, weights or shapes to the tables
+ '%FD_WIDTH', '%FD_WEIGHT' or '%FD_SHAPE' near the top
+ of the source code;
+
+ Please also send a bug report to the author.
+
+END_ERR_PARSE
+
+my $ERR_DETAIL =<<'END_ERR_DETAIL';
+[ERROR] I've parsed both %s
+ and %s as
+
+ Family: %s
+ Width: %s
+ Weight: %s
+ Shape: %s
+ Size: %s-%s
+
+END_ERR_DETAIL
+#-----------------------------------------------------------------------
+# Assert all font infos are unique
+#-----------------------------------------------------------------------
+sub assert_unique {
+ my @fonts = @_;
+
+ # These attributes should uniquely identify each font
+ my @attributes = qw(family width weight shape minsize maxsize);
+
+ ATTEMPT:
+ for my $attempt (1 .. 2) {
+ my (%seen, $err_details);
+ for my $font (@fonts) {
+ my $key
+ = join "\x00",
+ @{$font}{ @attributes };
+
+ if ($seen{$key}) {
+ $err_details .= sprintf $ERR_DETAIL,
+ $seen{$key}{filename},
+ $font->{filename},
+ @{$font}{ @attributes };
+ }
+ else {
+ $seen{$key} = $font;
+ }
+ }
+
+ # If the font infos aren't unique, append 'Subfamily' to 'Family'
+ # and try again
+ if ($err_details) {
+ if ($attempt == 1) {
+ $err_details =~ s/\[ERROR\]/[WARNING]/xmsg;
+ warn $err_details;
+
+ for my $font (@fonts) {
+ $font->{family} .= $font->{subfamily};
+ }
+
+ my @subfamilies
+ = sort keys %{{ map { ($_->{family} => 1) } @fonts }};
+ warn sprintf $WARN_PARSE, join ', ', @subfamilies;
+
+ next ATTEMPT;
+ }
+ else {
+ die $err_details, $ERR_PARSE;
+ }
+ }
+
+ last ATTEMPT;
+ }
+
+ return 1;
+}
+
+#-----------------------------------------------------------------------
+# Generate (font-specific) encoding vector for ornament glyphs
+#-----------------------------------------------------------------------
+sub get_orn {
+ my ($font) = @_;
+
+ my $fontfile = $font->{filename};
+ my $enc_name = $font->{family} . '_orn';
+
+ if (not -e "$enc_name.enc") {
# Default ornament names: 'orn.' plus three digits
my @encoding = map { sprintf "orn.%03d", $_ } 1 .. 256;
-
- open my $OTFINFO, '-|', "otfinfo --glyphs \"$fontfile\""
- or die "ERROR: 'otfinfo --glyphs \"$fontfile\"' failed";
+
+ open my $OTFINFO, '-|', qq(otfinfo --glyphs "$font->{filename}")
+ or die "[ERROR] 'otfinfo --glyphs $font->{filename}' failed";
chop(my @glyphnames = <$OTFINFO>);
close $OTFINFO;
# Test for some known alternative names (probably not exhaustive)
- my @ornaments
- = sort grep { m/\A (?:orn|u2022[.]|word[.]|hand|bullet[.]) | [.]orn \z/xms }
+ my @ornaments
+ = sort grep { m/\A (?: orn|u2022[.]|word[.]|hand|bullet[.])
+ | [.]orn \z/xms
+ }
@glyphnames;
-
- if (@ornaments > 256) {
- @encoding = @ornaments[0 .. 255];
- }
- else {
- @encoding[0 .. $#ornaments] = @ornaments;
- }
- open my $ORNAMENTS, '>', "$enc_name.enc"
- or die "ERROR: can't create '$enc_name.enc' - $!";
-
- print {$ORNAMENTS} "/$fontinfo{family}OrnamentEncoding [\n";
- map { print {$ORNAMENTS} " /$_\n" } @encoding;
- print {$ORNAMENTS} "] def\n";
- close $ORNAMENTS;
+ @encoding[0 .. $#ornaments] = @ornaments;
+
+ open my $ORN, '>', "$enc_name.enc"
+ or die "[ERROR] Can't create '$enc_name.enc': $!";
+
+ print {$ORN} "/$font->{family}OrnamentEncoding [\n";
+ map { print {$ORN} " /$_\n" } @encoding[0 .. 255];
+ print {$ORN} "] def\n";
+ close $ORN;
}
-
+
return $enc_name;
}
-# ------------------------------------------------------------------------
-
-sub write_style_file {
- my ($family, $safe, @fd_data) = @_;
-
- my (%seen_enc, %seen_style, %seen_series, %seen_shape);
-
- LINE:
- for my $line_ref (@fd_data) {
- my ($fam, $enc, $style, $series, $shape) = @{$line_ref}[0 .. 4];
- next LINE if $fam ne $family;
- $seen_enc{$enc} = 1;
- $seen_style{$style} = 1;
- $seen_series{$series} = 1;
- $seen_shape{$shape} = 1;
- }
-
- open my $STYLE, '>', "$family.sty"
- or die "ERROR: can't create '$family.sty' - $!";
- print {$STYLE} <<"END_STY_HEADER";
-%%Generayed by autoinst on $date
+
+############################################################################
+
+
+package LaTeX;
+
+#-----------------------------------------------------------------------
+# Create a style file for LaTeX
+#-----------------------------------------------------------------------
+sub write_stylefile {
+ my ($fam, $data) = @_;
+
+ my %seen = %{ get_keys($data) };
+
+ my $fn = sprintf "%s.sty", $fam;
+ my $dir = File::Spec->catdir($ARGV{target}, 'tex', 'latex', $fam);
+ File::Path::make_path($dir);
+ $fn = File::Spec->catfile($dir, $fn);
+ open my $STY, '>', $fn or die "[ERROR] Can't create '$fn': $!";
+
+ print {$STY} <<"END_STY_HEADER";
+%% Generated by autoinst on $TODAY
%%
\\NeedsTeXFormat{LaTeX2e}
-\\ProvidesPackage{$family}
- [$date (autoinst) Style file for $family.]
-
+\\ProvidesPackage{$fam}
+ [$TODAY (autoinst) Style file for $fam.]
+
END_STY_HEADER
-
- my $textenc = join ',', grep { $_ ne 'OT1' } @{$ARGV{encoding}};
-
- print {$STYLE} "\\RequirePackage[$textenc]{fontenc}\n" if $textenc;
- print {$STYLE} "\\RequirePackage{textcomp}\n" if $seen_enc{TS1};
-
- print {$STYLE} <<'END_STY_FONTAXES_START';
+
+ my $enc = join ',', grep { $_ ne 'OT1' } @{$ARGV{encoding}};
+
+ print {$STY} "\\RequirePackage[$enc]{fontenc}\n" if $enc;
+ print {$STY} "\\RequirePackage{textcomp}\n" if $seen{TS1};
+
+ print {$STY} <<'END_STY_FONTAXES_START';
\IfFileExists{fontaxes.sty}{
\RequirePackage{fontaxes}
END_STY_FONTAXES_START
- if ($seen_shape{tl} || $seen_shape{tlit}) {
- print {$STYLE} <<'END_STY_FONTAXES_TL';
+ if ($seen{tl} or $seen{tlit}) {
+ print {$STY} <<'END_STY_FONTAXES_TL';
\providecommand{\tldefault}{tl}
\DeclareRobustCommand\tlshape{\not@math@alphabet\tlshape\relax
\fontsecondaryshape\tldefault\selectfont}
@@ -919,82 +1035,79 @@ END_STY_FONTAXES_START
\let\texttitling\texttl
\fa@naming@exception{shape}{{n}{tl}}{tl}
\fa@naming@exception{shape}{{it}{tl}}{tlit}
-
+
END_STY_FONTAXES_TL
}
- if ($seen_shape{nw} || $seen_shape{sw}) {
- print {$STYLE} <<'END_STY_FONTAXES_SW';
+ if ($seen{nw} or $seen{sw}) {
+ print {$STY} <<'END_STY_FONTAXES_SW';
\DeclareRobustCommand\swshape{\not@math@alphabet\swshape\relax
\fontprimaryshape\itdefault\fontsecondaryshape\swdefault\selectfont}
\fa@naming@exception{shape}{{n}{sw}}{nw}
\fa@naming@exception{shape}{{it}{sw}}{sw}
-
+
END_STY_FONTAXES_SW
}
- if ($seen_style{Sup}) {
- print {$STYLE} <<'END_STY_FONTAXES_SUP';
+ if ($seen{Sup}) {
+ print {$STY} <<'END_STY_FONTAXES_SUP';
\fa@naming@exception{figures}{{superior}{proportional}}{Sup}
\fa@naming@exception{figures}{{superior}{tabular}}{Sup}
\def\sufigures{\@nomath\sufigures
\fontfigurestyle{superior}\selectfont}
\DeclareTextFontCommand{\textsu}{\sufigures}
\let\textsuperior\textsu
-
+
END_STY_FONTAXES_SUP
}
- if ($seen_style{Inf}) {
- print {$STYLE} <<'END_STY_FONTAXES_INF';
+ if ($seen{Inf}) {
+ print {$STY} <<'END_STY_FONTAXES_INF';
\fa@naming@exception{figures}{{inferior}{proportional}}{Inf}
\fa@naming@exception{figures}{{inferior}{tabular}}{Inf}
\def\infigures{\@nomath\infigures
\fontfigurestyle{inferior}\selectfont}
\DeclareTextFontCommand{\textin}{\infigures}
\let\textinferior\textin
-
+
END_STY_FONTAXES_INF
}
- if ($seen_style{Orn}) {
- print {$STYLE} <<'END_STY_FONTAXES_ORN';
+ if ($seen{Orn}) {
+ print {$STY} <<'END_STY_FONTAXES_ORN';
\fa@naming@exception{figures}{{ornament}{proportional}}{Orn}
\fa@naming@exception{figures}{{ornament}{tabular}}{Orn}
\def\ornaments{\@nomath\ornaments
\fontencoding{U}\fontfigurestyle{ornament}\selectfont}
\DeclareTextFontCommand{\textornaments}{\ornaments}
\providecommand{\ornament}[1]{\textornaments{\char##1}}
-
+
END_STY_FONTAXES_ORN
}
- if ($seen_style{Numr}) {
- print {$STYLE} <<'END_STY_FONTAXES_NUMR';
+ if ($seen{Numr}) {
+ print {$STY} <<'END_STY_FONTAXES_NUMR';
\fa@naming@exception{figures}{{numerators}{proportional}}{Numr}
\fa@naming@exception{figures}{{numerators}{tabular}}{Numr}
END_STY_FONTAXES_NUMR
}
- if ($seen_style{Dnom}) {
- print {$STYLE} <<'END_STY_FONTAXES_DNOM';
+ if ($seen{Dnom}) {
+ print {$STY} <<'END_STY_FONTAXES_DNOM';
\fa@naming@exception{figures}{{denominators}{proportional}}{Dnom}
\fa@naming@exception{figures}{{denominators}{tabular}}{Dnom}
END_STY_FONTAXES_DNOM
}
- print {$STYLE} <<'END_STY_FONTAXES_END';
-}{}
-
-END_STY_FONTAXES_END
+ print {$STY} "}{}\n\n";
- print {$STYLE} <<"END_STY_XKEYVAL";
+ print {$STY} <<"END_STY_XKEYVAL";
\\IfFileExists{xkeyval.sty}{
- \\newcommand*{\\$safe\@scale}{1}
+ \\newcommand*{\\$fam\@scale}{1}
\\RequirePackage{xkeyval}
- \\DeclareOptionX{scaled}{\\renewcommand*{\\$safe\@scale}{##1}}
+ \\DeclareOptionX{scaled}{\\renewcommand*{\\$fam\@scale}{##1}}
}{
\\let\\DeclareOptionX\\DeclareOption
\\let\\ExecuteOptionsX\\ExecuteOptions
@@ -1002,163 +1115,197 @@ END_STY_FONTAXES_END
}
END_STY_XKEYVAL
-
- if ($seen_style{LF} or $seen_style{TLF}) {
- print {$STYLE}
- "\\DeclareOptionX{lining}{\\edef\\$safe\@figurestyle{LF}}\n";
+
+ if ($seen{LF} or $seen{TLF}) {
+ print {$STY}
+ "\\DeclareOptionX{lining}{\\edef\\$fam\@figurestyle{LF}}\n";
}
- if ($seen_style{OsF} or $seen_style{TOsF}) {
- print {$STYLE}
- "\\DeclareOptionX{oldstyle}{\\edef\\$safe\@figurestyle{OsF}}\n";
+ if ($seen{OsF} or $seen{TOsF}) {
+ print {$STY}
+ "\\DeclareOptionX{oldstyle}{\\edef\\$fam\@figurestyle{OsF}}\n";
}
- if ($seen_style{TLF} or $seen_style{TOsF}) {
- print {$STYLE}
- "\\DeclareOptionX{tabular}{\\edef\\$safe\@figurealign{T}}\n";
+ if ($seen{TLF} or $seen{TOsF}) {
+ print {$STY}
+ "\\DeclareOptionX{tabular}{\\edef\\$fam\@figurealign{T}}\n";
}
- if ($seen_style{LF} or $seen_style{OsF}) {
- print {$STYLE}
- "\\DeclareOptionX{proportional}{\\edef\\$safe\@figurealign{}}\n";
+ if ($seen{LF} or $seen{OsF}) {
+ print {$STY}
+ "\\DeclareOptionX{proportional}{\\edef\\$fam\@figurealign{}}\n";
}
-
+
my $defaults
- = $seen_style{OsF} ? 'oldstyle,proportional'
- : $seen_style{TOsF} ? 'oldstyle,tabular'
- : $seen_style{LF} ? 'lining,proportional'
- : $seen_style{TLF} ? 'lining,tabular'
- : die "ERROR: encountered un unknown bug";
-
+ = $seen{OsF} ? 'oldstyle,proportional'
+ : $seen{TOsF} ? 'oldstyle,tabular'
+ : $seen{LF} ? 'lining,proportional'
+ : $seen{TLF} ? 'lining,tabular'
+ : die "[ERROR] Internal bug, please report!";
+
my $default_bold;
for my $series (
- qw(ultrablack ultrabold heavy extrablack black
+ qw(ultrablack ultrabold heavy extrablack black
extrabold demibold semibold bold)) {
- if ($seen_series{$FD_WEIGHT{$series}}) {
- printf {$STYLE}
+ if ($seen{$FD_WEIGHT{$series}}) {
+ printf {$STY}
"\\DeclareOptionX{%s}{\\renewcommand*{\\bfdefault}{%s}}\n",
$series, $FD_WEIGHT{$series};
$default_bold = $series;
}
}
$defaults .= ",$default_bold" if $default_bold;
-
+
my $default_regular;
for my $series (
qw(light medium regular)) {
- if ($seen_series{$FD_WEIGHT{$series} || 'm'}) {
- printf {$STYLE}
+ if ($seen{$FD_WEIGHT{$series} || 'm'}) {
+ printf {$STY}
"\\DeclareOptionX{%s}{\\renewcommand*{\\mddefault}{%s}}\n",
$series, $FD_WEIGHT{$series} || 'm';
$default_regular = $series;
}
}
$defaults .= ",$default_regular" if $default_regular;
-
- print {$STYLE} <<"END_STYLE_REST";
+
+ print {$STY} <<"END_STYLE_REST";
\\ExecuteOptionsX{$defaults}
\\ProcessOptionsX\\relax
\\renewcommand*
{\\$ARGV{nfss}default}
- {$family-\\$safe\@figurealign\\$safe\@figurestyle}
+ {$fam-\\$fam\@figurealign\\$fam\@figurestyle}
\\renewcommand*{\\familydefault}{\\$ARGV{nfss}default}
\\endinput
END_STYLE_REST
- close $STYLE;
+ close $STY;
+
+ return;
}
-# ------------------------------------------------------------------------
+#-----------------------------------------------------------------------
+# Walk a nested dictionary, return lookup table with all keys
+#-----------------------------------------------------------------------
+sub get_keys {
+ my $dict = shift;
+ my $seen = shift || {};
+
+ while (my ($k, $v) = each %$dict) {
+ $seen->{$k} = 1;
+ get_keys($v, $seen) if ref $v eq 'HASH';
+ }
+
+ return $seen;
+}
+
+#-----------------------------------------------------------------------
+# Create a .fd file for LaTeX's NFSS
+#-----------------------------------------------------------------------
+sub write_fdfile {
+ my ($fam, $enc, $sty, $data) = @_;
+
+ my $fn = sprintf "%s%s-%s.fd", $enc, $fam, $sty;
+ my $dir = File::Spec->catdir($ARGV{target}, 'tex', 'latex', $fam);
+ File::Path::make_path($dir);
+ $fn = File::Spec->catfile($dir, $fn);
+ open my $FD, '>', $fn or die "[ERROR] Can't create '$fn': $!";
-sub start_fd_file {
- my ($fam, $enc, $fig, $safe) = @_;
-
- open my $FD, '>', "$enc$fam-$fig.fd"
- or die "ERROR: can't create '$enc$fam-$fig.fd' - $!";
-
print {$FD} <<"END_FD_HEADER";
-%%Generated by autoinst on $date
+%% Generated by autoinst on $TODAY
%%
-\\ProvidesFile{$enc$fam-$fig.fd}
- [$date (autoinst) Font definitions for $enc/$fam-$fig.]
+\\ProvidesFile{${enc}${fam}-${sty}.fd}
+ [$TODAY (autoinst) Font definitions for ${enc}/${fam}-${sty}.]
-\\expandafter\\ifx\\csname $safe\@scale\\endcsname\\relax
- \\let\\$safe\@\@scale\\\@empty
+\\expandafter\\ifx\\csname ${fam}\@scale\\endcsname\\relax
+ \\let\\${fam}\@\@scale\\\@empty
\\else
- \\edef\\$safe\@\@scale{s*[\\csname $safe\@scale\\endcsname]}%
+ \\edef\\${fam}\@\@scale{s*[\\csname ${fam}\@scale\\endcsname]}%
\\fi
-
-\\DeclareFontFamily{$enc}{$fam-$fig}{}
+
+\\DeclareFontFamily{${enc}}{${fam}-${sty}}{}
END_FD_HEADER
- return $FD;
+ while (my ($series, $fdseries) = each %$data) {
+ while (my ($shape, $fdshape) = each %$fdseries) {
+ print {$FD}
+ "\\DeclareFontShape{$enc}{${fam}-${sty}}{$series}{$shape}{\n";
+ my @items = sort { $a->[0] <=> $b->[0] }
+ @{$fdshape};
+ $items[0][0] = $items[-1][1] = '';
+ $items[$_][0] = $items[$_ - 1][1] for (1 .. $#items);
+ for my $item (@items) {
+ print {$FD} " <$item->[0]-$item->[1]>",
+ " \\${fam}\@\@scale $item->[2]\n";
+ }
+ print {$FD} "}{}\n\n";
+ }
+ }
+ print {$FD} "\\endinput\n";
+
+ close $FD;
+
+ return;
}
-# ------------------------------------------------------------------------
-sub end_fd_file {
- my ($FD) = @_;
-
- print {$FD} "}{}\n\n\\endinput\n";
- close $FD;
-}
+############################################################################
+
+package main;
-main()
+main();
__END__
- pod2man --center="fontools" --date=`date +"%Y-%m-%d"` \
- --release="fontools" --section=1 autoinst autoinst.1
-
- man -t ./autoinst.1 | ps2pdf - autoinst.pdf
+############################################################################
+
+
+ To create the documentation:
+
+ pod2man --center="Marc Penninga" --release="fontools" --section=1 \
+ autoinst - | groff -Tps -man - | ps2pdf - autoinst.pdf
=pod
=head1 NAME
-autoinst - wrapper script around the F<LCDF TypeTools>,
+autoinst - wrapper around the F<LCDF TypeTools>,
for installing OpenType fonts in LaTeX.
=head1 SYNOPSIS
-autoinst [options] I<fontfile> [I<fontfile> ...]
+B<autoinst> [I<options>] B<font(s)>
=head1 DESCRIPTION
-Eddie Kohler's F<TypeTools>, especially F<otftotfm>, are great tools for
-installing OpenType fonts for use with LaTeX, but their use (even in
-automatic mode) is quite complicated because it needs lots of long
-command lines and doesn't generate the F<fd> and F<sty> files LaTeX needs.
-B<autoinst> simplifies the font installation
-process by generating and executing all commands for F<otftotfm>
-and by creating all necessary F<fd> and F<sty> files.
+Eddie Kohler's F<TypeTools>, especially F<otftotfm>, are superb tools
+for installing OpenType fonts in LaTeX, but their use
+(even in automatic mode) is complicated: they need many long
+command lines and don't generate the F<fd> and F<sty> files LaTeX needs.
+B<autoinst> simplifies the font installation process with F<otftotfm>
+by generating and executing all command lines
+and by creating and installing all F<fd> and F<sty> files.
-All the user then needs
-to do is move these files to a suitable location
-(F<< $LOCALTEXMF/tex/latex/<Supplier>/<FontFamily>/ >> is the
-official choice) and update TeX's filename database.
-
-Given a family of font files (in either F<.ttf> or F<.otf> format),
+Given a family of font files (in either F<otf> or F<ttf> format),
B<autoinst> will create several LaTeX font families:
=over 2
-=over 2
+=over 3
-=item B<->
+=item -
-Four text families (with lining and oldstyle figures, in tabular and
+Four text families (with lining and oldstyle digits, in tabular and
proportional variants), each with the following shapes:
=over 2
-=over 4
+=over 6
=item I<n>
@@ -1170,19 +1317,20 @@ Small caps
=item I<nw>
-`Upright swash'; usually normal text with some extra `oldstyle' ligatures,
+"Upright swash"; usually normal text with some extra "oldstyle" ligatures,
such as ct, sp and st.
=item I<tl>
-Titling shape. Meant for all-caps text only (even though it sometimes contains
-lowercase glyphs as well), where letterspacing and the positioning of
-punctuation characters have been adjusted to suit all-caps text.
-This shape is generated only for the families with lining figures.
+Titling shape. Meant for all-caps text only (even though it sometimes contains
+lowercase glyphs as well), where letterspacing and the positioning of
+punctuation characters have been adjusted to suit all-caps text.
+This shape is generated only for the families with lining digits, since
+all-caps text doesn't mix with old-style digits.
=item I<it>
-Italic or oblique text
+Italic (or oblique) text
=item I<scit>
@@ -1200,17 +1348,17 @@ Italic titling
=back
-=item B<->
+=item -
-For each text family: a family of TS1-encoded symbol fonts,
+For each text family: a family of TS1-encoded symbol fonts,
in roman and italic shapes.
-=item B<->
+=item -
Four families with superiors, inferiors, numerators and denominators,
in roman and italic shapes.
-=item B<->
+=item -
An ornament family, in roman and italic shapes.
@@ -1218,12 +1366,12 @@ An ornament family, in roman and italic shapes.
=back
-Of course, if the font doesn't contain oldstyle figures, small caps etc.,
-the corresponding shapes or families are not created;
-furthermore, the creation of most families and shapes can be controlled by
-command-line options (see below).
+Of course, if the fonts don't contain oldstyle digits, small caps etc.,
+the corresponding shapes and families are not created.
+Furthermore, the creation of most families and shapes can be controlled by
+command-line options (see L</"COMMAND-LINE OPTIONS"> below).
-The generated font families are named I<< <FontFamily>-<Suffix> >>,
+The generated font families are named I<< <FontFamily>-<Suffix> >>,
where I<< <Suffix> >> is one of
=over 8
@@ -1246,13 +1394,13 @@ tabular oldstyle figures
=item I<Sup>
-superior characters (many fonts only have an incomplete set
-of superiors: figures, some punctuation and the letters
-I<abdeilmnorst>; normal forms will be used for the other characters)
+superior characters (many fonts have only an incomplete set of superiors:
+digits, punctuation and the letters I<abdeilmnorst>;
+normal forms will be used for the other characters)
=item I<Inf>
-inferior characters; usually only figures and punctuation,
+inferior characters; usually only digits and punctuation,
normal forms for the other characters
=item I<Orn>
@@ -1269,29 +1417,30 @@ denominators
=back
-The generated fonts are named I<< <FontFile>-<suffix>-<shape>-<enc> >>,
-where I<< <FontFile> >> is the name of the OpenType file, I<< <suffix> >>
-is the same as above (but in lowercase), I<< <shape> >> is either empty,
-`sc', `swash' or `titling', and I<< <enc> >> is the encoding.
-A typical name in this scheme is F<MinionPro-Regular-osf-sc-ly1>.
+The generated fonts are named I<< <FontName>-<suffix>-<shape>-<enc> >>,
+where I<< <suffix> >> is the same as above (but in lowercase),
+I<< <shape> >> is either empty, "sc", "swash" or "titling",
+and I<< <enc> >> is the encoding.
+A typical name in this scheme would be "MinionPro-Regular-osf-sc-ly1".
=head2 On the choice of text encoding
-By default, all text families use the LY1 encoding. This has been chosen
-over T1 (Cork) because many OpenType fonts contain additional ligatures
-such as fj and Th, and LY1 has a number of empty slots to accommodate these.
-Different encodings can be selected using the B< --encoding>
-command line option (see below).
+By default, B<autoinst> generates text fonts with OT1, T1 and LY1
+encodings, and the generated style files use LY1 as the default text encoding.
+LY1 has been chosen over T1 because it has some empty slots to accomodate
+the additional ligatures and alternate glyphs provided by many OpenType fonts.
+Different encodings can be selected using the I<-encoding>
+command-line option (see L</"COMMAND-LINE OPTIONS"> below).
-=head2 Using the fonts with LaTeX
+=head2 Using the fonts in your LaTeX documents
-B<autoinst> generates a style file for using the font in LaTeX documents,
-named `<I<FontFamily>>.sty'. This style file also takes care of loading the
+B<autoinst> generates a style file for using the font in LaTeX documents,
+named F<< <FontFamily>.sty >>. This style file also takes care of loading the
F<fontenc> and F<textcomp> packages, if necessary.
-To use the font, simply put C<\usepackage{MinionPro}>
-(or whatever the font is called) in the preamble of your document.
+To use the font, simply put C<<< \usepackage{I<< <FontFamily> >>} >>>
+in the preamble of your document.
This style file defines a number of options:
@@ -1299,268 +1448,321 @@ This style file defines a number of options:
=item I<lining, oldstyle, tabular, proportional>
-Choose which figures will be used for the text fonts.
-The defaults are `oldstyle' and `proportional' (if available).
+Choose which digits will be used for the text fonts.
+The defaults are "oldstyle" and "proportional" (if available).
=item I<ultrablack, ultrabold, heavy, extrablack, black, extrabold,
demibold, semibold, bold>
-Choose the weight that LaTeX will use for the `bold' weight
+Choose the weight that LaTeX will use for the "bold" weight
(i.e., the value of C<\bfdefault>).
=item I<light, medium, regular>
-Choose the weight that LaTeX will use for the `regular' weight
+Choose the weight that LaTeX will use for the "regular" weight
(i.e., the value of C<\mddefault>).
=item I<< scaled=<scale> >>
-Scale the font by a factor of I<< <scale> >>.
+Scale the font by a factor of I<< <scale> >>.
For example: to increase the size of the font by 5%, use the command
-C<\usepackage[scaled=1.05]{MyriadPro}>.
+C<<< \usepackage[scaled=1.05]{I<< <FontFamily> >>} >>>.
This option is only available when the F<xkeyval> package is found
in your TeX installation.
=back
-The style file will also try to load the F<fontaxes> package (part of
-the MinionPro for LaTeX project), which gives easy access to various font
-shapes and styles. This package can be downloaded from the project's homepage
-(F<http://developer.berlios.de/projects/minionpro>) or directly through
-the CVS web interface
-(F<http://cvs.berlios.de/cgi-bin/viewcvs.cgi/minionpro/MinionPro/tex/>),
-and is also available from CTAN as part of the archive F<metrics-base.zip>
-(F<http://www.ctan.org/tex-archive/fonts/minionpro/metrics-base.zip>).
-
-Using the machinery set up by F<fontaxes>, the generated style file
-also defines a few commands (which take the text to be typeset as argument)
-and declarations (which don't take arguments, but affect all text up to
+The style file will also try to load the F<fontaxes> package,
+which gives easy access to various font shapes and styles.
+It is available from CTAN
+(F<http://www.ctan.org/tex-archive/macros/latex/contrib/fontaxes>).
+Using the machinery set up by F<fontaxes>, the generated style file also
+defines a number of commands (which take the text to be typeset as argument)
+and declarations (which don't take arguments, but affect all text up to
the end of the current group) of its own:
DECLARATION COMMAND SHORT FORM OF COMMAND
-
+
\tlshape \texttitling \texttl
- \sufigures \textsuperior \textsu
- \infigures \textinferior \textin
-
+ \sufigures \textsuperior \textsu
+ \infigures \textinferior \textin
+
In addition, the C<\swshape> and C<\textsw> commands are redefined to place
-swash on the secondary shape axis (F<fontaxes> places it on the primary
-shape axis); this allows the use of `upright swash'.
-Just saying C<\swshape> will still give normal (italic) swash,
-but C<\swshape\upshape> results in upright swash.
-
-Note that there is no separate command for accessing the italic titling shape;
-but these commands behave properly when nested, so C<\tlshape\itshape> gives
-italic titling.
-There are also no commands for accessing the numerator and denominator
-fonts; these can be selected using F<fontaxes>' low-level commands,
+swash on the secondary shape axis (F<fontaxes> places it on the primary
+shape axis); this makes these commands behave properly when nested, so that
+C<\swshape\upshape> will give upright swash.
+
+There are no commands for accessing the numerator and denominator
+fonts; these can be selected using F<fontaxes>' standard commands,
e.g., C<\fontfigurestyle{numerator}\selectfont>.
-The style file also provides a command C<<< \ornament{I<< <number> >>} >>>,
-where C<<< I<< <number> >> >>> is a number from 0 to the total number of
-ornaments minus one. Ornaments are always typeset using the current family,
+The style file also provides a command C<<< \ornament{I<< <number> >>} >>>,
+where C<<< I<< <number> >> >>> is a number from 0 to the total number of
+ornaments minus one. Ornaments are always typeset using the current family,
series and shape. A list of all ornaments in a font can be created by
-running LaTeX on the file F<nfssfont.tex> (part of a standard
-LaTeX installation) and specifying the ornament font
-(e.g., I<MinionPro-Regular-orn-u>).
+running LaTeX on the file F<nfssfont.tex> (part of a standard
+LaTeX installation) and supplying the name of the ornament font.
+
+To access the ornaments, B<autoinst> creates a font-specific encoding file
+F<< <FontFamily>_orn.enc >>, but only if that file doesn't yet exist.
+This means you can provide your own encoding vector,
+e.g. if your fonts use non-standard glyph names for ornaments.
These commands are only generated for shapes and number styles
-that actually exist; no commands are generated for shapes and styles
+that actually exist; no commands are generated for shapes and styles
that don't exist, or whose generation has been turned off.
-
-This whole machinery builds on F<fontaxes>; if that package cannot be found,
-the style file doesn't provide high-level access to the more `exotic'
-font shapes and styles. In that case, you're limited to using the lower-level
-commands from standard NFSS.
+Please note that these commands are built on top of F<fontaxes>;
+if that package cannot be found, you're limited to using the
+lower-level commands from standard NFSS (C<\fontfamily>, C<\fontseries>,
+C<\fontshape> etc.).
=head2 Using multiple font families in one document
-If you want to use several font families in one document, make sure
-all fonts were installed using the same version of B<autoinst>.
-B<autoinst> has seen some non-backward-compatible changes in the past,
-and F<.sty> and F<.fd> files that were generated by different versions
-of B<autoinst> may not be able to coexist peacefully.
+If you want to use more than one font family in a document, be aware
+that style files generated by versions of B<autoinst> older dan 2009
+are incompatible with those generated by newer versions.
=head2 NFSS codes
-In NFSS, weight and width are concatenated into a single `series' attribute.
-B<autoinst> maps widths, weights and shapes to NFSS codes using
-the following tables. These are based on the tables in Lehman's
-F<Font Installation Guide>, but some changes had to be made to avoid
-name clashes for font families with many different widths and weights
-(such as Helvetica Neue).
-
-
- WEIGHT WIDTH
-
- Thin t Ultra Condensed uc
- Ultra Light ul Extra Condensed ec
- Extra Light el Condensed c
- Light l Semicondensed sc
- Book [1] Regular [1]
- Regular [1] Semiextended sx
- Medium mb Extended x
- Demibold db
- Semibold sb
- Bold b
- Extra Bold eb SHAPES
- Black a
- Extra Black ea Roman n
- Heavy h Italic it
- Ultra ub Oblique it [2]
- Ultra Bold ub RomanI n [3]
- Ultra Black ua RomanII it [3]
-
+NFSS identifies fonts by a combination of family, series (weight plus width),
+shape and size.
+B<autoinst> parses the output of C<otfinfo --info> to determine
+these parameters. When this fails
+(e.g., because the font family contains unusual widths or weights),
+B<autoinst> ends up with different fonts having the I<same> values
+for the font parameters, which means that these fonts cannot be used in NFSS.
+B<autoinst> will then split the font family into multiple subfamilies
+(based on the font's "Subfamily" value) and try again.
+(Since many font families overdo the "Subfamily" by making each font
+a separate subfamily, this strategy is only used as a last resort.)
+
+If this proliferation of font families is unwanted,
+either rerun B<autoinst> on a smaller set of fonts (omitting the ones that
+failed to parse correctly)
+or else add the missing widths, weights and shapes to the tables C<%FD_WIDTH>,
+C<%FD_WEIGHT> and C<%FD_SHAPE>, near the top of the source code.
+Please also send a bug report (see L<AUTHOR> below).
+
+B<autoinst> maps widths, weights and shapes to NFSS codes using
+the following tables. These are based both on the standard I<Fontname> scheme
+and on the tables in Philipp Lehman's F<Font Installation Guide>,
+but some changes had to be made to avoid name clashes in font families
+with many different widths and weights.
+
+
+ WEIGHT WIDTH
+
+ Thin t Ultra Compressed up
+ Ultra Light ul Extra Compressed ep
+ Extra Light el Compressed, Compact p
+ Light l Compact p
+ Book [1] Ultra Condensed uc
+ Regular [1] Extra Condensed ec
+ Medium mb Condensed c
+ Demibold db Narrow n
+ Semibold sb Semicondensed sc
+ Bold b Regular [1]
+ Extra Bold eb Semiextended sx
+ Ultra ub Extended x
+ Ultra Bold ub Expanded e
+ Black k Wide w
+ Extra Black ek
+ Ultra Black uk
+ Heavy h SHAPE
+ Poster r
+ Roman, Upright n [2]
+ Italic it
+ Cursive, Kursiv it
+ Oblique, Slanted it [3]
+ Incline(d) it [3]
+
+
+=head3 Notes:
=over 4
=item [1]
-When I<both> weight and width are empty, the `series' attribute becomes `m'.
+When I<both> weight and width are empty, the "series" attribute becomes "m".
=item [2]
-Mapping the `Oblique' shape to `it' instead of the canonical `sl' simplifies
-B<autoinst>. Since font families with both `Italic' and `Oblique' shapes
-probably do not exist (apart from Computer Modern),
-this shouldn't cause problems in real life.
+Adobe Silentium Pro contains two "Roman" shapes ("RomanI" and "RomanII");
+the first of these is mapped to "n", the second one to "it".
=item [3]
-To the best of my knowledge, the only font family that has two `Roman' shapes
-is Silentium; since this has no `Italic' shape,
-the `it' code is (ab)used for the `RomanII' shape.
+Mapping the "Slanted", "Oblique" or "Inclined" shape to "it" instead of "sl"
+simplifies B<autoinst>. Since font families with both italic and slanted
+shapes do - to the best of my knowledge - not exist
+(apart from Computer Modern, of course),
+this shouldn't cause problems in real life.
=back
-
-=head2 A note for MikTeX users
-Calling F<otftotfm> with the B< --automatic> option (as B<autoinst> does by
-default) requires a TeX-installation that uses the F<kpathsea> library; with
-TeX-installations that implement their own directory searching
-(such as MiKTeX) F<otftotfm> might complain that it
-cannot find a writable F<texmf> directory and leave all generated F<tfm>,
-F<vf>, F<enc> and F<map> files in the current working directory.
-In that case, you need to move these to their correct destinations.
-You also need to tell the dvi-driver (F<dvips>, F<dvipdfm>, F<pdfTeX> etc.)
-about the new font map files; see the documentation for how this is done.
+=head2 A note for MiKTeX users
+
+Automatically installing the fonts into a suitable TEXMF tree
+(as B<autoinst> does by default) requires a TeX-installation that uses
+the F<kpathsea> library; with TeX distributions that implement their
+own directory searching (such as MiKTeX), B<autoinst> will complain that
+it cannot find the F<kpsewhich> program and install all generated files
+into subdirectories of the current directory.
+If you use such a TeX distribution, you should either move these files
+to their correct destinations by hand, or use the I<-target> option
+(see L</"COMMAND-LINE OPTIONS"> below) to specify a TEXMF tree.
-Also, some OpenType fonts lead to F<pl> and F<vpl> files that are too
-big for MiKTeX's F<pltotf> and F<vptovf>; the versions from TeXLive
-(F<http://tug.org/ftp/texlive/Contents/live/bin/win32/>) don't have this
-problem.
+Also, some OpenType fonts lead to F<pl> and F<vpl> files that
+are too big for MiKTeX's F<pltotf> and F<vptovf>;
+the versions that come with W32TeX (F<http://www.w32tex.org>)
+and TeXLive (F<http://tug.org/texlive>) don't have this problem.
=head1 COMMAND-LINE OPTIONS
+You may use either one or two dashes before options,
+and option names may be shortened to a unique prefix
+(e.g., B<-enc> instead of B<-encoding>).
+
=over 4
-=item B< --encoding>=I<encoding[,encoding]>
+=item B<-encoding>=I<encoding[,encoding]>
+
+Use the specified encodings for the text fonts. The default is "OT1,T1,LY1".
+For each encoding, a file F<< <encoding>.enc >> (in all I<lowercase>)
+should be somewhere where F<otftotfm> can find it. Suitable encoding files
+for OT1, T1/TS1 and LY1 come with B<autoinst>. (Note that these files are
+called F<fontools_ot1.enc> etc. to avoid name clashes with other packages;
+the "fontools_" prefix doesn't need to be specified.)
-Use the encoding I<encoding> for the text fonts. The default is `LY1'.
-A file named `<I<encoding>>.enc' (in all I<lowercase>) should be somewhere
-where F<otftotfm> can find it. Suitable encoding files
-for LY1, OT1 and T1/TS1 come with I<fontools>. (Note that these files are
-called I<fontools_xxx.enc> to avoid name clashes with other packages;
-the `fontools_' prefix doesn't need to be specified.)
+Multiple text encodings can be specified as a comma-separated list:
+C<-encoding=OT1,T1>. The encodings are passed to F<fontenc> in the order
+specified, so the last one will be the default text encoding.
-Multiple text encodings can be specified as well: C< --encoding=OT1,T1,LY1>.
-The encodings are passed to F<fontenc> in the order specified,
-so the last one will be the default text encoding.
+=item B<-sanserif>
-=item B< --sanserif>
+Install the font as a sanserif font, accessed via C<\sffamily> and C<\textsf>.
+Note that the generated style file redefines C<\familydefault>,
+so including it will still make this font the default text font.
-Install the font as a sanserif font, accessed via C<\sffamily> and C<\textsf>.
-Note that the generated style file redefines C<\familydefault>,
-so including it will make this font the default text font.
+=item B<-typewriter>
-=item B< --typewriter>
+Install the font as a typewriter font, accessed via C<\ttfamily> and
+C<\texttt>.
+Note that the generated style file redefines C<\familydefault>,
+so including it will still make this font the default text font.
-Install the font as a typewriter font, accessed via C<\ttfamily> and
-C<\texttt>.
-Note that the generated style file redefines C<\familydefault>,
-so including it will make this font the default text font.
+=item B<-ts1>
-=item B< --ts1>
+=item B<-nots1>
-=item B< --nots1>
+Turn the creation of TS1-encoded fonts on or off. The default is B<-ts1>
+if the text encodings (see I<-encoding> above) include T1,
+B<-nots1> otherwise.
-Turn the creation of TS1-encoded fonts on or off. The default is B< --ts1>
-if the text encodings (see I< --encoding> above) include T1,
-B< --nots1> otherwise.
+=item B<-smallcaps>
-=item B< --smallcaps>
+=item B<-nosmallcaps>
-=item B< --nosmallcaps>
+Turn the creation of small caps fonts on or off. The default is
+B<-smallcaps>.
-Turn the creation of small caps fonts on or off. The default is
-B< --smallcaps>.
+=item B<-swash>
-=item B< --swash>
+=item B<-noswash>
-=item B< --noswash>
+Turn the creation of swash fonts on or off. The default is B<-swash>.
-Turn the creation of swash fonts on or off. The default is B< --swash>.
+=item B<-titling>
-=item B< --titling>
+=item B<-notitling>
-=item B< --notitling>
+Turn the creation of titling fonts on or off. The default is B<-titling>.
-Turn the creation of titling fonts on or off. The default is B< --notitling>.
+=item B<-superiors>
-=item B< --superiors>
+=item B<-nosuperiors>
-=item B< --nosuperiors>
+Turn the creation of fonts with superior characters on or off.
+The default is B<-superiors>.
-Turn the creation of fonts with superior characters on or off.
-The default is B< --superiors>.
+=item B<-inferiors>
-=item B< --inferiors>
+=item B<-noinferiors>
-=item B< --noinferiors>
+Turn the creation of fonts with inferior digits on or off.
+The default is B<-noinferiors>.
-Turn the creation of fonts with inferior figures on or off.
-The default is B< --noinferiors>.
+=item B<-fractions>
-=item B< --fractions>
+=item B<-nofractions>
-=item B< --nofractions>
+Turn the creation of fonts with numerators and denominators on or off.
+The default is B<-nofractions>.
-Turn the creation of fonts with numerators and denominators on or off.
-The default is B< --nofractions>.
+=item B<-ornaments>
-=item B< --ornaments>
+=item B<-noornaments>
-=item B< --noornaments>
+Turn the creation of ornament fonts on or off. The default is B<-ornaments>.
-Turn the creation of ornament fonts on or off. The default is B< --ornaments>.
+=item B<-target>=I<DIRECTORY>
-=item B< --manual>
+Install all generated files into the TEXMF tree at I<DIRECTORY>.
-Manual mode. By default, B<autoinst> immediately executes all F<otftotfm>
-command lines it generates; with the B< --manual> option, these commands are
-instead written to a batch command file (named `<I<font>>.bat', to make things
-easier for our friends on Windows). Also, the generated F<otftotfm> command
-lines specify the I< --pl> option and leave out the I< --automatic> option;
-this causes human readable (and editable) F<pl> and F<vpl> files to be created
-instead of the default F<tfm> and F<vf> files.
+By default, B<autoinst> searches your $TEXMFLOCAL and $TEXMFHOME paths
+and installs all files into subdirectories of the first writable TEXMF tree
+it finds (or into subdirectories of the current directory,
+if no writable directory is found).
-=item B< --verbose>
+B<Note>: this option gets overriden by the B<-manual> option!
+
+=item B<-manual>
+
+Manual mode. By default, B<autoinst> immediately executes all F<otftotfm>
+command lines it generates; with the B<-manual> option, these commands are
+instead written to a file F<autoinst.bat>.
+Also, the generated F<otftotfm> command lines specify the I< --pl> option
+(which tells F<otftotfm> to generate readable/editable F<pl> and F<vpl> files
+instead of the default F<tfm> and F<vf> files)
+and leave out the I< --automatic> option (which tells F<otftotfm> to
+leave all generated files in the current directory, rather than install
+them into your TEXMF tree).
+
+When using this option, you should run F<pltotf> and F<vptovf> after
+executing all commands,
+to convert the F<pl> and F<vf> files to F<tfm> and F<vf> format.
+
+B<Note>: this option overrides the B<-target> option!
+
+=item B<-verbose>
Verbose mode; print detailed info about what B<autoinst> thinks it's doing.
-=item B< --extra>=I<text>
+=item B<-extra>=I<text>
-Pass I<text> as options to I<otftotfm>. To prevent I<text> from accidentily
+Pass I<text> as options to I<otftotfm>. To prevent I<text> from accidentily
being interpreted as options to B<autoinst>, it should be properly quoted.
+=item B<-figurekern>
+
+=item B<-nofigurekern>
+
+Some fonts provide kerning pairs for tabular figures.
+This is probably unwanted (e.g., numbers in tables won't line up exactly).
+The option B<-nofigurekern> adds extra I< --ligkern> options
+to the command lines for I<otftotfm> to suppress such kerns
+(but only for the "TLF" and "TOsF" families).
+Since this leads to very long command lines (it adds one hundred such options)
+and the problem affects only few fonts, the default is B<-figurekern>.
+
=back
@@ -1568,52 +1770,48 @@ being interpreted as options to B<autoinst>, it should be properly quoted.
Eddie Kohler's TypeTools (F<http://www.lcdf.org/type>).
-Perl is usually pre-installed on Linux and Unix systems;
-on Windows, try ActivePerl (available from F<http://www.activestate.com>)
-or Strawberry Perl (F<http://strawberryperl.com>).
+Perl is pre-installed on most Linux and Unix systems;
+on Windows, try ActiveState's ActivePerl
+(available from F<http://www.activestate.com>)
+or Strawberry Perl (F<http://strawberryperl.com>).
-XeTeX (F<http://www.tug.org/xetex>) is an extension of TeX
-that can natively use any font installed in the operating system
-(including both flavours of OpenType fonts)
-without additional support files.
+XeTeX (F<http://www.tug.org/xetex>) and LuaTeX (F<http://www.luatex.org>)
+are TeX extensions that can use any font (including both flavours of OpenType)
+without TeX-specific support files.
-John Owens' F<otfinst> (available from CTAN) is another wrapper
+John Owens' F<otfinst> (available from CTAN) is another wrapper
around F<otftotfm>, and may work when B<autoinst> doesn't.
-The MinionPro for LaTeX project
-(F<http://developer.berlios.de/projects/minionpro/>, also on CTAN)
-developed very complete support files for Minion Pro (including math),
+The MinionPro for LaTeX project
+(F<http://developer.berlios.de/projects/minionpro/>, also on CTAN)
+developed very complete support files for Minion Pro (including math),
but the project appears to have been abandoned;
-these files don't work with recent versions of Minion Pro.
+these files don't work with the latest versions of Minion Pro.
=head1 AUTHOR
-Marc Penninga <marc@penninga.info>
-
-When sending a bug report, please give as much relevant information as
-possible; this usually includes (but may not be limited to) the output from
-running B<autoinst> with the B< --verbose> option.
-Please make sure that this output includes all error messages (if any);
-this can be done using the command
+Marc Penninga <marcpenninga@gmail.com>
-C<< autoinst I<(... all options and files ...)> E<gt>autoinst.log 2>&1 >>
+When sending a bug report, please give as much relevant information as
+possible; this includes at least (but may not be limited to) the output
+from running B<autoinst> with the I<-verbose> option.
+Please make sure that this output includes all (if any) error messages.
=head1 COPYRIGHT
-Copyright (C) 2005, 2006, 2007, 2009, 2010, 2011 Marc Penninga.
+Copyright (C) 2005-2012 Marc Penninga.
=head1 LICENSE
This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License
-as published by the Free Software Foundation,
-either version 2 of the License, or (at your option)
-any later version.
-A copy of the GNU General Public License is included with the I<fontools>
-collection; see the file F<GPLv2.txt>.
+it under the terms of the GNU General Public License as published
+by the Free Software Foundation, either version 2 of the License,
+or (at your option) any later version.
+A copy of the GNU General Public License is included with B<autoinst>;
+see the file F<GPLv2.txt>.
=head1 DISCLAIMER
@@ -1627,36 +1825,60 @@ GNU General Public License for more details.
=head1 RECENT CHANGES
-(See the source code for the full story.)
+(See the source code for the rest of the story.)
=over 12
+=item I<2012-03-06>
+
+Implemented the "splitting the font family into multiple subfamilies"
+emergency strategy when font info parsing fails.
+Added recognition for a number of unusual widths, weights and shapes.
+
+=item I<2012-02-29>
+
+Fixed a bug in the font parsing code,
+where possible widths, weights and shapes where tested in the wrong order;
+this led to "ExtraLight" fonts being recognised as "Light".
+Added recognition for "Narrow" and "Wide" widths.
+Also added the I<-(no)figurekern> command-line option.
+
+=item I<2012-02-01>
+
+Reorganised the code, and fixed some bugs in the process.
+Added the I<-target> command-line option.
+Made B<autoinst> install the F<fd> and F<sty> files in
+the same TEXMF tree as the other generated files.
+Generate OT1, T1 and LY1 encoded text fonts by default.
+Made I<-titling> a default option (instead of I<-notitling>).
+Updated the documentation.
+
=item I<2011-06-15>
Fixed the font info parsing code for some fonts that are
-too lazy to spell out 'Italic' in full.
+too lazy to spell out "Italic" in full.
=item I<2010-04-29>
-The C< --feature=kern> option is only used for fonts that
+The I< --feature=kern> option is only used for fonts that
contain either a I<kern> feature or a I<kern> table.
-Font feature selection commands in the F<.sty> file are only
-generated for shapes and figure styles that are supported
+Font feature selection commands in the F<sty> file are only
+generated for shapes and figure styles that are supported
by the current font, and whose generation has not been
-turned off using the command line options.
+turned off using the command-line options.
Fixed the font info parsing to work with the Condensed fonts
in the Minion Pro family.
=item I<2010-04-23>
-Always provide the C< --feature=kern> option to F<otftotfm>,
-even if the font doesn't have a I<kern> feature;
+Always provide the I< --feature=kern> option to F<otftotfm>,
+even if the font doesn't have a I<kern> feature;
this will make F<otftotfm> use the I<kern> table if present.
-For fonts without a I<liga> feature, add C< --ligkern>
+For fonts without a I<liga> feature, add I< --ligkern>
options for the common f-ligatures to the F<otftotfm> command line,
so that any ligatures present in the font will still be used.
-Bug fix: the generated F<.sty> files now work for font families
-with names containing digits.
+Bug fix: the generated F<sty> files now work for font families
+with names containing digits.
=item I<2009-04-09>
@@ -1665,13 +1887,16 @@ I<fontools_>, to prevent name clashes with other packages.
=item I<2009-04-06>
-A small patch to the C<make_ornament_encoding> subroutine;
-it now also recognises the I<bullet.xxx> ornament glyphs
-in Adobe's Kepler Pro.
+A small patch to the C<get_orn> subroutine:
+it now also recognises the I<bullet.xxx> ornament glyphs
+in Adobe Kepler Pro.
+
+=back
=begin Really_old_history
+=over 12
=item I<2007-08-07>
@@ -1680,17 +1905,17 @@ Fixed a small bug with filename quoting on Windows.
=item I<2007-07-31>
Changed the tables that map weights and widths to NFSS codes:
-in some extended families (Helvetica Neue), different combinations of
-weight and width were mapped to the same `series'.
+in some extended families, different combinations of
+weight and width were mapped to the same series.
Added a work-around for incorrect size info in some Kepler fonts.
-Fixed a small bug in the generated commands for otftotfm
-(sometimes, the I< --onum> feature was included twice).
+Fixed a small bug in the generated commands for otftotfm
+(sometimes, the "onum" feature was included twice).
Added encoding file for OT1 to the I<fontools> collection.
=item I<2007-07-27>
-Two bugfixes: a closing brace was missing in the generated style file,
-and the NFSS series was formed as `width plus weight' instead of the reverse.
+Two bugfixes: a closing brace was missing in the generated style file,
+and the NFSS series was formed as "width plus weight" instead of the reverse.
=item I<2007-06-10>
@@ -1700,92 +1925,92 @@ caused problems for some other packages.
=item I<2007-06-04>
-Added the F< --no-updmap> option to all generated commands for F<otftotfm>
+Added the I< --no-updmap> option to all generated commands for F<otftotfm>
(except the last); this should yield a significant speed-up for large
families (suggested by Steven E. Harris).
Tweaked the font info parsing to work around a bug in the naming of
some FontFont fonts, where every font is in a family of its own.
-Added the `scaled' option (including the loading of F<xkeyval>)
+Added the "scaled" option (including the loading of F<xkeyval>)
to the generated style file.
-Extended the output of the F< --verbose> option.
+Extended the output of the I<-verbose> option.
=item I<2007-02-08>
-Yet Another Complete Rewrite.
-The code is now much more readable and more flexible;
+Yet Another Complete Rewrite.
+The code is now much more readable and more flexible;
the program can now handle fonts from different families,
-as well as multiple text encodings.
+as well as multiple text encodings.
Rewrote the font info parsing code to work for Arno Pro.
=item I<2006-10-11>
The program determines the fonts' weights, widths and shapes by parsing
-the output from F<otfinfo --info> instead of the font filename.
-This should make B<autoinst> work for non-Adobe fonts.
+the output from C<otfinfo --info> instead of the font filename.
+This should make B<autoinst> work for non-Adobe fonts.
Filenames with spaces now work as well.
=item I<2006-08-31>
-Made the generated style files try to include `fontaxes.sty';
-changed the names of the generated fonts and families
+Made the generated style files try to include "fontaxes.sty";
+changed the names of the generated fonts and families
(to make the previous change possible);
-added command line options for most font styles and shapes;
+added command-line options for most font styles and shapes;
tweaked the filename parsing code for Cronos Pro and Gill Sans Pro;
added runtime generation of encoding vectors for ornament fonts
(because GaramondPremier's ornament names differ from other fonts);
-changed the NFSS-code for italic small caps and titling to `scit' and `tlit'
-(to work with F<fontaxes>);
+changed the NFSS-code for italic small caps and titling to "scit" and "tlit"
+(to work with F<fontaxes>);
and edited (and hopefully improved) the documentation.
=item I<2005-10-03>
-When creating LY1, T1, OT1 or TS1 encoded fonts, the I< --coding-scheme>
-option is added to the commands for F<otftotfm>; this should make the
+When creating LY1, T1, OT1 or TS1 encoded fonts, the I<-coding-scheme>
+option is added to the commands for F<otftotfm>; this should make the
generated F<pl> and F<vpl> files acceptable to I<fontinst>.
Also elaborated the documentation somewhat and fixed a small bug.
=item I<2005-09-22>
-Added check to see if filename parsing succeeded;
-updated the filename parsing code to cater for GaramondPremier, Silentium
+Added check to see if filename parsing succeeded;
+updated the filename parsing code to cater for GaramondPremier, Silentium
and some non-Adobe fonts;
-added the B< --sanserif> and B< --typewriter> options and hacked the
+added the I<-sanserif> and I<-typewriter> options and hacked the
style files to support using several different font families in one document.
=item I<2005-09-12>
Cleaned up the code (it now runs under the F<strict> and F<warnings> pragmas);
-fixed a (rather obscure) bug that occurred when creating TS1-encoded
-fonts for families with multiple optical masters and oldstyle figures;
+fixed a (rather obscure) bug that occurred when creating TS1-encoded
+fonts for families with multiple optical masters and oldstyle digits;
added the I<medium, semibold> etc. options to the style file;
and improved the layout of the generated files.
=item I<2005-08-11>
The generated commands weren't actually executed, only printed....
-Also added a small hack to cater for fonts
-(such as some recent versions of MinionPro)
-that contain swash characters but don't provide a `swsh' feature.
+Also added a small hack to cater for fonts
+(such as some recent versions of MinionPro)
+that contain swash characters but don't provide a "swsh" feature.
=item I<2005-08-10>
-Dropped the `fontname' scheme in favor of a more verbose naming scheme,
-since many filenames were still more than eight characters long anyway.
+Dropped the "fontname" scheme in favor of a more verbose naming scheme,
+since many filenames were still more than eight characters long anyway.
Added F<nfssext.sty>-like commands to the generated style file.
-Changed the default encoding to LY1 and added the `inferior' shape.
+Changed the default encoding to LY1 and added the "inferior" shape.
=item I<2005-08-01>
-Rewrote (and hopefully improved) the user interface;
-changed the program to by default execute the generated F<otftotfm> command
-lines rather than writing them to a file;
-added automatic determination of the `fontname' code for the font family;
-changed the NFSS code for italic small caps to `si'; added titling shapes;
-changed the generated style
-file to include an interface for the ornaments and to load Lehman's NFSS
-extensions F<nfssext.sty> if this is installed; corrected the `fontname' codes
+Rewrote (and hopefully improved) the user interface;
+changed the program to by default execute the generated F<otftotfm> command
+lines rather than writing them to a file;
+added automatic determination of the "fontname" code for the font family;
+changed the NFSS code for italic small caps to "si"; added titling shapes;
+changed the generated style
+file to include an interface for the ornaments and to load Lehman's NFSS
+extensions F<nfssext.sty> if this is installed; corrected the "fontname" codes
for OT1, T1, LY1 and user-specific encodings; extended the output generated by
-the B< --verbose> option; and rewrote and extended the documentation.
+the I<-verbose> option; and rewrote and extended the documentation.
=item I<2005-06-16>
diff --git a/Build/source/texk/texlive/linked_scripts/fontools/cmap2enc b/Build/source/texk/texlive/linked_scripts/fontools/cmap2enc
deleted file mode 100755
index 4ba6842e179..00000000000
--- a/Build/source/texk/texlive/linked_scripts/fontools/cmap2enc
+++ /dev/null
@@ -1,5307 +0,0 @@
-#!/usr/bin/perl
-
-=begin COPYRIGHT ------------------------------------------------------------
-
- cmap2enc - convert glyph indices in a TrueType-flavored OpenType font to
- Adobe glyph names
-
- Copyright (c) 2005, 2006 Marc Penninga.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to
-
- Free Software Foundation, Inc.,
- 59 Temple Place,
- Suite 330,
- Boston, MA 02111-1307,
- USA
-
-=end ------------------------------------------------------------------------
-
-=cut
-
-use Getopt::Std;
-use integer;
-use warnings; no warnings qw(uninitialized);
-
-%friendly_name = (
- aalt => "Access All Alternates",
- afrc => "Alternate Fractions",
- alts => "Alternate Forms",
- calt => "Contextual Alternates",
- case => "Case-Sensitive Forms",
- clig => "Contextual Ligatures",
- cpsp => "Capital Spacing",
- cswh => "Contextual Swash",
- c2sc => "Small Capitals From Capitals",
- dlig => "Discretionary Ligatures",
- dnom => "Denominators",
- expt => "Expert Forms",
- fina => "Terminal Forms",
- frac => "Fractions",
- hist => "Historical Forms",
- hlig => "Historical Ligatures",
- init => "Initial Forms",
- liga => "Standard Ligatures",
- lnum => "Lining Figures",
- numr => "Numerators",
- onum => "Oldstyle Figures",
- ordn => "Ordinals",
- ornm => "Ornaments",
- pnum => "Proportional Figures",
- rlig => "Required Ligatures",
- salt => "Stylistic Alternates",
- sinf => "Scientific Inferiors",
- smcp => "Small Caps",
- subs => "Subscripts",
- sups => "Superscripts",
- swsh => "Swash",
- titl => "Titling",
- tnum => "Tabular Figures",
- zero => "Slashed Zero",
-);
-
-sub getu($) {
- my $arg = shift;
- my $n = length $arg;
- my $r = 0;
-
- for my $i (0 .. $n - 1) {
- $r = ($r << 8) + unpack("C", substr($arg, $i, 1));
- }
-
- return $r;
-}
-
-sub getcov($) {
- my $Coverage = shift;
- my $CoverageFormat = getu(substr $Coverage, 0, 2);
- my @r = ();
- if ($CoverageFormat == 1) {
- my $GlyphCount = getu(substr $Coverage, 2, 2);
- for my $i (0 .. $GlyphCount - 1) {
- push @r, getu(substr $Coverage, 4 + 2 * $i, 2);
- }
- } elsif ($CoverageFormat == 2) {
- my $RangeCount = getu(substr $Coverage, 2, 2);
- for my $i (0 .. $RangeCount - 1) {
- my $RangeRecord = substr $Coverage, 4 + 6 * $i, 6;
- my $Start = getu(substr $RangeRecord, 0, 2);
- my $End = getu(substr $RangeRecord, 2, 2);
- for my $j ($Start .. $End) {
- push @r, $j;
- }
- }
- } else {
- warn "Warning: unknown CoverageFormat `$CoverageFormat'\n";
- }
- return @r;
-}
-
-
-##############################################################################
-
-
-getopts "f:l:ps:x:", \%options;
-if ($options{f}) {
- for (split ",", $options{f}) {
- $feature_selected{$_} = 1;
- }
-}
-$suffix = $feature_selected{ pnum } ? '-' : '-t';
-$suffix .= $feature_selected{ onum } ? 'osf' : 'lf';
-$suffix .= $feature_selected{ smcp } ? '-sc' : '';
-$suffix .= $feature_selected{ swsh } ? '-swash' : '';
-$suffix .= $feature_selected{ titl } ? '-titling' : '';
-
-if ( $feature_selected{ sups } ) { $suffix = '-sup' }
-if ( $feature_selected{ ornm } ) { $suffix = '-orn' }
-
-$options{s} ||= "latn";
-$options{l} ||= "DFLT";
-
-$0 =~ s!.*/!!;
-die "Usage: $0 [options] fontfile encfile\n"
- unless ($options{p} and @ARGV == 1) or @ARGV == 2;
-
-chop(@glyph = <DATA>);
-for (@glyph) {
- next if /^\s*\#/;
- /(.+);([\dA-Fa-f]{4})/ and $code{$1} = $2;
-}
-
-if ((chop($fn = `kpsewhich $ARGV[0] 2>&1`) and -e $fn) or
- (chop($fn = `findtexmf $ARGV[0] 2>&1`) and -e $fn))
-{
- open FONT, "<$fn" or die "Error: can't open `$fn' - $!\n";
-} else {
- open FONT, "<$ARGV[0]" or
- die "Error: can't open `$ARGV[0]' - $!\n";
-}
-binmode FONT;
-{
- local $/;
- $font = <FONT>;
-}
-
-$OffsetTable = substr $font, 0, 12;
-$numTables = getu(substr $OffsetTable, 4, 2);
-
-$TableDirectory = substr $font, 12, 16 * $numTables;
-for $i (0 .. $numTables - 1) {
- $entry = substr $TableDirectory, 16 * $i, 16;
-
- $tag = substr $entry, 0, 4;
- $offset{$tag} = getu(substr $entry, 8, 4);
- $length{$tag} = getu(substr $entry, 12, 4);
-}
-
-if (exists $offset{GSUB}) {
- $GSUB = substr $font, $offset{GSUB}, $length{GSUB};
- $ScriptList = substr $GSUB, getu(substr $GSUB, 4, 2);
- $FeatureList = substr $GSUB, getu(substr $GSUB, 6, 2);
- $LookupList = substr $GSUB, getu(substr $GSUB, 8, 2);
-
- $LookupCount = getu(substr $LookupList, 0, 2);
- undef @Lookup;
- undef @LookupType;
- for $i (0 .. $LookupCount - 1) {
- $Lookup = substr $LookupList, getu(substr $LookupList, 2 + 2 * $i, 2);
- $LookupType[$i] = getu(substr $Lookup, 0, 2);
- next unless $LookupType[$i] == 1;
- $SubTableCount = getu(substr $Lookup, 4, 2);
- for $j (0 .. $SubTableCount - 1) {
- $SubTable = substr $Lookup, getu(substr $Lookup, 6 + 2 * $j, 2);
- $SubstFormat = getu(substr $SubTable, 0, 2);
- if ($SubstFormat == 1) {
- $Coverage = substr $SubTable, getu(substr $SubTable, 2, 2);
- @Coverage = getcov($Coverage);
- $DeltaGlyphID = getu(substr $SubTable, 4, 2);
- for $k (0 .. $#Coverage) {
- $Lookup[$i]{$Coverage[$k]} = $Coverage[$k] + $DeltaGlyphID;
- }
- } elsif ($SubstFormat == 2) {
- $Coverage = substr $SubTable, getu(substr $SubTable, 2, 2);
- @Coverage = getcov($Coverage);
- $GlyphCount = getu(substr $SubTable, 4, 2);
- if ($GlyphCount != scalar(@Coverage)) {
- warn "Error: SingleSubstFormat2 subtable - " .
- "GlyphCount wrong\n";
- next;
- }
- for $k (0 .. $#Coverage) {
- $Lookup[$i]{$Coverage[$k]} =
- getu(substr $SubTable, 6 + 2 * $k, 2);
- }
- } else {
- warn "Error: unknown SingleSubstFormat `$SubstFormat'\n";
- next;
- }
- }
- }
-
- undef @FeatureTag;
- undef @FeatureLookupListIndex;
- $FeatureCount = getu(substr $FeatureList, 0, 2);
- for $i (0 .. $FeatureCount - 1) {
- $FeatureRecord = substr $FeatureList, 2 + 6 * $i, 6;
- $FeatureTag[$i] = substr $FeatureRecord, 0, 4;
- $Feature = substr $FeatureList, getu(substr $FeatureRecord, 4, 2);
- $LookupCount = getu(substr $Feature, 2, 2);
- $feature_supported{$FeatureTag[$i]} = 1;
- for $j (0 .. $LookupCount - 1) {
- $FeatureLookupListIndex[$i][$j] =
- getu(substr $Feature, 4 + 2 * $j, 2);
- if ($LookupType[$FeatureLookupListIndex[$i][$j]] != 1) {
- $feature_supported{$FeatureTag[$i]} = 0;
- }
- }
- }
-
- undef %Script;
- undef %FeatureIndex;
- $ScriptCount = getu(substr $ScriptList, 0, 2);
- for $i (0 .. $ScriptCount - 1) {
- $ScriptRecord = substr $ScriptList, 2 + 6 * $i, 6;
- $ScriptTag = substr $ScriptRecord, 0, 4;
- $Script = substr $ScriptList, getu(substr $ScriptRecord, 4, 2);
- if (substr($Script, 0, 2)) {
- $LangSysTag = "DFLT";
- push @{$Script{$ScriptTag}}, $LangSysTag;
- $LangSys = substr $Script, getu(substr $Script, 0, 2);
- $FeatureCount = getu(substr $LangSys, 4, 2);
- for $k (0 .. $FeatureCount - 1) {
- push @{$FeatureIndex{$ScriptTag}{$LangSysTag}},
- getu(substr $LangSys, 6 + 2 * $k, 2);
- }
- }
- $LangSysCount = getu(substr $Script, 2, 2);
- for $j (0 .. $LangSysCount - 1) {
- $LangSysRecord = substr $Script, 4 + 6 * $j, 6;
- $LangSysTag = substr $LangSysRecord, 0, 4;
- push @{$Script{$ScriptTag}}, $LangSysTag;
- $LangSys = substr $Script, getu(substr $LangSysRecord, 4, 2);
- $FeatureCount = getu(substr $LangSys, 4, 2);
- for $k (0 .. $FeatureCount - 1) {
- push @{$FeatureIndex{$ScriptTag}{$LangSysTag}},
- getu(substr $LangSys, 6 + 2 * $k, 2);
- }
- }
- }
-}
-
-if (exists $offset{GPOS}) {
- $GPOS = substr $font, $offset{GPOS}, $length{GPOS};
- $FeatureList = substr $GPOS, getu(substr $GPOS, 6, 2);
- $FeatureCount = getu(substr $FeatureList, 0, 2);
- for $i (0 .. $FeatureCount - 1) {
- $FeatureRecord = substr $FeatureList, 2 + 6 * $i, 6;
- $FeatureTag = substr $FeatureRecord, 0, 4;
- $feature_supported{$FeatureTag} = 0;
- }
-}
-
-if ($options{p}) {
- if (exists $offset{name}) {
- $name = substr $font, $offset{name}, $length{name};
- $count = getu(substr $name, 2, 2);
- $stringOffset = getu(substr $name, 4, 2);
- for $i (0 .. $count - 1) {
- $nameRecord = substr $name, 6 + 12 * $i, 12;
- $platformID = getu(substr $nameRecord, 0, 2);
- $encodingID = getu(substr $nameRecord, 2, 2);
- $languageID = getu(substr $nameRecord, 4, 2);
- $nameID = getu(substr $nameRecord, 6, 2);
- $length = getu(substr $nameRecord, 8, 2);
- $offset = getu(substr $nameRecord, 10, 2);
- $string = substr $name, $stringOffset + $offset, $length;
- $string{"$platformID,$encodingID,$languageID,$nameID"} = $string;
- }
- print "\n", "-" x 80, "\n\n";
- for $i ((6,10,0)) {
- if (exists $string{"0,3,0,$i"}) {
- print $string{"0,3,0,$i"}, "\n\n";
- } elsif (exists $string{"0,4,0,$i"}) {
- print $string{"0,4,0,$i"}, "\n\n";
- } elsif (exists $string{"3,1,1033,$i"}) {
- print $string{"3,1,1033,$i"}, "\n\n";
- } elsif (exists $string{"3,10,1033,$i"}) {
- print $string{"3,10,1033,$i"}, "\n\n";
- }
- }
- print "-" x 80, "\n\n";
- }
- print "SCRIPT\tLANG\tFEATURES\n\n";
- for $script (keys %Script) {
- print "$script";
- for $lang (@{$Script{$script}}) {
- print "\t$lang\t";
- for (sort {$a <=> $b} @{$FeatureIndex{$script}{$lang}}) {
- print "$FeatureTag[$_]",
- exists $friendly_name{$FeatureTag[$_]}
- ? " - $friendly_name{$FeatureTag[$_]}"
- : " - Unknown Feature",
- $feature_supported{$FeatureTag[$_]}
- ? ""
- : " (not supported by $0)",
- "\n\t\t";
- }
- print "\n";
- }
- }
- print "-" x 80, "\n\n";
-}
-
-undef @subst;
-for $i (0 .. 0xFFFF) {
- $subst[$i] = $i;
-}
-
-undef %lookup_selected;
-for $feature (sort {$a <=> $b} @{$FeatureIndex{$options{s}}{$options{l}}}) {
- if (!$feature_selected{$FeatureTag[$feature]}) {
- next;
- }
- if (!$feature_supported{$FeatureTag[$feature]}) {
- warn "Warning: feature `$FeatureTag[$feature]' not supported\n";
- next;
- }
- for (@{$FeatureLookupListIndex[$feature]}) {
- $lookup_selected{$_} = 1;
- }
-}
-for $lookup (sort {$a <=> $b} keys %lookup_selected) {
- for (sort {$a <=> $b} keys %{$Lookup[$lookup]}) {
- $subst[$_] = $Lookup[$lookup]{$_};
- }
-}
-
-if ($options{x}) {
- open SUB, "<$options{x}"
- or warn "Warning: can't open `$options{x}' - $!\n\tfile skipped\n";
- for (<SUB>) {
- if (/^\s*\#/) {
- next;
- } elsif (/([0-9A-Fa-f]{4});([0-9A-Fa-f]{4})/) {
- $subst[hex($1)] = hex($2);
- $subst[hex($2)] = hex($2);
- } elsif (/(\w+);([0-9A-Fa-f]{4})/) {
- $glyphName{$1} ||= sprintf
- hex($2) < 256 ? "index0x%02X" : "index0x%04X", hex $2;
- delete $code{$1};
- $subst[hex($2)] = hex($2);
- }
- }
-}
-
-$cmap = substr $font, $offset{cmap}, $length{cmap};
-$numTables = getu(substr $cmap, 2, 2);
-
-for $i (0 .. $numTables - 1) {
- $EncodingRecord = substr $cmap, 4 + $i * 8, 8;
- $platformID = getu(substr $EncodingRecord, 0, 2);
- $encodingID = getu(substr $EncodingRecord, 2, 2);
- $offset = getu(substr $EncodingRecord, 4, 4);
- $format = getu(substr $cmap, $offset, 2);
- $length = getu(substr $cmap, $offset + 2, 2);
- $subtable = substr $cmap, $offset, $length;
-
- next unless ($platformID == 0 and ($encodingID == 3 or $encodingID == 4))
- or ($platformID == 3 and ($encodingID == 1 or $encodingID == 10));
-
- if ($format == 4) {
- $segCountX2 = getu(substr $subtable, 6, 2);
- $segCount = $segCountX2 / 2;
-
- $endCount = substr $subtable, 14, $segCountX2;
- $startCount = substr $subtable, 16 + $segCountX2, $segCountX2;
- $idDelta = substr $subtable, 16 + 2 * $segCountX2, $segCountX2;
- $idRangeOffset = substr $subtable, 16 + 3 * $segCountX2, $segCountX2;
-
- for $j (0 .. $segCount - 1) {
- $endCount[$j] = getu(substr $endCount, 2 * $j, 2);
- $startCount[$j] = getu(substr $startCount, 2 * $j, 2);
- $idDelta[$j] = getu(substr $idDelta, 2 * $j, 2);
- $idRangeOffset[$j] = getu(substr $idRangeOffset, 2 * $j, 2);
-
- next if $startCount[$j] == 0xFFFF;
-
- for $characterCode ($startCount[$j] .. $endCount[$j]) {
- if ($idRangeOffset[$j] != 0) {
- $ptr = $idRangeOffset[$j] / 2
- + $characterCode - $startCount[$j]
- + 8 + 3 * $segCount
- + $j;
- $tmp = getu(substr $subtable, 2 * $ptr, 2);
- if ($tmp) {
- $glyphIndex = ($tmp + $idDelta[$j]) % 65536;
- } else {
- $glyphIndex = 0;
- }
- } else {
- $glyphIndex = ($characterCode + $idDelta[$j]) % 65536;
- }
- $glyphIndex = $subst[$glyphIndex];
- $uni = sprintf "%04X", $characterCode;
- $glyphName{$uni} ||= sprintf
- $glyphIndex < 256 ? "index0x%02X" : "index0x%04X",
- $glyphIndex;
- }
- }
- last;
- } else {
- warn "Warning: unsupported format `$format'\n";
- }
-}
-if (!keys %glyphName) {
- die "Error: no supported platformID/encodingID found in `cmap' table\n";
-}
-
-if (!$options{p}) {
- if ((chop($fn = `kpsewhich $ARGV[1] 2>&1`) and -e $fn) or
- (chop($fn = `findtexmf $ARGV[1] 2>&1`) and -e $fn))
- {
- open ENC, "<$fn" or die "Error: can't open `$fn' - $!\n";
- } else {
- open ENC, "<$ARGV[1]" or die "Error: can't open `$ARGV[1]' - $!\n";
- }
- chop(@lines = <ENC>);
- map s/%.+//, @lines;
- $_ = join "", @lines;
- ($name, $_) = /\/([\w-]+)\s*\[(.*)\]\s*def/;
- @vector = /([\w.]+)/g;
-
- $ARGV[0] =~ /(.+)\.(?:ttf|otf)/ and $fontname = $1;
- $ARGV[1] =~ /(.+)\.enc/ and $encname = $1;
- open ENC, ">${encname}${suffix}-${fontname}.enc" or die
- "Error: can't open `${encname}${suffix}-${fontname}.enc' - $!\n";
- print ENC "/${name}${suffix}-${fontname} [\n";
- for ($i = 0; $i < 256; $i += 16) {
- printf ENC "%% 0x%04x\n", $i;
- for ($j = 0; $j < 16; $j += 4) {
- for $k (0 .. 3) {
- print ENC " /",
- $glyphName{$code{$vector[$i + $j + $k]}} ||
- $glyphName{$vector[$i + $j + $k]} ||
- $vector[$i + $j + $k];
- }
- print ENC "\n";
- }
- }
- print ENC "] def\n";
-
- open MTX, ">reset${fontname}-${encname}${suffix}.mtx"
- or die "Error: can't open " .
- "'reset${fontname}-${encname}${suffix}.mtx' - $!\n";
- print MTX <<EOF;
-\\relax
-\\metrics
-\\needsfontinstversion{1.900}
-
-\\setcommand\\deleteGlyph#1{
- \\ifisglyph{#1}\\then
- \\unsetglyph{#1}
- \\noleftrightkerning{#1}
- \\fi
-}
-
-\\setcommand\\renameGlyph#1#2{
- \\ifisglyph{#1}\\then
- \\setglyph{#2}
- \\glyph{#1}{1000}
- \\endsetglyph
- \\setleftrightkerning{#2}{#1}{1000}
- \\deleteGlyph{#1}
- \\fi
-}
-
-EOF
-
- for (@vector) {
- if ($glyphName{$code{$_}}) {
- print MTX "\\renameGlyph{$glyphName{$code{$_}}}{$_}\n";
- } elsif ($glyphName{$_}) {
- print MTX "\\renameGlyph{$glyphName{$_}}{$_}\n";
- }
- }
- print MTX "\n\\endmetrics\n";
-}
-
-__END__
-
-=pod
-
-
-=head1 NAME
-
-cmap2enc - convert glyph indices in a TrueType-flavored OpenType font to
-Adobe glyph names
-
-
-=head1 SYNOPSIS
-
-cmap2enc [options] I<fontfile> I<encoding>
-
-
-=head1 DESCRIPTION
-
-Many TrueType-flavored OpenType fonts contain no glyph names.
-When creating an F<afm> file with F<ttf2afm>, this causes all glyphs to be
-named something
-like C<index0x01E7>, which makes the F<afm> file almost useless for use with
-F<fontinst> or F<afm2tfm>.
-
-B<cmap2enc> uses the font's `cmap' table to map glyph indices to
-Unicode values, and Adobe's F<glyphlist.txt> file to map these to glyph names.
-
-B<cmap2enc> creates a new encoding file (for downloading with the font file)
-and a F<mtx> file (for use with F<fontinst>). The encoding file contains the
-same glyphs as the original one, but has all glyph names replaced with
-the corresponding glyph indices; the F<mtx> file maps these glyph indices back
-to the original glyph names (it consists of many commands of the form
-C<\renameGlyph{index0x01E7}{Euro}>, plus a definition of that
-C<\renameGlyph> command).
-
-Some of the glyph substitution features of OpenType fonts are supported;
-e.g. when the `smcp' (Small Caps) feature is specified, the glyph names
-of the lowercase glyphs will be mapped to the glyph indices of the
-small capitals.
-
-A list of features supported by the font can be generated using the B<-p>
-option, see below.
-
-
-=head1 EXAMPLES
-
-NOTE: the F<examples/> subdirectory in the I<fontools> distribution contains
-several complete examples of the use of B<cmap2enc> and other tools from
-the I<fontools> collection.
-
-=over 2
-
-=item B<->
-
-To display all scripts, languages and features supported by Linotype Palatino:
-
- cmap2enc -p pala.ttf
-
-
-=item B<->
-
-To install Linotype Palatino in T1 encoding, with oldstyle figures:
-
-=over 3
-
-=item B<1.>
-
-Generate an encoding file F<t1-tosf-pala.enc> and a metrics file
-F<resetpala-t1-osf.mtx>:
-
- cmap2enc -f onum pala.ttf t1.enc
-
-
-=item B<2.>
-
-Create an F<afm> file for the font; this is done best using I<font2afm>
-(also in the I<fontools> collection):
-
- font2afm pala.ttf
-
-
-=item B<3.>
-
-Reencode the F<afm> file using the F<t1-tosf-pala.enc> encoding to create
-a `raw' font I<rlplrj9d>, with either I<afm2afm> (also in the I<fontools>
-collection) or I<fontinst> (but be warned that I<fontinst> might take a long
-time, and can even crash if the F<afm> is really big):
-
- afm2afm -e t1-tosf-pala.enc -o rlplrj9d.afm pala.afm
-
-or
-
- \transformfont{rlplrj9d}{\reencodefont{t1-tosf-pala}{\fromafm{pala}}}
-
-
-=item B<4.>
-
-Create a `value-added' F<vpl> file from this raw font by adding
-ligatures, faking missing glyphs etc. with I<fontinst>:
-
- \installfont{lplrj9d}{rlplrj9d,resetpala-t1-tosf,newlatin}
- {t1}{T1}{lplj}{m}{n}{}
-
-
-=back
-
-=back
-
-
-=head1 OPTIONS
-
-B<cmap2enc> supports the following command-line options:
-
-=over 4
-
-=item B<-p>
-
-Print some info about the font, plus a list of all scripts, languages and
-features contained in this font's GSUB table; then exit. (When using
-this option, the I<encoding> need not be specified.)
-
-=item B<-f> I<feature>[,I<feature>]*
-
-Use the specified features when matching glyph indices to glyph names.
-Multiple features can be specified as a comma-separated list,
-B<without> spaces between the items.
-
-=item B<-x> I<extra>
-
-Use the user-specified substitutions from I<extra> (see below).
-
-=item B<-l> I<language>
-
-Select the specified language. The default is `DFLT' (surprise!).
-
-=item B<-s> I<script>
-
-Select the specified script. The default is `latn'.
-
-=back
-
-
-=head1 FILES
-
-All input files are searched using B<kpsewhich> or B<findtexmf> when these
-commands are available; otherwise only the current working directory
-is searched.
-
-=over 4
-
-=item I<fontfile>
-
-The font file can be any OpenType font, though B<cmap2enc> is probably only
-useful for the TrueType-flavored variant (PostScript-flavored ones always
-contain glyph names in the `CFF' table).
-
-=item I<encoding>
-
-The encoding files read and written by B<cmap2enc> are in standard F<dvips>
-format. The name of the output encoding file is
-C<< <encoding>-<suffix>-<font>.enc >>,
-
-where
-
-=over 10
-
-=item B<encoding>
-
-is the name of the input encoding file (without the extension `.enc');
-
-=item B<suffix>
-
-names the OpenType features you specified:
-
-=over 10
-
-=item I<tlf>
-
-for tabular lining figures (when neither the `onum' nor the `pnum' features
-have been chosen)
-
-=item I<lf>
-
-for proportional width lining figures (when you've specified `pnum',
-but not `onum')
-
-=item I<tosf>
-
-for tabular oldstyle figures (when you've specified `onum', but not `pnum')
-
-=item I<osf>
-
-for proportional width oldstyle figures (when both `onum' and `pnum' have been
-chosen)
-
-=item I<sc>
-
-for small caps (`smcp' feature)
-
-=item I<swash>
-
-for swash (`swsh' feature)
-
-=item I<titling>
-
-for a titling font (`titl' feature)
-
-=item I<sup>
-
-for superior figures and (some) letters (`sups' feature)
-
-=item I<orn>
-
-for ornaments (`ornm' feature)
-
-=back
-
-When several features have been specified, the B<suffix> is a combination
-of the appropriate items; e.g., when you specify -f onum,pnum,swsh (for a
-swash font with proportional oldstyle figures) the B<suffix> is
-C<osf-swash>.
-
-=item B<font>
-
-is the name of the input font file, without the `.ttf' or `.otf' extension.
-
-=back
-
-=item I<mtx>
-
-The output F<mtx> file is in standard F<fontinst> format. The name of this file
-is C<< reset<font>-<encoding>-<suffix>.mtx >>,
-
-where I<font>, I<encoding> and I<suffix> have the same meaning as above.
-
-=item I<extra>
-
-The option B<-x> can be used to name a file containing extra substitutions
-that complement or override the ones specified by the selected features.
-It consists of one substitution per line; each is either of the form
-C<< <from>;<to> >>, where I<from> and I<to> are both glyph indices
-(specified as four hexadecimal digits), or of the form
-C<< <glyph name>;<glyph index> >>, where I<glyph name> is any glyph name
-and I<glyph index> the glyph index (again, four hex digits) that is to be
-mapped to the specified glyph name. The F<examples/> subdirectory in the
-I<fontools> distribution contains some examples of user-defined
-substitution files.
-
-
-=back
-
-=head1 CAVEATS
-
-=over 2
-
-=item B<->
-
-Most OpenType fonts contain several tables in the `cmap' table,
-for different platforms and different encodings.
-B<cmap2enc> only reads the first table that implements Unicode, that is,
-the first table with either platformID = 0 and encodingID = 3 or 4
-or platformID = 3 and encodingID = 1 or 10.
-At least one of those will probably always be present, and (afaik) it doesn't
-matter which of these is used.
-
-The fact that only tableFormat = 4 is supported might be more of a restriction,
-though I haven't yet found any font that used a different tableFormat.
-
-=item B<->
-
-OpenType fonts implement features using so-called `Lookup Tables'.
-B<cmap2enc> supports only features from the `GSUB' table that have
-LookupType = 1 (single substitution).
-
-Some features are implemented as a combination of lookups from both
-the `GSUB' and the `GPOS' tables; these features are (currently?)
-not supported. An example of this are the `sinf' (Scientific Inferiors) and
-'subs' (Subscripts) features of Linotype Palatino; these are implemented
-by first replacing the standard numerals with smaller ones and then
-adjusting their position.
-
-=item B<->
-
-Some of the font's features may yield surprising results. E.g., Linotype
-Palatino doesn't have small-caps forms of dotlessi, germandbls and the
-standard f-ligatures, so it will give you the lowercase forms of these glyphs
-even when the `smcp' feature is specified.
-(The F<examples/palatinox> subdirectory contains a file F<unsetSCaps.mtx>
-that deletes these lowercase forms; F<fontinst>'s F<newlatin.mtx> file
-will then create fake small-caps forms of these glyphs.)
-
-=item B<->
-
-If the user-defined substitution file substitutes glyph1 with glyph2,
-B<cmap2enc> will also substitute glyph2 with glyph2; this may seem silly,
-but it means that any selected feature that would substitute glyph2 with glyph3
-gets overridden.
-
-=item B<->
-
-The glyph names are independent of the features selected, e.g., when using
-features like `smcp' or `onum', glyph names still come out as `a' and `zero'
-rather than `Asmall' and `zerooldstyle'. When installing the font with
-F<fontinst>, you should therefore always use F<t1.etx> rather than F<t1c.etx>
-or F<t1j.etx>.
-
-=back
-
-
-=head1 SEE ALSO
-
-The other programs in the I<fontools> bundle: F<afm2afm>, F<autoinst>,
-F<font2afm>, F<ot2kpx>, F<pfm2kpx>, F<showglyphs>.
-
-A good free (as in beer) Perl-implementation for Windows (and Linux)
-is ActivePerl, available from F<http://www.activestate.com>.
-
-
-=head1 AUTHOR
-
-Marc Penninga <marc@penninga.info>
-
-If you're sending a bug report, please give as much information as possible.
-Also be sure to mention the name I<fontools> somewhere in the subject line,
-or risk being caught by my spam filter.
-
-
-=head1 COPYRIGHT
-
-Copyright (c) 2005, 2006 Marc Penninga.
-
-
-=head1 LICENSE
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of version 2 of the GNU General Public License
-as published by the Free Software Foundation.
-
-A copy of the GNU General Public License is included with the I<fontools>
-collection; see the file F<GPLv2.txt>.
-
-
-=head1 DISCLAIMER
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-
-=head1 HISTORY
-
-=over 12
-
-=item I<2006-01-17>
-
-Changed the names of the generated output files; extended the documentation.
-
-=item I<2005-08-01>
-
-Removed some warning messages that didn't convey any useful information;
-added contents of F<glyphlist.txt> to the program itself and removed
-the file from the F<fontools> collection;
-expanded the example in the documentation
-
-=item I<2005-04-29>
-
-Improved the documentation
-
-=item I<2005-03-21>
-
-Fixed somed bugs; added `titl' feature
-
-=item I<2005-03-15>
-
-Input files searched using B<kpsewhich> or B<findtexmf>
-
-=item I<2005-03-08>
-
-Input files searched via B<kpsewhich> (where available)
-
-=item I<2005-02-18>
-
-Rewrote some of the code, fixed a few bugs
-
-=item I<2005-01-10>
-
-First version
-
-=back
-
-=cut
-
-
-
-# Contents: The Adobe Glyph List, followed by extensions for TeX fonts and
-# encodings. We also extend the second field so that it can contain
-# multiple Unicode scalar values, separated by semicolons, analogous to
-# otftotfm's "% UNICODING" comments.
-###############################################################################
-# Name: Adobe Glyph List
-# Table version: 2.0
-# Date: September 20, 2002
-#
-# See http://partners.adobe.com/asn/developer/typeforum/unicodegn.html
-#
-# Format: Semicolon-delimited fields:
-# (1) glyph name
-# (2) Unicode scalar value
-A;0041
-AE;00C6
-AEacute;01FC
-AEmacron;01E2
-AEsmall;F7E6
-Aacute;00C1
-Aacutesmall;F7E1
-Abreve;0102
-Abreveacute;1EAE
-Abrevecyrillic;04D0
-Abrevedotbelow;1EB6
-Abrevegrave;1EB0
-Abrevehookabove;1EB2
-Abrevetilde;1EB4
-Acaron;01CD
-Acircle;24B6
-Acircumflex;00C2
-Acircumflexacute;1EA4
-Acircumflexdotbelow;1EAC
-Acircumflexgrave;1EA6
-Acircumflexhookabove;1EA8
-Acircumflexsmall;F7E2
-Acircumflextilde;1EAA
-Acute;F6C9
-Acutesmall;F7B4
-Acyrillic;0410
-Adblgrave;0200
-Adieresis;00C4
-Adieresiscyrillic;04D2
-Adieresismacron;01DE
-Adieresissmall;F7E4
-Adotbelow;1EA0
-Adotmacron;01E0
-Agrave;00C0
-Agravesmall;F7E0
-Ahookabove;1EA2
-Aiecyrillic;04D4
-Ainvertedbreve;0202
-Alpha;0391
-Alphatonos;0386
-Amacron;0100
-Amonospace;FF21
-Aogonek;0104
-Aring;00C5
-Aringacute;01FA
-Aringbelow;1E00
-Aringsmall;F7E5
-Asmall;F761
-Atilde;00C3
-Atildesmall;F7E3
-Aybarmenian;0531
-B;0042
-Bcircle;24B7
-Bdotaccent;1E02
-Bdotbelow;1E04
-Becyrillic;0411
-Benarmenian;0532
-Beta;0392
-Bhook;0181
-Blinebelow;1E06
-Bmonospace;FF22
-Brevesmall;F6F4
-Bsmall;F762
-Btopbar;0182
-C;0043
-Caarmenian;053E
-Cacute;0106
-Caron;F6CA
-Caronsmall;F6F5
-Ccaron;010C
-Ccedilla;00C7
-Ccedillaacute;1E08
-Ccedillasmall;F7E7
-Ccircle;24B8
-Ccircumflex;0108
-Cdot;010A
-Cdotaccent;010A
-Cedillasmall;F7B8
-Chaarmenian;0549
-Cheabkhasiancyrillic;04BC
-Checyrillic;0427
-Chedescenderabkhasiancyrillic;04BE
-Chedescendercyrillic;04B6
-Chedieresiscyrillic;04F4
-Cheharmenian;0543
-Chekhakassiancyrillic;04CB
-Cheverticalstrokecyrillic;04B8
-Chi;03A7
-Chook;0187
-Circumflexsmall;F6F6
-Cmonospace;FF23
-Coarmenian;0551
-Csmall;F763
-D;0044
-DZ;01F1
-DZcaron;01C4
-Daarmenian;0534
-Dafrican;0189
-Dcaron;010E
-Dcedilla;1E10
-Dcircle;24B9
-Dcircumflexbelow;1E12
-Dcroat;0110
-Ddotaccent;1E0A
-Ddotbelow;1E0C
-Decyrillic;0414
-Deicoptic;03EE
-Delta;2206
-Deltagreek;0394
-Dhook;018A
-Dieresis;F6CB
-DieresisAcute;F6CC
-DieresisGrave;F6CD
-Dieresissmall;F7A8
-Digammagreek;03DC
-Djecyrillic;0402
-Dlinebelow;1E0E
-Dmonospace;FF24
-Dotaccentsmall;F6F7
-Dslash;0110
-Dsmall;F764
-Dtopbar;018B
-Dz;01F2
-Dzcaron;01C5
-Dzeabkhasiancyrillic;04E0
-Dzecyrillic;0405
-Dzhecyrillic;040F
-E;0045
-Eacute;00C9
-Eacutesmall;F7E9
-Ebreve;0114
-Ecaron;011A
-Ecedillabreve;1E1C
-Echarmenian;0535
-Ecircle;24BA
-Ecircumflex;00CA
-Ecircumflexacute;1EBE
-Ecircumflexbelow;1E18
-Ecircumflexdotbelow;1EC6
-Ecircumflexgrave;1EC0
-Ecircumflexhookabove;1EC2
-Ecircumflexsmall;F7EA
-Ecircumflextilde;1EC4
-Ecyrillic;0404
-Edblgrave;0204
-Edieresis;00CB
-Edieresissmall;F7EB
-Edot;0116
-Edotaccent;0116
-Edotbelow;1EB8
-Efcyrillic;0424
-Egrave;00C8
-Egravesmall;F7E8
-Eharmenian;0537
-Ehookabove;1EBA
-Eightroman;2167
-Einvertedbreve;0206
-Eiotifiedcyrillic;0464
-Elcyrillic;041B
-Elevenroman;216A
-Emacron;0112
-Emacronacute;1E16
-Emacrongrave;1E14
-Emcyrillic;041C
-Emonospace;FF25
-Encyrillic;041D
-Endescendercyrillic;04A2
-Eng;014A
-Enghecyrillic;04A4
-Enhookcyrillic;04C7
-Eogonek;0118
-Eopen;0190
-Epsilon;0395
-Epsilontonos;0388
-Ercyrillic;0420
-Ereversed;018E
-Ereversedcyrillic;042D
-Escyrillic;0421
-Esdescendercyrillic;04AA
-Esh;01A9
-Esmall;F765
-Eta;0397
-Etarmenian;0538
-Etatonos;0389
-Eth;00D0
-Ethsmall;F7F0
-Etilde;1EBC
-Etildebelow;1E1A
-Euro;20AC
-Ezh;01B7
-Ezhcaron;01EE
-Ezhreversed;01B8
-F;0046
-Fcircle;24BB
-Fdotaccent;1E1E
-Feharmenian;0556
-Feicoptic;03E4
-Fhook;0191
-Fitacyrillic;0472
-Fiveroman;2164
-Fmonospace;FF26
-Fourroman;2163
-Fsmall;F766
-G;0047
-GBsquare;3387
-Gacute;01F4
-Gamma;0393
-Gammaafrican;0194
-Gangiacoptic;03EA
-Gbreve;011E
-Gcaron;01E6
-Gcedilla;0122
-Gcircle;24BC
-Gcircumflex;011C
-Gcommaaccent;0122
-Gdot;0120
-Gdotaccent;0120
-Gecyrillic;0413
-Ghadarmenian;0542
-Ghemiddlehookcyrillic;0494
-Ghestrokecyrillic;0492
-Gheupturncyrillic;0490
-Ghook;0193
-Gimarmenian;0533
-Gjecyrillic;0403
-Gmacron;1E20
-Gmonospace;FF27
-Grave;F6CE
-Gravesmall;F760
-Gsmall;F767
-Gsmallhook;029B
-Gstroke;01E4
-H;0048
-H18533;25CF
-H18543;25AA
-H18551;25AB
-H22073;25A1
-HPsquare;33CB
-Haabkhasiancyrillic;04A8
-Hadescendercyrillic;04B2
-Hardsigncyrillic;042A
-Hbar;0126
-Hbrevebelow;1E2A
-Hcedilla;1E28
-Hcircle;24BD
-Hcircumflex;0124
-Hdieresis;1E26
-Hdotaccent;1E22
-Hdotbelow;1E24
-Hmonospace;FF28
-Hoarmenian;0540
-Horicoptic;03E8
-Hsmall;F768
-Hungarumlaut;F6CF
-Hungarumlautsmall;F6F8
-Hzsquare;3390
-I;0049
-IAcyrillic;042F
-IJ;0132
-IUcyrillic;042E
-Iacute;00CD
-Iacutesmall;F7ED
-Ibreve;012C
-Icaron;01CF
-Icircle;24BE
-Icircumflex;00CE
-Icircumflexsmall;F7EE
-Icyrillic;0406
-Idblgrave;0208
-Idieresis;00CF
-Idieresisacute;1E2E
-Idieresiscyrillic;04E4
-Idieresissmall;F7EF
-Idot;0130
-Idotaccent;0130
-Idotbelow;1ECA
-Iebrevecyrillic;04D6
-Iecyrillic;0415
-Ifraktur;2111
-Igrave;00CC
-Igravesmall;F7EC
-Ihookabove;1EC8
-Iicyrillic;0418
-Iinvertedbreve;020A
-Iishortcyrillic;0419
-Imacron;012A
-Imacroncyrillic;04E2
-Imonospace;FF29
-Iniarmenian;053B
-Iocyrillic;0401
-Iogonek;012E
-Iota;0399
-Iotaafrican;0196
-Iotadieresis;03AA
-Iotatonos;038A
-Ismall;F769
-Istroke;0197
-Itilde;0128
-Itildebelow;1E2C
-Izhitsacyrillic;0474
-Izhitsadblgravecyrillic;0476
-J;004A
-Jaarmenian;0541
-Jcircle;24BF
-Jcircumflex;0134
-Jecyrillic;0408
-Jheharmenian;054B
-Jmonospace;FF2A
-Jsmall;F76A
-K;004B
-KBsquare;3385
-KKsquare;33CD
-Kabashkircyrillic;04A0
-Kacute;1E30
-Kacyrillic;041A
-Kadescendercyrillic;049A
-Kahookcyrillic;04C3
-Kappa;039A
-Kastrokecyrillic;049E
-Kaverticalstrokecyrillic;049C
-Kcaron;01E8
-Kcedilla;0136
-Kcircle;24C0
-Kcommaaccent;0136
-Kdotbelow;1E32
-Keharmenian;0554
-Kenarmenian;053F
-Khacyrillic;0425
-Kheicoptic;03E6
-Khook;0198
-Kjecyrillic;040C
-Klinebelow;1E34
-Kmonospace;FF2B
-Koppacyrillic;0480
-Koppagreek;03DE
-Ksicyrillic;046E
-Ksmall;F76B
-L;004C
-LJ;01C7
-LL;F6BF
-Lacute;0139
-Lambda;039B
-Lcaron;013D
-Lcedilla;013B
-Lcircle;24C1
-Lcircumflexbelow;1E3C
-Lcommaaccent;013B
-Ldot;013F
-Ldotaccent;013F
-Ldotbelow;1E36
-Ldotbelowmacron;1E38
-Liwnarmenian;053C
-Lj;01C8
-Ljecyrillic;0409
-Llinebelow;1E3A
-Lmonospace;FF2C
-Lslash;0141
-Lslashsmall;F6F9
-Lsmall;F76C
-M;004D
-MBsquare;3386
-Macron;F6D0
-Macronsmall;F7AF
-Macute;1E3E
-Mcircle;24C2
-Mdotaccent;1E40
-Mdotbelow;1E42
-Menarmenian;0544
-Mmonospace;FF2D
-Msmall;F76D
-Mturned;019C
-Mu;039C
-N;004E
-NJ;01CA
-Nacute;0143
-Ncaron;0147
-Ncedilla;0145
-Ncircle;24C3
-Ncircumflexbelow;1E4A
-Ncommaaccent;0145
-Ndotaccent;1E44
-Ndotbelow;1E46
-Nhookleft;019D
-Nineroman;2168
-Nj;01CB
-Njecyrillic;040A
-Nlinebelow;1E48
-Nmonospace;FF2E
-Nowarmenian;0546
-Nsmall;F76E
-Ntilde;00D1
-Ntildesmall;F7F1
-Nu;039D
-O;004F
-OE;0152
-OEsmall;F6FA
-Oacute;00D3
-Oacutesmall;F7F3
-Obarredcyrillic;04E8
-Obarreddieresiscyrillic;04EA
-Obreve;014E
-Ocaron;01D1
-Ocenteredtilde;019F
-Ocircle;24C4
-Ocircumflex;00D4
-Ocircumflexacute;1ED0
-Ocircumflexdotbelow;1ED8
-Ocircumflexgrave;1ED2
-Ocircumflexhookabove;1ED4
-Ocircumflexsmall;F7F4
-Ocircumflextilde;1ED6
-Ocyrillic;041E
-Odblacute;0150
-Odblgrave;020C
-Odieresis;00D6
-Odieresiscyrillic;04E6
-Odieresissmall;F7F6
-Odotbelow;1ECC
-Ogoneksmall;F6FB
-Ograve;00D2
-Ogravesmall;F7F2
-Oharmenian;0555
-Ohm;2126
-Ohookabove;1ECE
-Ohorn;01A0
-Ohornacute;1EDA
-Ohorndotbelow;1EE2
-Ohorngrave;1EDC
-Ohornhookabove;1EDE
-Ohorntilde;1EE0
-Ohungarumlaut;0150
-Oi;01A2
-Oinvertedbreve;020E
-Omacron;014C
-Omacronacute;1E52
-Omacrongrave;1E50
-Omega;2126
-Omegacyrillic;0460
-Omegagreek;03A9
-Omegaroundcyrillic;047A
-Omegatitlocyrillic;047C
-Omegatonos;038F
-Omicron;039F
-Omicrontonos;038C
-Omonospace;FF2F
-Oneroman;2160
-Oogonek;01EA
-Oogonekmacron;01EC
-Oopen;0186
-Oslash;00D8
-Oslashacute;01FE
-Oslashsmall;F7F8
-Osmall;F76F
-Ostrokeacute;01FE
-Otcyrillic;047E
-Otilde;00D5
-Otildeacute;1E4C
-Otildedieresis;1E4E
-Otildesmall;F7F5
-P;0050
-Pacute;1E54
-Pcircle;24C5
-Pdotaccent;1E56
-Pecyrillic;041F
-Peharmenian;054A
-Pemiddlehookcyrillic;04A6
-Phi;03A6
-Phook;01A4
-Pi;03A0
-Piwrarmenian;0553
-Pmonospace;FF30
-Psi;03A8
-Psicyrillic;0470
-Psmall;F770
-Q;0051
-Qcircle;24C6
-Qmonospace;FF31
-Qsmall;F771
-R;0052
-Raarmenian;054C
-Racute;0154
-Rcaron;0158
-Rcedilla;0156
-Rcircle;24C7
-Rcommaaccent;0156
-Rdblgrave;0210
-Rdotaccent;1E58
-Rdotbelow;1E5A
-Rdotbelowmacron;1E5C
-Reharmenian;0550
-Rfraktur;211C
-Rho;03A1
-Ringsmall;F6FC
-Rinvertedbreve;0212
-Rlinebelow;1E5E
-Rmonospace;FF32
-Rsmall;F772
-Rsmallinverted;0281
-Rsmallinvertedsuperior;02B6
-S;0053
-SF010000;250C
-SF020000;2514
-SF030000;2510
-SF040000;2518
-SF050000;253C
-SF060000;252C
-SF070000;2534
-SF080000;251C
-SF090000;2524
-SF100000;2500
-SF110000;2502
-SF190000;2561
-SF200000;2562
-SF210000;2556
-SF220000;2555
-SF230000;2563
-SF240000;2551
-SF250000;2557
-SF260000;255D
-SF270000;255C
-SF280000;255B
-SF360000;255E
-SF370000;255F
-SF380000;255A
-SF390000;2554
-SF400000;2569
-SF410000;2566
-SF420000;2560
-SF430000;2550
-SF440000;256C
-SF450000;2567
-SF460000;2568
-SF470000;2564
-SF480000;2565
-SF490000;2559
-SF500000;2558
-SF510000;2552
-SF520000;2553
-SF530000;256B
-SF540000;256A
-Sacute;015A
-Sacutedotaccent;1E64
-Sampigreek;03E0
-Scaron;0160
-Scarondotaccent;1E66
-Scaronsmall;F6FD
-Scedilla;015E
-Schwa;018F
-Schwacyrillic;04D8
-Schwadieresiscyrillic;04DA
-Scircle;24C8
-Scircumflex;015C
-Scommaaccent;0218
-Sdotaccent;1E60
-Sdotbelow;1E62
-Sdotbelowdotaccent;1E68
-Seharmenian;054D
-Sevenroman;2166
-Shaarmenian;0547
-Shacyrillic;0428
-Shchacyrillic;0429
-Sheicoptic;03E2
-Shhacyrillic;04BA
-Shimacoptic;03EC
-Sigma;03A3
-Sixroman;2165
-Smonospace;FF33
-Softsigncyrillic;042C
-Ssmall;F773
-Stigmagreek;03DA
-T;0054
-Tau;03A4
-Tbar;0166
-Tcaron;0164
-Tcedilla;0162
-Tcircle;24C9
-Tcircumflexbelow;1E70
-Tcommaaccent;0162
-Tdotaccent;1E6A
-Tdotbelow;1E6C
-Tecyrillic;0422
-Tedescendercyrillic;04AC
-Tenroman;2169
-Tetsecyrillic;04B4
-Theta;0398
-Thook;01AC
-Thorn;00DE
-Thornsmall;F7FE
-Threeroman;2162
-Tildesmall;F6FE
-Tiwnarmenian;054F
-Tlinebelow;1E6E
-Tmonospace;FF34
-Toarmenian;0539
-Tonefive;01BC
-Tonesix;0184
-Tonetwo;01A7
-Tretroflexhook;01AE
-Tsecyrillic;0426
-Tshecyrillic;040B
-Tsmall;F774
-Twelveroman;216B
-Tworoman;2161
-U;0055
-Uacute;00DA
-Uacutesmall;F7FA
-Ubreve;016C
-Ucaron;01D3
-Ucircle;24CA
-Ucircumflex;00DB
-Ucircumflexbelow;1E76
-Ucircumflexsmall;F7FB
-Ucyrillic;0423
-Udblacute;0170
-Udblgrave;0214
-Udieresis;00DC
-Udieresisacute;01D7
-Udieresisbelow;1E72
-Udieresiscaron;01D9
-Udieresiscyrillic;04F0
-Udieresisgrave;01DB
-Udieresismacron;01D5
-Udieresissmall;F7FC
-Udotbelow;1EE4
-Ugrave;00D9
-Ugravesmall;F7F9
-Uhookabove;1EE6
-Uhorn;01AF
-Uhornacute;1EE8
-Uhorndotbelow;1EF0
-Uhorngrave;1EEA
-Uhornhookabove;1EEC
-Uhorntilde;1EEE
-Uhungarumlaut;0170
-Uhungarumlautcyrillic;04F2
-Uinvertedbreve;0216
-Ukcyrillic;0478
-Umacron;016A
-Umacroncyrillic;04EE
-Umacrondieresis;1E7A
-Umonospace;FF35
-Uogonek;0172
-Upsilon;03A5
-Upsilon1;03D2
-Upsilonacutehooksymbolgreek;03D3
-Upsilonafrican;01B1
-Upsilondieresis;03AB
-Upsilondieresishooksymbolgreek;03D4
-Upsilonhooksymbol;03D2
-Upsilontonos;038E
-Uring;016E
-Ushortcyrillic;040E
-Usmall;F775
-Ustraightcyrillic;04AE
-Ustraightstrokecyrillic;04B0
-Utilde;0168
-Utildeacute;1E78
-Utildebelow;1E74
-V;0056
-Vcircle;24CB
-Vdotbelow;1E7E
-Vecyrillic;0412
-Vewarmenian;054E
-Vhook;01B2
-Vmonospace;FF36
-Voarmenian;0548
-Vsmall;F776
-Vtilde;1E7C
-W;0057
-Wacute;1E82
-Wcircle;24CC
-Wcircumflex;0174
-Wdieresis;1E84
-Wdotaccent;1E86
-Wdotbelow;1E88
-Wgrave;1E80
-Wmonospace;FF37
-Wsmall;F777
-X;0058
-Xcircle;24CD
-Xdieresis;1E8C
-Xdotaccent;1E8A
-Xeharmenian;053D
-Xi;039E
-Xmonospace;FF38
-Xsmall;F778
-Y;0059
-Yacute;00DD
-Yacutesmall;F7FD
-Yatcyrillic;0462
-Ycircle;24CE
-Ycircumflex;0176
-Ydieresis;0178
-Ydieresissmall;F7FF
-Ydotaccent;1E8E
-Ydotbelow;1EF4
-Yericyrillic;042B
-Yerudieresiscyrillic;04F8
-Ygrave;1EF2
-Yhook;01B3
-Yhookabove;1EF6
-Yiarmenian;0545
-Yicyrillic;0407
-Yiwnarmenian;0552
-Ymonospace;FF39
-Ysmall;F779
-Ytilde;1EF8
-Yusbigcyrillic;046A
-Yusbigiotifiedcyrillic;046C
-Yuslittlecyrillic;0466
-Yuslittleiotifiedcyrillic;0468
-Z;005A
-Zaarmenian;0536
-Zacute;0179
-Zcaron;017D
-Zcaronsmall;F6FF
-Zcircle;24CF
-Zcircumflex;1E90
-Zdot;017B
-Zdotaccent;017B
-Zdotbelow;1E92
-Zecyrillic;0417
-Zedescendercyrillic;0498
-Zedieresiscyrillic;04DE
-Zeta;0396
-Zhearmenian;053A
-Zhebrevecyrillic;04C1
-Zhecyrillic;0416
-Zhedescendercyrillic;0496
-Zhedieresiscyrillic;04DC
-Zlinebelow;1E94
-Zmonospace;FF3A
-Zsmall;F77A
-Zstroke;01B5
-a;0061
-aabengali;0986
-aacute;00E1
-aadeva;0906
-aagujarati;0A86
-aagurmukhi;0A06
-aamatragurmukhi;0A3E
-aarusquare;3303
-aavowelsignbengali;09BE
-aavowelsigndeva;093E
-aavowelsigngujarati;0ABE
-abbreviationmarkarmenian;055F
-abbreviationsigndeva;0970
-abengali;0985
-abopomofo;311A
-abreve;0103
-abreveacute;1EAF
-abrevecyrillic;04D1
-abrevedotbelow;1EB7
-abrevegrave;1EB1
-abrevehookabove;1EB3
-abrevetilde;1EB5
-acaron;01CE
-acircle;24D0
-acircumflex;00E2
-acircumflexacute;1EA5
-acircumflexdotbelow;1EAD
-acircumflexgrave;1EA7
-acircumflexhookabove;1EA9
-acircumflextilde;1EAB
-acute;00B4
-acutebelowcmb;0317
-acutecmb;0301
-acutecomb;0301
-acutedeva;0954
-acutelowmod;02CF
-acutetonecmb;0341
-acyrillic;0430
-adblgrave;0201
-addakgurmukhi;0A71
-adeva;0905
-adieresis;00E4
-adieresiscyrillic;04D3
-adieresismacron;01DF
-adotbelow;1EA1
-adotmacron;01E1
-ae;00E6
-aeacute;01FD
-aekorean;3150
-aemacron;01E3
-afii00208;2015
-afii08941;20A4
-afii10017;0410
-afii10018;0411
-afii10019;0412
-afii10020;0413
-afii10021;0414
-afii10022;0415
-afii10023;0401
-afii10024;0416
-afii10025;0417
-afii10026;0418
-afii10027;0419
-afii10028;041A
-afii10029;041B
-afii10030;041C
-afii10031;041D
-afii10032;041E
-afii10033;041F
-afii10034;0420
-afii10035;0421
-afii10036;0422
-afii10037;0423
-afii10038;0424
-afii10039;0425
-afii10040;0426
-afii10041;0427
-afii10042;0428
-afii10043;0429
-afii10044;042A
-afii10045;042B
-afii10046;042C
-afii10047;042D
-afii10048;042E
-afii10049;042F
-afii10050;0490
-afii10051;0402
-afii10052;0403
-afii10053;0404
-afii10054;0405
-afii10055;0406
-afii10056;0407
-afii10057;0408
-afii10058;0409
-afii10059;040A
-afii10060;040B
-afii10061;040C
-afii10062;040E
-afii10063;F6C4
-afii10064;F6C5
-afii10065;0430
-afii10066;0431
-afii10067;0432
-afii10068;0433
-afii10069;0434
-afii10070;0435
-afii10071;0451
-afii10072;0436
-afii10073;0437
-afii10074;0438
-afii10075;0439
-afii10076;043A
-afii10077;043B
-afii10078;043C
-afii10079;043D
-afii10080;043E
-afii10081;043F
-afii10082;0440
-afii10083;0441
-afii10084;0442
-afii10085;0443
-afii10086;0444
-afii10087;0445
-afii10088;0446
-afii10089;0447
-afii10090;0448
-afii10091;0449
-afii10092;044A
-afii10093;044B
-afii10094;044C
-afii10095;044D
-afii10096;044E
-afii10097;044F
-afii10098;0491
-afii10099;0452
-afii10100;0453
-afii10101;0454
-afii10102;0455
-afii10103;0456
-afii10104;0457
-afii10105;0458
-afii10106;0459
-afii10107;045A
-afii10108;045B
-afii10109;045C
-afii10110;045E
-afii10145;040F
-afii10146;0462
-afii10147;0472
-afii10148;0474
-afii10192;F6C6
-afii10193;045F
-afii10194;0463
-afii10195;0473
-afii10196;0475
-afii10831;F6C7
-afii10832;F6C8
-afii10846;04D9
-afii299;200E
-afii300;200F
-afii301;200D
-afii57381;066A
-afii57388;060C
-afii57392;0660
-afii57393;0661
-afii57394;0662
-afii57395;0663
-afii57396;0664
-afii57397;0665
-afii57398;0666
-afii57399;0667
-afii57400;0668
-afii57401;0669
-afii57403;061B
-afii57407;061F
-afii57409;0621
-afii57410;0622
-afii57411;0623
-afii57412;0624
-afii57413;0625
-afii57414;0626
-afii57415;0627
-afii57416;0628
-afii57417;0629
-afii57418;062A
-afii57419;062B
-afii57420;062C
-afii57421;062D
-afii57422;062E
-afii57423;062F
-afii57424;0630
-afii57425;0631
-afii57426;0632
-afii57427;0633
-afii57428;0634
-afii57429;0635
-afii57430;0636
-afii57431;0637
-afii57432;0638
-afii57433;0639
-afii57434;063A
-afii57440;0640
-afii57441;0641
-afii57442;0642
-afii57443;0643
-afii57444;0644
-afii57445;0645
-afii57446;0646
-afii57448;0648
-afii57449;0649
-afii57450;064A
-afii57451;064B
-afii57452;064C
-afii57453;064D
-afii57454;064E
-afii57455;064F
-afii57456;0650
-afii57457;0651
-afii57458;0652
-afii57470;0647
-afii57505;06A4
-afii57506;067E
-afii57507;0686
-afii57508;0698
-afii57509;06AF
-afii57511;0679
-afii57512;0688
-afii57513;0691
-afii57514;06BA
-afii57519;06D2
-afii57534;06D5
-afii57636;20AA
-afii57645;05BE
-afii57658;05C3
-afii57664;05D0
-afii57665;05D1
-afii57666;05D2
-afii57667;05D3
-afii57668;05D4
-afii57669;05D5
-afii57670;05D6
-afii57671;05D7
-afii57672;05D8
-afii57673;05D9
-afii57674;05DA
-afii57675;05DB
-afii57676;05DC
-afii57677;05DD
-afii57678;05DE
-afii57679;05DF
-afii57680;05E0
-afii57681;05E1
-afii57682;05E2
-afii57683;05E3
-afii57684;05E4
-afii57685;05E5
-afii57686;05E6
-afii57687;05E7
-afii57688;05E8
-afii57689;05E9
-afii57690;05EA
-afii57694;FB2A
-afii57695;FB2B
-afii57700;FB4B
-afii57705;FB1F
-afii57716;05F0
-afii57717;05F1
-afii57718;05F2
-afii57723;FB35
-afii57793;05B4
-afii57794;05B5
-afii57795;05B6
-afii57796;05BB
-afii57797;05B8
-afii57798;05B7
-afii57799;05B0
-afii57800;05B2
-afii57801;05B1
-afii57802;05B3
-afii57803;05C2
-afii57804;05C1
-afii57806;05B9
-afii57807;05BC
-afii57839;05BD
-afii57841;05BF
-afii57842;05C0
-afii57929;02BC
-afii61248;2105
-afii61289;2113
-afii61352;2116
-afii61573;202C
-afii61574;202D
-afii61575;202E
-afii61664;200C
-afii63167;066D
-afii64937;02BD
-agrave;00E0
-agujarati;0A85
-agurmukhi;0A05
-ahiragana;3042
-ahookabove;1EA3
-aibengali;0990
-aibopomofo;311E
-aideva;0910
-aiecyrillic;04D5
-aigujarati;0A90
-aigurmukhi;0A10
-aimatragurmukhi;0A48
-ainarabic;0639
-ainfinalarabic;FECA
-aininitialarabic;FECB
-ainmedialarabic;FECC
-ainvertedbreve;0203
-aivowelsignbengali;09C8
-aivowelsigndeva;0948
-aivowelsigngujarati;0AC8
-akatakana;30A2
-akatakanahalfwidth;FF71
-akorean;314F
-alef;05D0
-alefarabic;0627
-alefdageshhebrew;FB30
-aleffinalarabic;FE8E
-alefhamzaabovearabic;0623
-alefhamzaabovefinalarabic;FE84
-alefhamzabelowarabic;0625
-alefhamzabelowfinalarabic;FE88
-alefhebrew;05D0
-aleflamedhebrew;FB4F
-alefmaddaabovearabic;0622
-alefmaddaabovefinalarabic;FE82
-alefmaksuraarabic;0649
-alefmaksurafinalarabic;FEF0
-alefmaksurainitialarabic;FEF3
-alefmaksuramedialarabic;FEF4
-alefpatahhebrew;FB2E
-alefqamatshebrew;FB2F
-aleph;2135
-allequal;224C
-alpha;03B1
-alphatonos;03AC
-amacron;0101
-amonospace;FF41
-ampersand;0026
-ampersandmonospace;FF06
-ampersandsmall;F726
-amsquare;33C2
-anbopomofo;3122
-angbopomofo;3124
-angkhankhuthai;0E5A
-angle;2220
-anglebracketleft;3008
-anglebracketleftvertical;FE3F
-anglebracketright;3009
-anglebracketrightvertical;FE40
-angleleft;2329
-angleright;232A
-angstrom;212B
-anoteleia;0387
-anudattadeva;0952
-anusvarabengali;0982
-anusvaradeva;0902
-anusvaragujarati;0A82
-aogonek;0105
-apaatosquare;3300
-aparen;249C
-apostrophearmenian;055A
-apostrophemod;02BC
-apple;F8FF
-approaches;2250
-approxequal;2248
-approxequalorimage;2252
-approximatelyequal;2245
-araeaekorean;318E
-araeakorean;318D
-arc;2312
-arighthalfring;1E9A
-aring;00E5
-aringacute;01FB
-aringbelow;1E01
-arrowboth;2194
-arrowdashdown;21E3
-arrowdashleft;21E0
-arrowdashright;21E2
-arrowdashup;21E1
-arrowdblboth;21D4
-arrowdbldown;21D3
-arrowdblleft;21D0
-arrowdblright;21D2
-arrowdblup;21D1
-arrowdown;2193
-arrowdownleft;2199
-arrowdownright;2198
-arrowdownwhite;21E9
-arrowheaddownmod;02C5
-arrowheadleftmod;02C2
-arrowheadrightmod;02C3
-arrowheadupmod;02C4
-arrowhorizex;F8E7
-arrowleft;2190
-arrowleftdbl;21D0
-arrowleftdblstroke;21CD
-arrowleftoverright;21C6
-arrowleftwhite;21E6
-arrowright;2192
-arrowrightdblstroke;21CF
-arrowrightheavy;279E
-arrowrightoverleft;21C4
-arrowrightwhite;21E8
-arrowtableft;21E4
-arrowtabright;21E5
-arrowup;2191
-arrowupdn;2195
-arrowupdnbse;21A8
-arrowupdownbase;21A8
-arrowupleft;2196
-arrowupleftofdown;21C5
-arrowupright;2197
-arrowupwhite;21E7
-arrowvertex;F8E6
-asciicircum;005E
-asciicircummonospace;FF3E
-asciitilde;007E
-asciitildemonospace;FF5E
-ascript;0251
-ascriptturned;0252
-asmallhiragana;3041
-asmallkatakana;30A1
-asmallkatakanahalfwidth;FF67
-asterisk;002A
-asteriskaltonearabic;066D
-asteriskarabic;066D
-asteriskmath;2217
-asteriskmonospace;FF0A
-asterisksmall;FE61
-asterism;2042
-asuperior;F6E9
-asymptoticallyequal;2243
-at;0040
-atilde;00E3
-atmonospace;FF20
-atsmall;FE6B
-aturned;0250
-aubengali;0994
-aubopomofo;3120
-audeva;0914
-augujarati;0A94
-augurmukhi;0A14
-aulengthmarkbengali;09D7
-aumatragurmukhi;0A4C
-auvowelsignbengali;09CC
-auvowelsigndeva;094C
-auvowelsigngujarati;0ACC
-avagrahadeva;093D
-aybarmenian;0561
-ayin;05E2
-ayinaltonehebrew;FB20
-ayinhebrew;05E2
-b;0062
-babengali;09AC
-backslash;005C
-backslashmonospace;FF3C
-badeva;092C
-bagujarati;0AAC
-bagurmukhi;0A2C
-bahiragana;3070
-bahtthai;0E3F
-bakatakana;30D0
-bar;007C
-barmonospace;FF5C
-bbopomofo;3105
-bcircle;24D1
-bdotaccent;1E03
-bdotbelow;1E05
-beamedsixteenthnotes;266C
-because;2235
-becyrillic;0431
-beharabic;0628
-behfinalarabic;FE90
-behinitialarabic;FE91
-behiragana;3079
-behmedialarabic;FE92
-behmeeminitialarabic;FC9F
-behmeemisolatedarabic;FC08
-behnoonfinalarabic;FC6D
-bekatakana;30D9
-benarmenian;0562
-bet;05D1
-beta;03B2
-betasymbolgreek;03D0
-betdagesh;FB31
-betdageshhebrew;FB31
-bethebrew;05D1
-betrafehebrew;FB4C
-bhabengali;09AD
-bhadeva;092D
-bhagujarati;0AAD
-bhagurmukhi;0A2D
-bhook;0253
-bihiragana;3073
-bikatakana;30D3
-bilabialclick;0298
-bindigurmukhi;0A02
-birusquare;3331
-blackcircle;25CF
-blackdiamond;25C6
-blackdownpointingtriangle;25BC
-blackleftpointingpointer;25C4
-blackleftpointingtriangle;25C0
-blacklenticularbracketleft;3010
-blacklenticularbracketleftvertical;FE3B
-blacklenticularbracketright;3011
-blacklenticularbracketrightvertical;FE3C
-blacklowerlefttriangle;25E3
-blacklowerrighttriangle;25E2
-blackrectangle;25AC
-blackrightpointingpointer;25BA
-blackrightpointingtriangle;25B6
-blacksmallsquare;25AA
-blacksmilingface;263B
-blacksquare;25A0
-blackstar;2605
-blackupperlefttriangle;25E4
-blackupperrighttriangle;25E5
-blackuppointingsmalltriangle;25B4
-blackuppointingtriangle;25B2
-blank;2423
-blinebelow;1E07
-block;2588
-bmonospace;FF42
-bobaimaithai;0E1A
-bohiragana;307C
-bokatakana;30DC
-bparen;249D
-bqsquare;33C3
-braceex;F8F4
-braceleft;007B
-braceleftbt;F8F3
-braceleftmid;F8F2
-braceleftmonospace;FF5B
-braceleftsmall;FE5B
-bracelefttp;F8F1
-braceleftvertical;FE37
-braceright;007D
-bracerightbt;F8FE
-bracerightmid;F8FD
-bracerightmonospace;FF5D
-bracerightsmall;FE5C
-bracerighttp;F8FC
-bracerightvertical;FE38
-bracketleft;005B
-bracketleftbt;F8F0
-bracketleftex;F8EF
-bracketleftmonospace;FF3B
-bracketlefttp;F8EE
-bracketright;005D
-bracketrightbt;F8FB
-bracketrightex;F8FA
-bracketrightmonospace;FF3D
-bracketrighttp;F8F9
-breve;02D8
-brevebelowcmb;032E
-brevecmb;0306
-breveinvertedbelowcmb;032F
-breveinvertedcmb;0311
-breveinverteddoublecmb;0361
-bridgebelowcmb;032A
-bridgeinvertedbelowcmb;033A
-brokenbar;00A6
-bstroke;0180
-bsuperior;F6EA
-btopbar;0183
-buhiragana;3076
-bukatakana;30D6
-bullet;2022
-bulletinverse;25D8
-bulletoperator;2219
-bullseye;25CE
-c;0063
-caarmenian;056E
-cabengali;099A
-cacute;0107
-cadeva;091A
-cagujarati;0A9A
-cagurmukhi;0A1A
-calsquare;3388
-candrabindubengali;0981
-candrabinducmb;0310
-candrabindudeva;0901
-candrabindugujarati;0A81
-capslock;21EA
-careof;2105
-caron;02C7
-caronbelowcmb;032C
-caroncmb;030C
-carriagereturn;21B5
-cbopomofo;3118
-ccaron;010D
-ccedilla;00E7
-ccedillaacute;1E09
-ccircle;24D2
-ccircumflex;0109
-ccurl;0255
-cdot;010B
-cdotaccent;010B
-cdsquare;33C5
-cedilla;00B8
-cedillacmb;0327
-cent;00A2
-centigrade;2103
-centinferior;F6DF
-centmonospace;FFE0
-centoldstyle;F7A2
-centsuperior;F6E0
-chaarmenian;0579
-chabengali;099B
-chadeva;091B
-chagujarati;0A9B
-chagurmukhi;0A1B
-chbopomofo;3114
-cheabkhasiancyrillic;04BD
-checkmark;2713
-checyrillic;0447
-chedescenderabkhasiancyrillic;04BF
-chedescendercyrillic;04B7
-chedieresiscyrillic;04F5
-cheharmenian;0573
-chekhakassiancyrillic;04CC
-cheverticalstrokecyrillic;04B9
-chi;03C7
-chieuchacirclekorean;3277
-chieuchaparenkorean;3217
-chieuchcirclekorean;3269
-chieuchkorean;314A
-chieuchparenkorean;3209
-chochangthai;0E0A
-chochanthai;0E08
-chochingthai;0E09
-chochoethai;0E0C
-chook;0188
-cieucacirclekorean;3276
-cieucaparenkorean;3216
-cieuccirclekorean;3268
-cieuckorean;3148
-cieucparenkorean;3208
-cieucuparenkorean;321C
-circle;25CB
-circlemultiply;2297
-circleot;2299
-circleplus;2295
-circlepostalmark;3036
-circlewithlefthalfblack;25D0
-circlewithrighthalfblack;25D1
-circumflex;02C6
-circumflexbelowcmb;032D
-circumflexcmb;0302
-clear;2327
-clickalveolar;01C2
-clickdental;01C0
-clicklateral;01C1
-clickretroflex;01C3
-club;2663
-clubsuitblack;2663
-clubsuitwhite;2667
-cmcubedsquare;33A4
-cmonospace;FF43
-cmsquaredsquare;33A0
-coarmenian;0581
-colon;003A
-colonmonetary;20A1
-colonmonospace;FF1A
-colonsign;20A1
-colonsmall;FE55
-colontriangularhalfmod;02D1
-colontriangularmod;02D0
-comma;002C
-commaabovecmb;0313
-commaaboverightcmb;0315
-commaaccent;F6C3
-commaarabic;060C
-commaarmenian;055D
-commainferior;F6E1
-commamonospace;FF0C
-commareversedabovecmb;0314
-commareversedmod;02BD
-commasmall;FE50
-commasuperior;F6E2
-commaturnedabovecmb;0312
-commaturnedmod;02BB
-compass;263C
-congruent;2245
-contourintegral;222E
-control;2303
-controlACK;0006
-controlBEL;0007
-controlBS;0008
-controlCAN;0018
-controlCR;000D
-controlDC1;0011
-controlDC2;0012
-controlDC3;0013
-controlDC4;0014
-controlDEL;007F
-controlDLE;0010
-controlEM;0019
-controlENQ;0005
-controlEOT;0004
-controlESC;001B
-controlETB;0017
-controlETX;0003
-controlFF;000C
-controlFS;001C
-controlGS;001D
-controlHT;0009
-controlLF;000A
-controlNAK;0015
-controlRS;001E
-controlSI;000F
-controlSO;000E
-controlSOT;0002
-controlSTX;0001
-controlSUB;001A
-controlSYN;0016
-controlUS;001F
-controlVT;000B
-copyright;00A9
-copyrightsans;F8E9
-copyrightserif;F6D9
-cornerbracketleft;300C
-cornerbracketlefthalfwidth;FF62
-cornerbracketleftvertical;FE41
-cornerbracketright;300D
-cornerbracketrighthalfwidth;FF63
-cornerbracketrightvertical;FE42
-corporationsquare;337F
-cosquare;33C7
-coverkgsquare;33C6
-cparen;249E
-cruzeiro;20A2
-cstretched;0297
-curlyand;22CF
-curlyor;22CE
-currency;00A4
-cyrBreve;F6D1
-cyrFlex;F6D2
-cyrbreve;F6D4
-cyrflex;F6D5
-d;0064
-daarmenian;0564
-dabengali;09A6
-dadarabic;0636
-dadeva;0926
-dadfinalarabic;FEBE
-dadinitialarabic;FEBF
-dadmedialarabic;FEC0
-dagesh;05BC
-dageshhebrew;05BC
-dagger;2020
-daggerdbl;2021
-dagujarati;0AA6
-dagurmukhi;0A26
-dahiragana;3060
-dakatakana;30C0
-dalarabic;062F
-dalet;05D3
-daletdagesh;FB33
-daletdageshhebrew;FB33
-dalethatafpatah;05D3 05B2
-dalethatafpatahhebrew;05D3 05B2
-dalethatafsegol;05D3 05B1
-dalethatafsegolhebrew;05D3 05B1
-dalethebrew;05D3
-dalethiriq;05D3 05B4
-dalethiriqhebrew;05D3 05B4
-daletholam;05D3 05B9
-daletholamhebrew;05D3 05B9
-daletpatah;05D3 05B7
-daletpatahhebrew;05D3 05B7
-daletqamats;05D3 05B8
-daletqamatshebrew;05D3 05B8
-daletqubuts;05D3 05BB
-daletqubutshebrew;05D3 05BB
-daletsegol;05D3 05B6
-daletsegolhebrew;05D3 05B6
-daletsheva;05D3 05B0
-daletshevahebrew;05D3 05B0
-dalettsere;05D3 05B5
-dalettserehebrew;05D3 05B5
-dalfinalarabic;FEAA
-dammaarabic;064F
-dammalowarabic;064F
-dammatanaltonearabic;064C
-dammatanarabic;064C
-danda;0964
-dargahebrew;05A7
-dargalefthebrew;05A7
-dasiapneumatacyrilliccmb;0485
-dblGrave;F6D3
-dblanglebracketleft;300A
-dblanglebracketleftvertical;FE3D
-dblanglebracketright;300B
-dblanglebracketrightvertical;FE3E
-dblarchinvertedbelowcmb;032B
-dblarrowleft;21D4
-dblarrowright;21D2
-dbldanda;0965
-dblgrave;F6D6
-dblgravecmb;030F
-dblintegral;222C
-dbllowline;2017
-dbllowlinecmb;0333
-dbloverlinecmb;033F
-dblprimemod;02BA
-dblverticalbar;2016
-dblverticallineabovecmb;030E
-dbopomofo;3109
-dbsquare;33C8
-dcaron;010F
-dcedilla;1E11
-dcircle;24D3
-dcircumflexbelow;1E13
-dcroat;0111
-ddabengali;09A1
-ddadeva;0921
-ddagujarati;0AA1
-ddagurmukhi;0A21
-ddalarabic;0688
-ddalfinalarabic;FB89
-dddhadeva;095C
-ddhabengali;09A2
-ddhadeva;0922
-ddhagujarati;0AA2
-ddhagurmukhi;0A22
-ddotaccent;1E0B
-ddotbelow;1E0D
-decimalseparatorarabic;066B
-decimalseparatorpersian;066B
-decyrillic;0434
-degree;00B0
-dehihebrew;05AD
-dehiragana;3067
-deicoptic;03EF
-dekatakana;30C7
-deleteleft;232B
-deleteright;2326
-delta;03B4
-deltaturned;018D
-denominatorminusonenumeratorbengali;09F8
-dezh;02A4
-dhabengali;09A7
-dhadeva;0927
-dhagujarati;0AA7
-dhagurmukhi;0A27
-dhook;0257
-dialytikatonos;0385
-dialytikatonoscmb;0344
-diamond;2666
-diamondsuitwhite;2662
-dieresis;00A8
-dieresisacute;F6D7
-dieresisbelowcmb;0324
-dieresiscmb;0308
-dieresisgrave;F6D8
-dieresistonos;0385
-dihiragana;3062
-dikatakana;30C2
-dittomark;3003
-divide;00F7
-divides;2223
-divisionslash;2215
-djecyrillic;0452
-dkshade;2593
-dlinebelow;1E0F
-dlsquare;3397
-dmacron;0111
-dmonospace;FF44
-dnblock;2584
-dochadathai;0E0E
-dodekthai;0E14
-dohiragana;3069
-dokatakana;30C9
-dollar;0024
-dollarinferior;F6E3
-dollarmonospace;FF04
-dollaroldstyle;F724
-dollarsmall;FE69
-dollarsuperior;F6E4
-dong;20AB
-dorusquare;3326
-dotaccent;02D9
-dotaccentcmb;0307
-dotbelowcmb;0323
-dotbelowcomb;0323
-dotkatakana;30FB
-dotlessi;0131
-dotlessj;F6BE
-dotlessjstrokehook;0284
-dotmath;22C5
-dottedcircle;25CC
-doubleyodpatah;FB1F
-doubleyodpatahhebrew;FB1F
-downtackbelowcmb;031E
-downtackmod;02D5
-dparen;249F
-dsuperior;F6EB
-dtail;0256
-dtopbar;018C
-duhiragana;3065
-dukatakana;30C5
-dz;01F3
-dzaltone;02A3
-dzcaron;01C6
-dzcurl;02A5
-dzeabkhasiancyrillic;04E1
-dzecyrillic;0455
-dzhecyrillic;045F
-e;0065
-eacute;00E9
-earth;2641
-ebengali;098F
-ebopomofo;311C
-ebreve;0115
-ecandradeva;090D
-ecandragujarati;0A8D
-ecandravowelsigndeva;0945
-ecandravowelsigngujarati;0AC5
-ecaron;011B
-ecedillabreve;1E1D
-echarmenian;0565
-echyiwnarmenian;0587
-ecircle;24D4
-ecircumflex;00EA
-ecircumflexacute;1EBF
-ecircumflexbelow;1E19
-ecircumflexdotbelow;1EC7
-ecircumflexgrave;1EC1
-ecircumflexhookabove;1EC3
-ecircumflextilde;1EC5
-ecyrillic;0454
-edblgrave;0205
-edeva;090F
-edieresis;00EB
-edot;0117
-edotaccent;0117
-edotbelow;1EB9
-eegurmukhi;0A0F
-eematragurmukhi;0A47
-efcyrillic;0444
-egrave;00E8
-egujarati;0A8F
-eharmenian;0567
-ehbopomofo;311D
-ehiragana;3048
-ehookabove;1EBB
-eibopomofo;311F
-eight;0038
-eightarabic;0668
-eightbengali;09EE
-eightcircle;2467
-eightcircleinversesansserif;2791
-eightdeva;096E
-eighteencircle;2471
-eighteenparen;2485
-eighteenperiod;2499
-eightgujarati;0AEE
-eightgurmukhi;0A6E
-eighthackarabic;0668
-eighthangzhou;3028
-eighthnotebeamed;266B
-eightideographicparen;3227
-eightinferior;2088
-eightmonospace;FF18
-eightoldstyle;F738
-eightparen;247B
-eightperiod;248F
-eightpersian;06F8
-eightroman;2177
-eightsuperior;2078
-eightthai;0E58
-einvertedbreve;0207
-eiotifiedcyrillic;0465
-ekatakana;30A8
-ekatakanahalfwidth;FF74
-ekonkargurmukhi;0A74
-ekorean;3154
-elcyrillic;043B
-element;2208
-elevencircle;246A
-elevenparen;247E
-elevenperiod;2492
-elevenroman;217A
-ellipsis;2026
-ellipsisvertical;22EE
-emacron;0113
-emacronacute;1E17
-emacrongrave;1E15
-emcyrillic;043C
-emdash;2014
-emdashvertical;FE31
-emonospace;FF45
-emphasismarkarmenian;055B
-emptyset;2205
-enbopomofo;3123
-encyrillic;043D
-endash;2013
-endashvertical;FE32
-endescendercyrillic;04A3
-eng;014B
-engbopomofo;3125
-enghecyrillic;04A5
-enhookcyrillic;04C8
-enspace;2002
-eogonek;0119
-eokorean;3153
-eopen;025B
-eopenclosed;029A
-eopenreversed;025C
-eopenreversedclosed;025E
-eopenreversedhook;025D
-eparen;24A0
-epsilon;03B5
-epsilontonos;03AD
-equal;003D
-equalmonospace;FF1D
-equalsmall;FE66
-equalsuperior;207C
-equivalence;2261
-erbopomofo;3126
-ercyrillic;0440
-ereversed;0258
-ereversedcyrillic;044D
-escyrillic;0441
-esdescendercyrillic;04AB
-esh;0283
-eshcurl;0286
-eshortdeva;090E
-eshortvowelsigndeva;0946
-eshreversedloop;01AA
-eshsquatreversed;0285
-esmallhiragana;3047
-esmallkatakana;30A7
-esmallkatakanahalfwidth;FF6A
-estimated;212E
-esuperior;F6EC
-eta;03B7
-etarmenian;0568
-etatonos;03AE
-eth;00F0
-etilde;1EBD
-etildebelow;1E1B
-etnahtafoukhhebrew;0591
-etnahtafoukhlefthebrew;0591
-etnahtahebrew;0591
-etnahtalefthebrew;0591
-eturned;01DD
-eukorean;3161
-euro;20AC
-evowelsignbengali;09C7
-evowelsigndeva;0947
-evowelsigngujarati;0AC7
-exclam;0021
-exclamarmenian;055C
-exclamdbl;203C
-exclamdown;00A1
-exclamdownsmall;F7A1
-exclammonospace;FF01
-exclamsmall;F721
-existential;2203
-ezh;0292
-ezhcaron;01EF
-ezhcurl;0293
-ezhreversed;01B9
-ezhtail;01BA
-f;0066
-fadeva;095E
-fagurmukhi;0A5E
-fahrenheit;2109
-fathaarabic;064E
-fathalowarabic;064E
-fathatanarabic;064B
-fbopomofo;3108
-fcircle;24D5
-fdotaccent;1E1F
-feharabic;0641
-feharmenian;0586
-fehfinalarabic;FED2
-fehinitialarabic;FED3
-fehmedialarabic;FED4
-feicoptic;03E5
-female;2640
-ff;FB00
-ffi;FB03
-ffl;FB04
-fi;FB01
-fifteencircle;246E
-fifteenparen;2482
-fifteenperiod;2496
-figuredash;2012
-filledbox;25A0
-filledrect;25AC
-finalkaf;05DA
-finalkafdagesh;FB3A
-finalkafdageshhebrew;FB3A
-finalkafhebrew;05DA
-finalkafqamats;05DA 05B8
-finalkafqamatshebrew;05DA 05B8
-finalkafsheva;05DA 05B0
-finalkafshevahebrew;05DA 05B0
-finalmem;05DD
-finalmemhebrew;05DD
-finalnun;05DF
-finalnunhebrew;05DF
-finalpe;05E3
-finalpehebrew;05E3
-finaltsadi;05E5
-finaltsadihebrew;05E5
-firsttonechinese;02C9
-fisheye;25C9
-fitacyrillic;0473
-five;0035
-fivearabic;0665
-fivebengali;09EB
-fivecircle;2464
-fivecircleinversesansserif;278E
-fivedeva;096B
-fiveeighths;215D
-fivegujarati;0AEB
-fivegurmukhi;0A6B
-fivehackarabic;0665
-fivehangzhou;3025
-fiveideographicparen;3224
-fiveinferior;2085
-fivemonospace;FF15
-fiveoldstyle;F735
-fiveparen;2478
-fiveperiod;248C
-fivepersian;06F5
-fiveroman;2174
-fivesuperior;2075
-fivethai;0E55
-fl;FB02
-florin;0192
-fmonospace;FF46
-fmsquare;3399
-fofanthai;0E1F
-fofathai;0E1D
-fongmanthai;0E4F
-forall;2200
-four;0034
-fourarabic;0664
-fourbengali;09EA
-fourcircle;2463
-fourcircleinversesansserif;278D
-fourdeva;096A
-fourgujarati;0AEA
-fourgurmukhi;0A6A
-fourhackarabic;0664
-fourhangzhou;3024
-fourideographicparen;3223
-fourinferior;2084
-fourmonospace;FF14
-fournumeratorbengali;09F7
-fouroldstyle;F734
-fourparen;2477
-fourperiod;248B
-fourpersian;06F4
-fourroman;2173
-foursuperior;2074
-fourteencircle;246D
-fourteenparen;2481
-fourteenperiod;2495
-fourthai;0E54
-fourthtonechinese;02CB
-fparen;24A1
-fraction;2044
-franc;20A3
-g;0067
-gabengali;0997
-gacute;01F5
-gadeva;0917
-gafarabic;06AF
-gaffinalarabic;FB93
-gafinitialarabic;FB94
-gafmedialarabic;FB95
-gagujarati;0A97
-gagurmukhi;0A17
-gahiragana;304C
-gakatakana;30AC
-gamma;03B3
-gammalatinsmall;0263
-gammasuperior;02E0
-gangiacoptic;03EB
-gbopomofo;310D
-gbreve;011F
-gcaron;01E7
-gcedilla;0123
-gcircle;24D6
-gcircumflex;011D
-gcommaaccent;0123
-gdot;0121
-gdotaccent;0121
-gecyrillic;0433
-gehiragana;3052
-gekatakana;30B2
-geometricallyequal;2251
-gereshaccenthebrew;059C
-gereshhebrew;05F3
-gereshmuqdamhebrew;059D
-germandbls;00DF
-gershayimaccenthebrew;059E
-gershayimhebrew;05F4
-getamark;3013
-ghabengali;0998
-ghadarmenian;0572
-ghadeva;0918
-ghagujarati;0A98
-ghagurmukhi;0A18
-ghainarabic;063A
-ghainfinalarabic;FECE
-ghaininitialarabic;FECF
-ghainmedialarabic;FED0
-ghemiddlehookcyrillic;0495
-ghestrokecyrillic;0493
-gheupturncyrillic;0491
-ghhadeva;095A
-ghhagurmukhi;0A5A
-ghook;0260
-ghzsquare;3393
-gihiragana;304E
-gikatakana;30AE
-gimarmenian;0563
-gimel;05D2
-gimeldagesh;FB32
-gimeldageshhebrew;FB32
-gimelhebrew;05D2
-gjecyrillic;0453
-glottalinvertedstroke;01BE
-glottalstop;0294
-glottalstopinverted;0296
-glottalstopmod;02C0
-glottalstopreversed;0295
-glottalstopreversedmod;02C1
-glottalstopreversedsuperior;02E4
-glottalstopstroke;02A1
-glottalstopstrokereversed;02A2
-gmacron;1E21
-gmonospace;FF47
-gohiragana;3054
-gokatakana;30B4
-gparen;24A2
-gpasquare;33AC
-gradient;2207
-grave;0060
-gravebelowcmb;0316
-gravecmb;0300
-gravecomb;0300
-gravedeva;0953
-gravelowmod;02CE
-gravemonospace;FF40
-gravetonecmb;0340
-greater;003E
-greaterequal;2265
-greaterequalorless;22DB
-greatermonospace;FF1E
-greaterorequivalent;2273
-greaterorless;2277
-greateroverequal;2267
-greatersmall;FE65
-gscript;0261
-gstroke;01E5
-guhiragana;3050
-guillemotleft;00AB
-guillemotright;00BB
-guilsinglleft;2039
-guilsinglright;203A
-gukatakana;30B0
-guramusquare;3318
-gysquare;33C9
-h;0068
-haabkhasiancyrillic;04A9
-haaltonearabic;06C1
-habengali;09B9
-hadescendercyrillic;04B3
-hadeva;0939
-hagujarati;0AB9
-hagurmukhi;0A39
-haharabic;062D
-hahfinalarabic;FEA2
-hahinitialarabic;FEA3
-hahiragana;306F
-hahmedialarabic;FEA4
-haitusquare;332A
-hakatakana;30CF
-hakatakanahalfwidth;FF8A
-halantgurmukhi;0A4D
-hamzaarabic;0621
-hamzadammaarabic;0621 064F
-hamzadammatanarabic;0621 064C
-hamzafathaarabic;0621 064E
-hamzafathatanarabic;0621 064B
-hamzalowarabic;0621
-hamzalowkasraarabic;0621 0650
-hamzalowkasratanarabic;0621 064D
-hamzasukunarabic;0621 0652
-hangulfiller;3164
-hardsigncyrillic;044A
-harpoonleftbarbup;21BC
-harpoonrightbarbup;21C0
-hasquare;33CA
-hatafpatah;05B2
-hatafpatah16;05B2
-hatafpatah23;05B2
-hatafpatah2f;05B2
-hatafpatahhebrew;05B2
-hatafpatahnarrowhebrew;05B2
-hatafpatahquarterhebrew;05B2
-hatafpatahwidehebrew;05B2
-hatafqamats;05B3
-hatafqamats1b;05B3
-hatafqamats28;05B3
-hatafqamats34;05B3
-hatafqamatshebrew;05B3
-hatafqamatsnarrowhebrew;05B3
-hatafqamatsquarterhebrew;05B3
-hatafqamatswidehebrew;05B3
-hatafsegol;05B1
-hatafsegol17;05B1
-hatafsegol24;05B1
-hatafsegol30;05B1
-hatafsegolhebrew;05B1
-hatafsegolnarrowhebrew;05B1
-hatafsegolquarterhebrew;05B1
-hatafsegolwidehebrew;05B1
-hbar;0127
-hbopomofo;310F
-hbrevebelow;1E2B
-hcedilla;1E29
-hcircle;24D7
-hcircumflex;0125
-hdieresis;1E27
-hdotaccent;1E23
-hdotbelow;1E25
-he;05D4
-heart;2665
-heartsuitblack;2665
-heartsuitwhite;2661
-hedagesh;FB34
-hedageshhebrew;FB34
-hehaltonearabic;06C1
-heharabic;0647
-hehebrew;05D4
-hehfinalaltonearabic;FBA7
-hehfinalalttwoarabic;FEEA
-hehfinalarabic;FEEA
-hehhamzaabovefinalarabic;FBA5
-hehhamzaaboveisolatedarabic;FBA4
-hehinitialaltonearabic;FBA8
-hehinitialarabic;FEEB
-hehiragana;3078
-hehmedialaltonearabic;FBA9
-hehmedialarabic;FEEC
-heiseierasquare;337B
-hekatakana;30D8
-hekatakanahalfwidth;FF8D
-hekutaarusquare;3336
-henghook;0267
-herutusquare;3339
-het;05D7
-hethebrew;05D7
-hhook;0266
-hhooksuperior;02B1
-hieuhacirclekorean;327B
-hieuhaparenkorean;321B
-hieuhcirclekorean;326D
-hieuhkorean;314E
-hieuhparenkorean;320D
-hihiragana;3072
-hikatakana;30D2
-hikatakanahalfwidth;FF8B
-hiriq;05B4
-hiriq14;05B4
-hiriq21;05B4
-hiriq2d;05B4
-hiriqhebrew;05B4
-hiriqnarrowhebrew;05B4
-hiriqquarterhebrew;05B4
-hiriqwidehebrew;05B4
-hlinebelow;1E96
-hmonospace;FF48
-hoarmenian;0570
-hohipthai;0E2B
-hohiragana;307B
-hokatakana;30DB
-hokatakanahalfwidth;FF8E
-holam;05B9
-holam19;05B9
-holam26;05B9
-holam32;05B9
-holamhebrew;05B9
-holamnarrowhebrew;05B9
-holamquarterhebrew;05B9
-holamwidehebrew;05B9
-honokhukthai;0E2E
-hookabovecomb;0309
-hookcmb;0309
-hookpalatalizedbelowcmb;0321
-hookretroflexbelowcmb;0322
-hoonsquare;3342
-horicoptic;03E9
-horizontalbar;2015
-horncmb;031B
-hotsprings;2668
-house;2302
-hparen;24A3
-hsuperior;02B0
-hturned;0265
-huhiragana;3075
-huiitosquare;3333
-hukatakana;30D5
-hukatakanahalfwidth;FF8C
-hungarumlaut;02DD
-hungarumlautcmb;030B
-hv;0195
-hyphen;002D
-hypheninferior;F6E5
-hyphenmonospace;FF0D
-hyphensmall;FE63
-hyphensuperior;F6E6
-hyphentwo;2010
-i;0069
-iacute;00ED
-iacyrillic;044F
-ibengali;0987
-ibopomofo;3127
-ibreve;012D
-icaron;01D0
-icircle;24D8
-icircumflex;00EE
-icyrillic;0456
-idblgrave;0209
-ideographearthcircle;328F
-ideographfirecircle;328B
-ideographicallianceparen;323F
-ideographiccallparen;323A
-ideographiccentrecircle;32A5
-ideographicclose;3006
-ideographiccomma;3001
-ideographiccommaleft;FF64
-ideographiccongratulationparen;3237
-ideographiccorrectcircle;32A3
-ideographicearthparen;322F
-ideographicenterpriseparen;323D
-ideographicexcellentcircle;329D
-ideographicfestivalparen;3240
-ideographicfinancialcircle;3296
-ideographicfinancialparen;3236
-ideographicfireparen;322B
-ideographichaveparen;3232
-ideographichighcircle;32A4
-ideographiciterationmark;3005
-ideographiclaborcircle;3298
-ideographiclaborparen;3238
-ideographicleftcircle;32A7
-ideographiclowcircle;32A6
-ideographicmedicinecircle;32A9
-ideographicmetalparen;322E
-ideographicmoonparen;322A
-ideographicnameparen;3234
-ideographicperiod;3002
-ideographicprintcircle;329E
-ideographicreachparen;3243
-ideographicrepresentparen;3239
-ideographicresourceparen;323E
-ideographicrightcircle;32A8
-ideographicsecretcircle;3299
-ideographicselfparen;3242
-ideographicsocietyparen;3233
-ideographicspace;3000
-ideographicspecialparen;3235
-ideographicstockparen;3231
-ideographicstudyparen;323B
-ideographicsunparen;3230
-ideographicsuperviseparen;323C
-ideographicwaterparen;322C
-ideographicwoodparen;322D
-ideographiczero;3007
-ideographmetalcircle;328E
-ideographmooncircle;328A
-ideographnamecircle;3294
-ideographsuncircle;3290
-ideographwatercircle;328C
-ideographwoodcircle;328D
-ideva;0907
-idieresis;00EF
-idieresisacute;1E2F
-idieresiscyrillic;04E5
-idotbelow;1ECB
-iebrevecyrillic;04D7
-iecyrillic;0435
-ieungacirclekorean;3275
-ieungaparenkorean;3215
-ieungcirclekorean;3267
-ieungkorean;3147
-ieungparenkorean;3207
-igrave;00EC
-igujarati;0A87
-igurmukhi;0A07
-ihiragana;3044
-ihookabove;1EC9
-iibengali;0988
-iicyrillic;0438
-iideva;0908
-iigujarati;0A88
-iigurmukhi;0A08
-iimatragurmukhi;0A40
-iinvertedbreve;020B
-iishortcyrillic;0439
-iivowelsignbengali;09C0
-iivowelsigndeva;0940
-iivowelsigngujarati;0AC0
-ij;0133
-ikatakana;30A4
-ikatakanahalfwidth;FF72
-ikorean;3163
-ilde;02DC
-iluyhebrew;05AC
-imacron;012B
-imacroncyrillic;04E3
-imageorapproximatelyequal;2253
-imatragurmukhi;0A3F
-imonospace;FF49
-increment;2206
-infinity;221E
-iniarmenian;056B
-integral;222B
-integralbottom;2321
-integralbt;2321
-integralex;F8F5
-integraltop;2320
-integraltp;2320
-intersection;2229
-intisquare;3305
-invbullet;25D8
-invcircle;25D9
-invsmileface;263B
-iocyrillic;0451
-iogonek;012F
-iota;03B9
-iotadieresis;03CA
-iotadieresistonos;0390
-iotalatin;0269
-iotatonos;03AF
-iparen;24A4
-irigurmukhi;0A72
-ismallhiragana;3043
-ismallkatakana;30A3
-ismallkatakanahalfwidth;FF68
-issharbengali;09FA
-istroke;0268
-isuperior;F6ED
-iterationhiragana;309D
-iterationkatakana;30FD
-itilde;0129
-itildebelow;1E2D
-iubopomofo;3129
-iucyrillic;044E
-ivowelsignbengali;09BF
-ivowelsigndeva;093F
-ivowelsigngujarati;0ABF
-izhitsacyrillic;0475
-izhitsadblgravecyrillic;0477
-j;006A
-jaarmenian;0571
-jabengali;099C
-jadeva;091C
-jagujarati;0A9C
-jagurmukhi;0A1C
-jbopomofo;3110
-jcaron;01F0
-jcircle;24D9
-jcircumflex;0135
-jcrossedtail;029D
-jdotlessstroke;025F
-jecyrillic;0458
-jeemarabic;062C
-jeemfinalarabic;FE9E
-jeeminitialarabic;FE9F
-jeemmedialarabic;FEA0
-jeharabic;0698
-jehfinalarabic;FB8B
-jhabengali;099D
-jhadeva;091D
-jhagujarati;0A9D
-jhagurmukhi;0A1D
-jheharmenian;057B
-jis;3004
-jmonospace;FF4A
-jparen;24A5
-jsuperior;02B2
-k;006B
-kabashkircyrillic;04A1
-kabengali;0995
-kacute;1E31
-kacyrillic;043A
-kadescendercyrillic;049B
-kadeva;0915
-kaf;05DB
-kafarabic;0643
-kafdagesh;FB3B
-kafdageshhebrew;FB3B
-kaffinalarabic;FEDA
-kafhebrew;05DB
-kafinitialarabic;FEDB
-kafmedialarabic;FEDC
-kafrafehebrew;FB4D
-kagujarati;0A95
-kagurmukhi;0A15
-kahiragana;304B
-kahookcyrillic;04C4
-kakatakana;30AB
-kakatakanahalfwidth;FF76
-kappa;03BA
-kappasymbolgreek;03F0
-kapyeounmieumkorean;3171
-kapyeounphieuphkorean;3184
-kapyeounpieupkorean;3178
-kapyeounssangpieupkorean;3179
-karoriisquare;330D
-kashidaautoarabic;0640
-kashidaautonosidebearingarabic;0640
-kasmallkatakana;30F5
-kasquare;3384
-kasraarabic;0650
-kasratanarabic;064D
-kastrokecyrillic;049F
-katahiraprolongmarkhalfwidth;FF70
-kaverticalstrokecyrillic;049D
-kbopomofo;310E
-kcalsquare;3389
-kcaron;01E9
-kcedilla;0137
-kcircle;24DA
-kcommaaccent;0137
-kdotbelow;1E33
-keharmenian;0584
-kehiragana;3051
-kekatakana;30B1
-kekatakanahalfwidth;FF79
-kenarmenian;056F
-kesmallkatakana;30F6
-kgreenlandic;0138
-khabengali;0996
-khacyrillic;0445
-khadeva;0916
-khagujarati;0A96
-khagurmukhi;0A16
-khaharabic;062E
-khahfinalarabic;FEA6
-khahinitialarabic;FEA7
-khahmedialarabic;FEA8
-kheicoptic;03E7
-khhadeva;0959
-khhagurmukhi;0A59
-khieukhacirclekorean;3278
-khieukhaparenkorean;3218
-khieukhcirclekorean;326A
-khieukhkorean;314B
-khieukhparenkorean;320A
-khokhaithai;0E02
-khokhonthai;0E05
-khokhuatthai;0E03
-khokhwaithai;0E04
-khomutthai;0E5B
-khook;0199
-khorakhangthai;0E06
-khzsquare;3391
-kihiragana;304D
-kikatakana;30AD
-kikatakanahalfwidth;FF77
-kiroguramusquare;3315
-kiromeetorusquare;3316
-kirosquare;3314
-kiyeokacirclekorean;326E
-kiyeokaparenkorean;320E
-kiyeokcirclekorean;3260
-kiyeokkorean;3131
-kiyeokparenkorean;3200
-kiyeoksioskorean;3133
-kjecyrillic;045C
-klinebelow;1E35
-klsquare;3398
-kmcubedsquare;33A6
-kmonospace;FF4B
-kmsquaredsquare;33A2
-kohiragana;3053
-kohmsquare;33C0
-kokaithai;0E01
-kokatakana;30B3
-kokatakanahalfwidth;FF7A
-kooposquare;331E
-koppacyrillic;0481
-koreanstandardsymbol;327F
-koroniscmb;0343
-kparen;24A6
-kpasquare;33AA
-ksicyrillic;046F
-ktsquare;33CF
-kturned;029E
-kuhiragana;304F
-kukatakana;30AF
-kukatakanahalfwidth;FF78
-kvsquare;33B8
-kwsquare;33BE
-l;006C
-labengali;09B2
-lacute;013A
-ladeva;0932
-lagujarati;0AB2
-lagurmukhi;0A32
-lakkhangyaothai;0E45
-lamaleffinalarabic;FEFC
-lamalefhamzaabovefinalarabic;FEF8
-lamalefhamzaaboveisolatedarabic;FEF7
-lamalefhamzabelowfinalarabic;FEFA
-lamalefhamzabelowisolatedarabic;FEF9
-lamalefisolatedarabic;FEFB
-lamalefmaddaabovefinalarabic;FEF6
-lamalefmaddaaboveisolatedarabic;FEF5
-lamarabic;0644
-lambda;03BB
-lambdastroke;019B
-lamed;05DC
-lameddagesh;FB3C
-lameddageshhebrew;FB3C
-lamedhebrew;05DC
-lamedholam;05DC 05B9
-lamedholamdagesh;05DC 05B9 05BC
-lamedholamdageshhebrew;05DC 05B9 05BC
-lamedholamhebrew;05DC 05B9
-lamfinalarabic;FEDE
-lamhahinitialarabic;FCCA
-laminitialarabic;FEDF
-lamjeeminitialarabic;FCC9
-lamkhahinitialarabic;FCCB
-lamlamhehisolatedarabic;FDF2
-lammedialarabic;FEE0
-lammeemhahinitialarabic;FD88
-lammeeminitialarabic;FCCC
-lammeemjeeminitialarabic;FEDF FEE4 FEA0
-lammeemkhahinitialarabic;FEDF FEE4 FEA8
-largecircle;25EF
-lbar;019A
-lbelt;026C
-lbopomofo;310C
-lcaron;013E
-lcedilla;013C
-lcircle;24DB
-lcircumflexbelow;1E3D
-lcommaaccent;013C
-ldot;0140
-ldotaccent;0140
-ldotbelow;1E37
-ldotbelowmacron;1E39
-leftangleabovecmb;031A
-lefttackbelowcmb;0318
-less;003C
-lessequal;2264
-lessequalorgreater;22DA
-lessmonospace;FF1C
-lessorequivalent;2272
-lessorgreater;2276
-lessoverequal;2266
-lesssmall;FE64
-lezh;026E
-lfblock;258C
-lhookretroflex;026D
-lira;20A4
-liwnarmenian;056C
-lj;01C9
-ljecyrillic;0459
-ll;F6C0
-lladeva;0933
-llagujarati;0AB3
-llinebelow;1E3B
-llladeva;0934
-llvocalicbengali;09E1
-llvocalicdeva;0961
-llvocalicvowelsignbengali;09E3
-llvocalicvowelsigndeva;0963
-lmiddletilde;026B
-lmonospace;FF4C
-lmsquare;33D0
-lochulathai;0E2C
-logicaland;2227
-logicalnot;00AC
-logicalnotreversed;2310
-logicalor;2228
-lolingthai;0E25
-longs;017F
-lowlinecenterline;FE4E
-lowlinecmb;0332
-lowlinedashed;FE4D
-lozenge;25CA
-lparen;24A7
-lslash;0142
-lsquare;2113
-lsuperior;F6EE
-ltshade;2591
-luthai;0E26
-lvocalicbengali;098C
-lvocalicdeva;090C
-lvocalicvowelsignbengali;09E2
-lvocalicvowelsigndeva;0962
-lxsquare;33D3
-m;006D
-mabengali;09AE
-macron;00AF
-macronbelowcmb;0331
-macroncmb;0304
-macronlowmod;02CD
-macronmonospace;FFE3
-macute;1E3F
-madeva;092E
-magujarati;0AAE
-magurmukhi;0A2E
-mahapakhhebrew;05A4
-mahapakhlefthebrew;05A4
-mahiragana;307E
-maichattawalowleftthai;F895
-maichattawalowrightthai;F894
-maichattawathai;0E4B
-maichattawaupperleftthai;F893
-maieklowleftthai;F88C
-maieklowrightthai;F88B
-maiekthai;0E48
-maiekupperleftthai;F88A
-maihanakatleftthai;F884
-maihanakatthai;0E31
-maitaikhuleftthai;F889
-maitaikhuthai;0E47
-maitholowleftthai;F88F
-maitholowrightthai;F88E
-maithothai;0E49
-maithoupperleftthai;F88D
-maitrilowleftthai;F892
-maitrilowrightthai;F891
-maitrithai;0E4A
-maitriupperleftthai;F890
-maiyamokthai;0E46
-makatakana;30DE
-makatakanahalfwidth;FF8F
-male;2642
-mansyonsquare;3347
-maqafhebrew;05BE
-mars;2642
-masoracirclehebrew;05AF
-masquare;3383
-mbopomofo;3107
-mbsquare;33D4
-mcircle;24DC
-mcubedsquare;33A5
-mdotaccent;1E41
-mdotbelow;1E43
-meemarabic;0645
-meemfinalarabic;FEE2
-meeminitialarabic;FEE3
-meemmedialarabic;FEE4
-meemmeeminitialarabic;FCD1
-meemmeemisolatedarabic;FC48
-meetorusquare;334D
-mehiragana;3081
-meizierasquare;337E
-mekatakana;30E1
-mekatakanahalfwidth;FF92
-mem;05DE
-memdagesh;FB3E
-memdageshhebrew;FB3E
-memhebrew;05DE
-menarmenian;0574
-merkhahebrew;05A5
-merkhakefulahebrew;05A6
-merkhakefulalefthebrew;05A6
-merkhalefthebrew;05A5
-mhook;0271
-mhzsquare;3392
-middledotkatakanahalfwidth;FF65
-middot;00B7
-mieumacirclekorean;3272
-mieumaparenkorean;3212
-mieumcirclekorean;3264
-mieumkorean;3141
-mieumpansioskorean;3170
-mieumparenkorean;3204
-mieumpieupkorean;316E
-mieumsioskorean;316F
-mihiragana;307F
-mikatakana;30DF
-mikatakanahalfwidth;FF90
-minus;2212
-minusbelowcmb;0320
-minuscircle;2296
-minusmod;02D7
-minusplus;2213
-minute;2032
-miribaarusquare;334A
-mirisquare;3349
-mlonglegturned;0270
-mlsquare;3396
-mmcubedsquare;33A3
-mmonospace;FF4D
-mmsquaredsquare;339F
-mohiragana;3082
-mohmsquare;33C1
-mokatakana;30E2
-mokatakanahalfwidth;FF93
-molsquare;33D6
-momathai;0E21
-moverssquare;33A7
-moverssquaredsquare;33A8
-mparen;24A8
-mpasquare;33AB
-mssquare;33B3
-msuperior;F6EF
-mturned;026F
-mu;00B5
-mu1;00B5
-muasquare;3382
-muchgreater;226B
-muchless;226A
-mufsquare;338C
-mugreek;03BC
-mugsquare;338D
-muhiragana;3080
-mukatakana;30E0
-mukatakanahalfwidth;FF91
-mulsquare;3395
-multiply;00D7
-mumsquare;339B
-munahhebrew;05A3
-munahlefthebrew;05A3
-musicalnote;266A
-musicalnotedbl;266B
-musicflatsign;266D
-musicsharpsign;266F
-mussquare;33B2
-muvsquare;33B6
-muwsquare;33BC
-mvmegasquare;33B9
-mvsquare;33B7
-mwmegasquare;33BF
-mwsquare;33BD
-n;006E
-nabengali;09A8
-nabla;2207
-nacute;0144
-nadeva;0928
-nagujarati;0AA8
-nagurmukhi;0A28
-nahiragana;306A
-nakatakana;30CA
-nakatakanahalfwidth;FF85
-napostrophe;0149
-nasquare;3381
-nbopomofo;310B
-nbspace;00A0
-ncaron;0148
-ncedilla;0146
-ncircle;24DD
-ncircumflexbelow;1E4B
-ncommaaccent;0146
-ndotaccent;1E45
-ndotbelow;1E47
-nehiragana;306D
-nekatakana;30CD
-nekatakanahalfwidth;FF88
-newsheqelsign;20AA
-nfsquare;338B
-ngabengali;0999
-ngadeva;0919
-ngagujarati;0A99
-ngagurmukhi;0A19
-ngonguthai;0E07
-nhiragana;3093
-nhookleft;0272
-nhookretroflex;0273
-nieunacirclekorean;326F
-nieunaparenkorean;320F
-nieuncieuckorean;3135
-nieuncirclekorean;3261
-nieunhieuhkorean;3136
-nieunkorean;3134
-nieunpansioskorean;3168
-nieunparenkorean;3201
-nieunsioskorean;3167
-nieuntikeutkorean;3166
-nihiragana;306B
-nikatakana;30CB
-nikatakanahalfwidth;FF86
-nikhahitleftthai;F899
-nikhahitthai;0E4D
-nine;0039
-ninearabic;0669
-ninebengali;09EF
-ninecircle;2468
-ninecircleinversesansserif;2792
-ninedeva;096F
-ninegujarati;0AEF
-ninegurmukhi;0A6F
-ninehackarabic;0669
-ninehangzhou;3029
-nineideographicparen;3228
-nineinferior;2089
-ninemonospace;FF19
-nineoldstyle;F739
-nineparen;247C
-nineperiod;2490
-ninepersian;06F9
-nineroman;2178
-ninesuperior;2079
-nineteencircle;2472
-nineteenparen;2486
-nineteenperiod;249A
-ninethai;0E59
-nj;01CC
-njecyrillic;045A
-nkatakana;30F3
-nkatakanahalfwidth;FF9D
-nlegrightlong;019E
-nlinebelow;1E49
-nmonospace;FF4E
-nmsquare;339A
-nnabengali;09A3
-nnadeva;0923
-nnagujarati;0AA3
-nnagurmukhi;0A23
-nnnadeva;0929
-nohiragana;306E
-nokatakana;30CE
-nokatakanahalfwidth;FF89
-nonbreakingspace;00A0
-nonenthai;0E13
-nonuthai;0E19
-noonarabic;0646
-noonfinalarabic;FEE6
-noonghunnaarabic;06BA
-noonghunnafinalarabic;FB9F
-noonhehinitialarabic;FEE7 FEEC
-nooninitialarabic;FEE7
-noonjeeminitialarabic;FCD2
-noonjeemisolatedarabic;FC4B
-noonmedialarabic;FEE8
-noonmeeminitialarabic;FCD5
-noonmeemisolatedarabic;FC4E
-noonnoonfinalarabic;FC8D
-notcontains;220C
-notelement;2209
-notelementof;2209
-notequal;2260
-notgreater;226F
-notgreaternorequal;2271
-notgreaternorless;2279
-notidentical;2262
-notless;226E
-notlessnorequal;2270
-notparallel;2226
-notprecedes;2280
-notsubset;2284
-notsucceeds;2281
-notsuperset;2285
-nowarmenian;0576
-nparen;24A9
-nssquare;33B1
-nsuperior;207F
-ntilde;00F1
-nu;03BD
-nuhiragana;306C
-nukatakana;30CC
-nukatakanahalfwidth;FF87
-nuktabengali;09BC
-nuktadeva;093C
-nuktagujarati;0ABC
-nuktagurmukhi;0A3C
-numbersign;0023
-numbersignmonospace;FF03
-numbersignsmall;FE5F
-numeralsigngreek;0374
-numeralsignlowergreek;0375
-numero;2116
-nun;05E0
-nundagesh;FB40
-nundageshhebrew;FB40
-nunhebrew;05E0
-nvsquare;33B5
-nwsquare;33BB
-nyabengali;099E
-nyadeva;091E
-nyagujarati;0A9E
-nyagurmukhi;0A1E
-o;006F
-oacute;00F3
-oangthai;0E2D
-obarred;0275
-obarredcyrillic;04E9
-obarreddieresiscyrillic;04EB
-obengali;0993
-obopomofo;311B
-obreve;014F
-ocandradeva;0911
-ocandragujarati;0A91
-ocandravowelsigndeva;0949
-ocandravowelsigngujarati;0AC9
-ocaron;01D2
-ocircle;24DE
-ocircumflex;00F4
-ocircumflexacute;1ED1
-ocircumflexdotbelow;1ED9
-ocircumflexgrave;1ED3
-ocircumflexhookabove;1ED5
-ocircumflextilde;1ED7
-ocyrillic;043E
-odblacute;0151
-odblgrave;020D
-odeva;0913
-odieresis;00F6
-odieresiscyrillic;04E7
-odotbelow;1ECD
-oe;0153
-oekorean;315A
-ogonek;02DB
-ogonekcmb;0328
-ograve;00F2
-ogujarati;0A93
-oharmenian;0585
-ohiragana;304A
-ohookabove;1ECF
-ohorn;01A1
-ohornacute;1EDB
-ohorndotbelow;1EE3
-ohorngrave;1EDD
-ohornhookabove;1EDF
-ohorntilde;1EE1
-ohungarumlaut;0151
-oi;01A3
-oinvertedbreve;020F
-okatakana;30AA
-okatakanahalfwidth;FF75
-okorean;3157
-olehebrew;05AB
-omacron;014D
-omacronacute;1E53
-omacrongrave;1E51
-omdeva;0950
-omega;03C9
-omega1;03D6
-omegacyrillic;0461
-omegalatinclosed;0277
-omegaroundcyrillic;047B
-omegatitlocyrillic;047D
-omegatonos;03CE
-omgujarati;0AD0
-omicron;03BF
-omicrontonos;03CC
-omonospace;FF4F
-one;0031
-onearabic;0661
-onebengali;09E7
-onecircle;2460
-onecircleinversesansserif;278A
-onedeva;0967
-onedotenleader;2024
-oneeighth;215B
-onefitted;F6DC
-onegujarati;0AE7
-onegurmukhi;0A67
-onehackarabic;0661
-onehalf;00BD
-onehangzhou;3021
-oneideographicparen;3220
-oneinferior;2081
-onemonospace;FF11
-onenumeratorbengali;09F4
-oneoldstyle;F731
-oneparen;2474
-oneperiod;2488
-onepersian;06F1
-onequarter;00BC
-oneroman;2170
-onesuperior;00B9
-onethai;0E51
-onethird;2153
-oogonek;01EB
-oogonekmacron;01ED
-oogurmukhi;0A13
-oomatragurmukhi;0A4B
-oopen;0254
-oparen;24AA
-openbullet;25E6
-option;2325
-ordfeminine;00AA
-ordmasculine;00BA
-orthogonal;221F
-oshortdeva;0912
-oshortvowelsigndeva;094A
-oslash;00F8
-oslashacute;01FF
-osmallhiragana;3049
-osmallkatakana;30A9
-osmallkatakanahalfwidth;FF6B
-ostrokeacute;01FF
-osuperior;F6F0
-otcyrillic;047F
-otilde;00F5
-otildeacute;1E4D
-otildedieresis;1E4F
-oubopomofo;3121
-overline;203E
-overlinecenterline;FE4A
-overlinecmb;0305
-overlinedashed;FE49
-overlinedblwavy;FE4C
-overlinewavy;FE4B
-overscore;00AF
-ovowelsignbengali;09CB
-ovowelsigndeva;094B
-ovowelsigngujarati;0ACB
-p;0070
-paampssquare;3380
-paasentosquare;332B
-pabengali;09AA
-pacute;1E55
-padeva;092A
-pagedown;21DF
-pageup;21DE
-pagujarati;0AAA
-pagurmukhi;0A2A
-pahiragana;3071
-paiyannoithai;0E2F
-pakatakana;30D1
-palatalizationcyrilliccmb;0484
-palochkacyrillic;04C0
-pansioskorean;317F
-paragraph;00B6
-parallel;2225
-parenleft;0028
-parenleftaltonearabic;FD3E
-parenleftbt;F8ED
-parenleftex;F8EC
-parenleftinferior;208D
-parenleftmonospace;FF08
-parenleftsmall;FE59
-parenleftsuperior;207D
-parenlefttp;F8EB
-parenleftvertical;FE35
-parenright;0029
-parenrightaltonearabic;FD3F
-parenrightbt;F8F8
-parenrightex;F8F7
-parenrightinferior;208E
-parenrightmonospace;FF09
-parenrightsmall;FE5A
-parenrightsuperior;207E
-parenrighttp;F8F6
-parenrightvertical;FE36
-partialdiff;2202
-paseqhebrew;05C0
-pashtahebrew;0599
-pasquare;33A9
-patah;05B7
-patah11;05B7
-patah1d;05B7
-patah2a;05B7
-patahhebrew;05B7
-patahnarrowhebrew;05B7
-patahquarterhebrew;05B7
-patahwidehebrew;05B7
-pazerhebrew;05A1
-pbopomofo;3106
-pcircle;24DF
-pdotaccent;1E57
-pe;05E4
-pecyrillic;043F
-pedagesh;FB44
-pedageshhebrew;FB44
-peezisquare;333B
-pefinaldageshhebrew;FB43
-peharabic;067E
-peharmenian;057A
-pehebrew;05E4
-pehfinalarabic;FB57
-pehinitialarabic;FB58
-pehiragana;307A
-pehmedialarabic;FB59
-pekatakana;30DA
-pemiddlehookcyrillic;04A7
-perafehebrew;FB4E
-percent;0025
-percentarabic;066A
-percentmonospace;FF05
-percentsmall;FE6A
-period;002E
-periodarmenian;0589
-periodcentered;00B7
-periodhalfwidth;FF61
-periodinferior;F6E7
-periodmonospace;FF0E
-periodsmall;FE52
-periodsuperior;F6E8
-perispomenigreekcmb;0342
-perpendicular;22A5
-perthousand;2030
-peseta;20A7
-pfsquare;338A
-phabengali;09AB
-phadeva;092B
-phagujarati;0AAB
-phagurmukhi;0A2B
-phi;03C6
-phi1;03D5
-phieuphacirclekorean;327A
-phieuphaparenkorean;321A
-phieuphcirclekorean;326C
-phieuphkorean;314D
-phieuphparenkorean;320C
-philatin;0278
-phinthuthai;0E3A
-phisymbolgreek;03D5
-phook;01A5
-phophanthai;0E1E
-phophungthai;0E1C
-phosamphaothai;0E20
-pi;03C0
-pieupacirclekorean;3273
-pieupaparenkorean;3213
-pieupcieuckorean;3176
-pieupcirclekorean;3265
-pieupkiyeokkorean;3172
-pieupkorean;3142
-pieupparenkorean;3205
-pieupsioskiyeokkorean;3174
-pieupsioskorean;3144
-pieupsiostikeutkorean;3175
-pieupthieuthkorean;3177
-pieuptikeutkorean;3173
-pihiragana;3074
-pikatakana;30D4
-pisymbolgreek;03D6
-piwrarmenian;0583
-plus;002B
-plusbelowcmb;031F
-pluscircle;2295
-plusminus;00B1
-plusmod;02D6
-plusmonospace;FF0B
-plussmall;FE62
-plussuperior;207A
-pmonospace;FF50
-pmsquare;33D8
-pohiragana;307D
-pointingindexdownwhite;261F
-pointingindexleftwhite;261C
-pointingindexrightwhite;261E
-pointingindexupwhite;261D
-pokatakana;30DD
-poplathai;0E1B
-postalmark;3012
-postalmarkface;3020
-pparen;24AB
-precedes;227A
-prescription;211E
-primemod;02B9
-primereversed;2035
-product;220F
-projective;2305
-prolongedkana;30FC
-propellor;2318
-propersubset;2282
-propersuperset;2283
-proportion;2237
-proportional;221D
-psi;03C8
-psicyrillic;0471
-psilipneumatacyrilliccmb;0486
-pssquare;33B0
-puhiragana;3077
-pukatakana;30D7
-pvsquare;33B4
-pwsquare;33BA
-q;0071
-qadeva;0958
-qadmahebrew;05A8
-qafarabic;0642
-qaffinalarabic;FED6
-qafinitialarabic;FED7
-qafmedialarabic;FED8
-qamats;05B8
-qamats10;05B8
-qamats1a;05B8
-qamats1c;05B8
-qamats27;05B8
-qamats29;05B8
-qamats33;05B8
-qamatsde;05B8
-qamatshebrew;05B8
-qamatsnarrowhebrew;05B8
-qamatsqatanhebrew;05B8
-qamatsqatannarrowhebrew;05B8
-qamatsqatanquarterhebrew;05B8
-qamatsqatanwidehebrew;05B8
-qamatsquarterhebrew;05B8
-qamatswidehebrew;05B8
-qarneyparahebrew;059F
-qbopomofo;3111
-qcircle;24E0
-qhook;02A0
-qmonospace;FF51
-qof;05E7
-qofdagesh;FB47
-qofdageshhebrew;FB47
-qofhatafpatah;05E7 05B2
-qofhatafpatahhebrew;05E7 05B2
-qofhatafsegol;05E7 05B1
-qofhatafsegolhebrew;05E7 05B1
-qofhebrew;05E7
-qofhiriq;05E7 05B4
-qofhiriqhebrew;05E7 05B4
-qofholam;05E7 05B9
-qofholamhebrew;05E7 05B9
-qofpatah;05E7 05B7
-qofpatahhebrew;05E7 05B7
-qofqamats;05E7 05B8
-qofqamatshebrew;05E7 05B8
-qofqubuts;05E7 05BB
-qofqubutshebrew;05E7 05BB
-qofsegol;05E7 05B6
-qofsegolhebrew;05E7 05B6
-qofsheva;05E7 05B0
-qofshevahebrew;05E7 05B0
-qoftsere;05E7 05B5
-qoftserehebrew;05E7 05B5
-qparen;24AC
-quarternote;2669
-qubuts;05BB
-qubuts18;05BB
-qubuts25;05BB
-qubuts31;05BB
-qubutshebrew;05BB
-qubutsnarrowhebrew;05BB
-qubutsquarterhebrew;05BB
-qubutswidehebrew;05BB
-question;003F
-questionarabic;061F
-questionarmenian;055E
-questiondown;00BF
-questiondownsmall;F7BF
-questiongreek;037E
-questionmonospace;FF1F
-questionsmall;F73F
-quotedbl;0022
-quotedblbase;201E
-quotedblleft;201C
-quotedblmonospace;FF02
-quotedblprime;301E
-quotedblprimereversed;301D
-quotedblright;201D
-quoteleft;2018
-quoteleftreversed;201B
-quotereversed;201B
-quoteright;2019
-quoterightn;0149
-quotesinglbase;201A
-quotesingle;0027
-quotesinglemonospace;FF07
-r;0072
-raarmenian;057C
-rabengali;09B0
-racute;0155
-radeva;0930
-radical;221A
-radicalex;F8E5
-radoverssquare;33AE
-radoverssquaredsquare;33AF
-radsquare;33AD
-rafe;05BF
-rafehebrew;05BF
-ragujarati;0AB0
-ragurmukhi;0A30
-rahiragana;3089
-rakatakana;30E9
-rakatakanahalfwidth;FF97
-ralowerdiagonalbengali;09F1
-ramiddlediagonalbengali;09F0
-ramshorn;0264
-ratio;2236
-rbopomofo;3116
-rcaron;0159
-rcedilla;0157
-rcircle;24E1
-rcommaaccent;0157
-rdblgrave;0211
-rdotaccent;1E59
-rdotbelow;1E5B
-rdotbelowmacron;1E5D
-referencemark;203B
-reflexsubset;2286
-reflexsuperset;2287
-registered;00AE
-registersans;F8E8
-registerserif;F6DA
-reharabic;0631
-reharmenian;0580
-rehfinalarabic;FEAE
-rehiragana;308C
-rehyehaleflamarabic;0631 FEF3 FE8E 0644
-rekatakana;30EC
-rekatakanahalfwidth;FF9A
-resh;05E8
-reshdageshhebrew;FB48
-reshhatafpatah;05E8 05B2
-reshhatafpatahhebrew;05E8 05B2
-reshhatafsegol;05E8 05B1
-reshhatafsegolhebrew;05E8 05B1
-reshhebrew;05E8
-reshhiriq;05E8 05B4
-reshhiriqhebrew;05E8 05B4
-reshholam;05E8 05B9
-reshholamhebrew;05E8 05B9
-reshpatah;05E8 05B7
-reshpatahhebrew;05E8 05B7
-reshqamats;05E8 05B8
-reshqamatshebrew;05E8 05B8
-reshqubuts;05E8 05BB
-reshqubutshebrew;05E8 05BB
-reshsegol;05E8 05B6
-reshsegolhebrew;05E8 05B6
-reshsheva;05E8 05B0
-reshshevahebrew;05E8 05B0
-reshtsere;05E8 05B5
-reshtserehebrew;05E8 05B5
-reversedtilde;223D
-reviahebrew;0597
-reviamugrashhebrew;0597
-revlogicalnot;2310
-rfishhook;027E
-rfishhookreversed;027F
-rhabengali;09DD
-rhadeva;095D
-rho;03C1
-rhook;027D
-rhookturned;027B
-rhookturnedsuperior;02B5
-rhosymbolgreek;03F1
-rhotichookmod;02DE
-rieulacirclekorean;3271
-rieulaparenkorean;3211
-rieulcirclekorean;3263
-rieulhieuhkorean;3140
-rieulkiyeokkorean;313A
-rieulkiyeoksioskorean;3169
-rieulkorean;3139
-rieulmieumkorean;313B
-rieulpansioskorean;316C
-rieulparenkorean;3203
-rieulphieuphkorean;313F
-rieulpieupkorean;313C
-rieulpieupsioskorean;316B
-rieulsioskorean;313D
-rieulthieuthkorean;313E
-rieultikeutkorean;316A
-rieulyeorinhieuhkorean;316D
-rightangle;221F
-righttackbelowcmb;0319
-righttriangle;22BF
-rihiragana;308A
-rikatakana;30EA
-rikatakanahalfwidth;FF98
-ring;02DA
-ringbelowcmb;0325
-ringcmb;030A
-ringhalfleft;02BF
-ringhalfleftarmenian;0559
-ringhalfleftbelowcmb;031C
-ringhalfleftcentered;02D3
-ringhalfright;02BE
-ringhalfrightbelowcmb;0339
-ringhalfrightcentered;02D2
-rinvertedbreve;0213
-rittorusquare;3351
-rlinebelow;1E5F
-rlongleg;027C
-rlonglegturned;027A
-rmonospace;FF52
-rohiragana;308D
-rokatakana;30ED
-rokatakanahalfwidth;FF9B
-roruathai;0E23
-rparen;24AD
-rrabengali;09DC
-rradeva;0931
-rragurmukhi;0A5C
-rreharabic;0691
-rrehfinalarabic;FB8D
-rrvocalicbengali;09E0
-rrvocalicdeva;0960
-rrvocalicgujarati;0AE0
-rrvocalicvowelsignbengali;09C4
-rrvocalicvowelsigndeva;0944
-rrvocalicvowelsigngujarati;0AC4
-rsuperior;F6F1
-rtblock;2590
-rturned;0279
-rturnedsuperior;02B4
-ruhiragana;308B
-rukatakana;30EB
-rukatakanahalfwidth;FF99
-rupeemarkbengali;09F2
-rupeesignbengali;09F3
-rupiah;F6DD
-ruthai;0E24
-rvocalicbengali;098B
-rvocalicdeva;090B
-rvocalicgujarati;0A8B
-rvocalicvowelsignbengali;09C3
-rvocalicvowelsigndeva;0943
-rvocalicvowelsigngujarati;0AC3
-s;0073
-sabengali;09B8
-sacute;015B
-sacutedotaccent;1E65
-sadarabic;0635
-sadeva;0938
-sadfinalarabic;FEBA
-sadinitialarabic;FEBB
-sadmedialarabic;FEBC
-sagujarati;0AB8
-sagurmukhi;0A38
-sahiragana;3055
-sakatakana;30B5
-sakatakanahalfwidth;FF7B
-sallallahoualayhewasallamarabic;FDFA
-samekh;05E1
-samekhdagesh;FB41
-samekhdageshhebrew;FB41
-samekhhebrew;05E1
-saraaathai;0E32
-saraaethai;0E41
-saraaimaimalaithai;0E44
-saraaimaimuanthai;0E43
-saraamthai;0E33
-saraathai;0E30
-saraethai;0E40
-saraiileftthai;F886
-saraiithai;0E35
-saraileftthai;F885
-saraithai;0E34
-saraothai;0E42
-saraueeleftthai;F888
-saraueethai;0E37
-saraueleftthai;F887
-sarauethai;0E36
-sarauthai;0E38
-sarauuthai;0E39
-sbopomofo;3119
-scaron;0161
-scarondotaccent;1E67
-scedilla;015F
-schwa;0259
-schwacyrillic;04D9
-schwadieresiscyrillic;04DB
-schwahook;025A
-scircle;24E2
-scircumflex;015D
-scommaaccent;0219
-sdotaccent;1E61
-sdotbelow;1E63
-sdotbelowdotaccent;1E69
-seagullbelowcmb;033C
-second;2033
-secondtonechinese;02CA
-section;00A7
-seenarabic;0633
-seenfinalarabic;FEB2
-seeninitialarabic;FEB3
-seenmedialarabic;FEB4
-segol;05B6
-segol13;05B6
-segol1f;05B6
-segol2c;05B6
-segolhebrew;05B6
-segolnarrowhebrew;05B6
-segolquarterhebrew;05B6
-segoltahebrew;0592
-segolwidehebrew;05B6
-seharmenian;057D
-sehiragana;305B
-sekatakana;30BB
-sekatakanahalfwidth;FF7E
-semicolon;003B
-semicolonarabic;061B
-semicolonmonospace;FF1B
-semicolonsmall;FE54
-semivoicedmarkkana;309C
-semivoicedmarkkanahalfwidth;FF9F
-sentisquare;3322
-sentosquare;3323
-seven;0037
-sevenarabic;0667
-sevenbengali;09ED
-sevencircle;2466
-sevencircleinversesansserif;2790
-sevendeva;096D
-seveneighths;215E
-sevengujarati;0AED
-sevengurmukhi;0A6D
-sevenhackarabic;0667
-sevenhangzhou;3027
-sevenideographicparen;3226
-seveninferior;2087
-sevenmonospace;FF17
-sevenoldstyle;F737
-sevenparen;247A
-sevenperiod;248E
-sevenpersian;06F7
-sevenroman;2176
-sevensuperior;2077
-seventeencircle;2470
-seventeenparen;2484
-seventeenperiod;2498
-seventhai;0E57
-sfthyphen;00AD
-shaarmenian;0577
-shabengali;09B6
-shacyrillic;0448
-shaddaarabic;0651
-shaddadammaarabic;FC61
-shaddadammatanarabic;FC5E
-shaddafathaarabic;FC60
-shaddafathatanarabic;0651 064B
-shaddakasraarabic;FC62
-shaddakasratanarabic;FC5F
-shade;2592
-shadedark;2593
-shadelight;2591
-shademedium;2592
-shadeva;0936
-shagujarati;0AB6
-shagurmukhi;0A36
-shalshelethebrew;0593
-shbopomofo;3115
-shchacyrillic;0449
-sheenarabic;0634
-sheenfinalarabic;FEB6
-sheeninitialarabic;FEB7
-sheenmedialarabic;FEB8
-sheicoptic;03E3
-sheqel;20AA
-sheqelhebrew;20AA
-sheva;05B0
-sheva115;05B0
-sheva15;05B0
-sheva22;05B0
-sheva2e;05B0
-shevahebrew;05B0
-shevanarrowhebrew;05B0
-shevaquarterhebrew;05B0
-shevawidehebrew;05B0
-shhacyrillic;04BB
-shimacoptic;03ED
-shin;05E9
-shindagesh;FB49
-shindageshhebrew;FB49
-shindageshshindot;FB2C
-shindageshshindothebrew;FB2C
-shindageshsindot;FB2D
-shindageshsindothebrew;FB2D
-shindothebrew;05C1
-shinhebrew;05E9
-shinshindot;FB2A
-shinshindothebrew;FB2A
-shinsindot;FB2B
-shinsindothebrew;FB2B
-shook;0282
-sigma;03C3
-sigma1;03C2
-sigmafinal;03C2
-sigmalunatesymbolgreek;03F2
-sihiragana;3057
-sikatakana;30B7
-sikatakanahalfwidth;FF7C
-siluqhebrew;05BD
-siluqlefthebrew;05BD
-similar;223C
-sindothebrew;05C2
-siosacirclekorean;3274
-siosaparenkorean;3214
-sioscieuckorean;317E
-sioscirclekorean;3266
-sioskiyeokkorean;317A
-sioskorean;3145
-siosnieunkorean;317B
-siosparenkorean;3206
-siospieupkorean;317D
-siostikeutkorean;317C
-six;0036
-sixarabic;0666
-sixbengali;09EC
-sixcircle;2465
-sixcircleinversesansserif;278F
-sixdeva;096C
-sixgujarati;0AEC
-sixgurmukhi;0A6C
-sixhackarabic;0666
-sixhangzhou;3026
-sixideographicparen;3225
-sixinferior;2086
-sixmonospace;FF16
-sixoldstyle;F736
-sixparen;2479
-sixperiod;248D
-sixpersian;06F6
-sixroman;2175
-sixsuperior;2076
-sixteencircle;246F
-sixteencurrencydenominatorbengali;09F9
-sixteenparen;2483
-sixteenperiod;2497
-sixthai;0E56
-slash;002F
-slashmonospace;FF0F
-slong;017F
-slongdotaccent;1E9B
-smileface;263A
-smonospace;FF53
-sofpasuqhebrew;05C3
-softhyphen;00AD
-softsigncyrillic;044C
-sohiragana;305D
-sokatakana;30BD
-sokatakanahalfwidth;FF7F
-soliduslongoverlaycmb;0338
-solidusshortoverlaycmb;0337
-sorusithai;0E29
-sosalathai;0E28
-sosothai;0E0B
-sosuathai;0E2A
-space;0020
-spacehackarabic;0020
-spade;2660
-spadesuitblack;2660
-spadesuitwhite;2664
-sparen;24AE
-squarebelowcmb;033B
-squarecc;33C4
-squarecm;339D
-squarediagonalcrosshatchfill;25A9
-squarehorizontalfill;25A4
-squarekg;338F
-squarekm;339E
-squarekmcapital;33CE
-squareln;33D1
-squarelog;33D2
-squaremg;338E
-squaremil;33D5
-squaremm;339C
-squaremsquared;33A1
-squareorthogonalcrosshatchfill;25A6
-squareupperlefttolowerrightfill;25A7
-squareupperrighttolowerleftfill;25A8
-squareverticalfill;25A5
-squarewhitewithsmallblack;25A3
-srsquare;33DB
-ssabengali;09B7
-ssadeva;0937
-ssagujarati;0AB7
-ssangcieuckorean;3149
-ssanghieuhkorean;3185
-ssangieungkorean;3180
-ssangkiyeokkorean;3132
-ssangnieunkorean;3165
-ssangpieupkorean;3143
-ssangsioskorean;3146
-ssangtikeutkorean;3138
-ssuperior;F6F2
-sterling;00A3
-sterlingmonospace;FFE1
-strokelongoverlaycmb;0336
-strokeshortoverlaycmb;0335
-subset;2282
-subsetnotequal;228A
-subsetorequal;2286
-succeeds;227B
-suchthat;220B
-suhiragana;3059
-sukatakana;30B9
-sukatakanahalfwidth;FF7D
-sukunarabic;0652
-summation;2211
-sun;263C
-superset;2283
-supersetnotequal;228B
-supersetorequal;2287
-svsquare;33DC
-syouwaerasquare;337C
-t;0074
-tabengali;09A4
-tackdown;22A4
-tackleft;22A3
-tadeva;0924
-tagujarati;0AA4
-tagurmukhi;0A24
-taharabic;0637
-tahfinalarabic;FEC2
-tahinitialarabic;FEC3
-tahiragana;305F
-tahmedialarabic;FEC4
-taisyouerasquare;337D
-takatakana;30BF
-takatakanahalfwidth;FF80
-tatweelarabic;0640
-tau;03C4
-tav;05EA
-tavdages;FB4A
-tavdagesh;FB4A
-tavdageshhebrew;FB4A
-tavhebrew;05EA
-tbar;0167
-tbopomofo;310A
-tcaron;0165
-tccurl;02A8
-tcedilla;0163
-tcheharabic;0686
-tchehfinalarabic;FB7B
-tchehinitialarabic;FB7C
-tchehmedialarabic;FB7D
-tchehmeeminitialarabic;FB7C FEE4
-tcircle;24E3
-tcircumflexbelow;1E71
-tcommaaccent;0163
-tdieresis;1E97
-tdotaccent;1E6B
-tdotbelow;1E6D
-tecyrillic;0442
-tedescendercyrillic;04AD
-teharabic;062A
-tehfinalarabic;FE96
-tehhahinitialarabic;FCA2
-tehhahisolatedarabic;FC0C
-tehinitialarabic;FE97
-tehiragana;3066
-tehjeeminitialarabic;FCA1
-tehjeemisolatedarabic;FC0B
-tehmarbutaarabic;0629
-tehmarbutafinalarabic;FE94
-tehmedialarabic;FE98
-tehmeeminitialarabic;FCA4
-tehmeemisolatedarabic;FC0E
-tehnoonfinalarabic;FC73
-tekatakana;30C6
-tekatakanahalfwidth;FF83
-telephone;2121
-telephoneblack;260E
-telishagedolahebrew;05A0
-telishaqetanahebrew;05A9
-tencircle;2469
-tenideographicparen;3229
-tenparen;247D
-tenperiod;2491
-tenroman;2179
-tesh;02A7
-tet;05D8
-tetdagesh;FB38
-tetdageshhebrew;FB38
-tethebrew;05D8
-tetsecyrillic;04B5
-tevirhebrew;059B
-tevirlefthebrew;059B
-thabengali;09A5
-thadeva;0925
-thagujarati;0AA5
-thagurmukhi;0A25
-thalarabic;0630
-thalfinalarabic;FEAC
-thanthakhatlowleftthai;F898
-thanthakhatlowrightthai;F897
-thanthakhatthai;0E4C
-thanthakhatupperleftthai;F896
-theharabic;062B
-thehfinalarabic;FE9A
-thehinitialarabic;FE9B
-thehmedialarabic;FE9C
-thereexists;2203
-therefore;2234
-theta;03B8
-theta1;03D1
-thetasymbolgreek;03D1
-thieuthacirclekorean;3279
-thieuthaparenkorean;3219
-thieuthcirclekorean;326B
-thieuthkorean;314C
-thieuthparenkorean;320B
-thirteencircle;246C
-thirteenparen;2480
-thirteenperiod;2494
-thonangmonthothai;0E11
-thook;01AD
-thophuthaothai;0E12
-thorn;00FE
-thothahanthai;0E17
-thothanthai;0E10
-thothongthai;0E18
-thothungthai;0E16
-thousandcyrillic;0482
-thousandsseparatorarabic;066C
-thousandsseparatorpersian;066C
-three;0033
-threearabic;0663
-threebengali;09E9
-threecircle;2462
-threecircleinversesansserif;278C
-threedeva;0969
-threeeighths;215C
-threegujarati;0AE9
-threegurmukhi;0A69
-threehackarabic;0663
-threehangzhou;3023
-threeideographicparen;3222
-threeinferior;2083
-threemonospace;FF13
-threenumeratorbengali;09F6
-threeoldstyle;F733
-threeparen;2476
-threeperiod;248A
-threepersian;06F3
-threequarters;00BE
-threequartersemdash;F6DE
-threeroman;2172
-threesuperior;00B3
-threethai;0E53
-thzsquare;3394
-tihiragana;3061
-tikatakana;30C1
-tikatakanahalfwidth;FF81
-tikeutacirclekorean;3270
-tikeutaparenkorean;3210
-tikeutcirclekorean;3262
-tikeutkorean;3137
-tikeutparenkorean;3202
-tilde;02DC
-tildebelowcmb;0330
-tildecmb;0303
-tildecomb;0303
-tildedoublecmb;0360
-tildeoperator;223C
-tildeoverlaycmb;0334
-tildeverticalcmb;033E
-timescircle;2297
-tipehahebrew;0596
-tipehalefthebrew;0596
-tippigurmukhi;0A70
-titlocyrilliccmb;0483
-tiwnarmenian;057F
-tlinebelow;1E6F
-tmonospace;FF54
-toarmenian;0569
-tohiragana;3068
-tokatakana;30C8
-tokatakanahalfwidth;FF84
-tonebarextrahighmod;02E5
-tonebarextralowmod;02E9
-tonebarhighmod;02E6
-tonebarlowmod;02E8
-tonebarmidmod;02E7
-tonefive;01BD
-tonesix;0185
-tonetwo;01A8
-tonos;0384
-tonsquare;3327
-topatakthai;0E0F
-tortoiseshellbracketleft;3014
-tortoiseshellbracketleftsmall;FE5D
-tortoiseshellbracketleftvertical;FE39
-tortoiseshellbracketright;3015
-tortoiseshellbracketrightsmall;FE5E
-tortoiseshellbracketrightvertical;FE3A
-totaothai;0E15
-tpalatalhook;01AB
-tparen;24AF
-trademark;2122
-trademarksans;F8EA
-trademarkserif;F6DB
-tretroflexhook;0288
-triagdn;25BC
-triaglf;25C4
-triagrt;25BA
-triagup;25B2
-ts;02A6
-tsadi;05E6
-tsadidagesh;FB46
-tsadidageshhebrew;FB46
-tsadihebrew;05E6
-tsecyrillic;0446
-tsere;05B5
-tsere12;05B5
-tsere1e;05B5
-tsere2b;05B5
-tserehebrew;05B5
-tserenarrowhebrew;05B5
-tserequarterhebrew;05B5
-tserewidehebrew;05B5
-tshecyrillic;045B
-tsuperior;F6F3
-ttabengali;099F
-ttadeva;091F
-ttagujarati;0A9F
-ttagurmukhi;0A1F
-tteharabic;0679
-ttehfinalarabic;FB67
-ttehinitialarabic;FB68
-ttehmedialarabic;FB69
-tthabengali;09A0
-tthadeva;0920
-tthagujarati;0AA0
-tthagurmukhi;0A20
-tturned;0287
-tuhiragana;3064
-tukatakana;30C4
-tukatakanahalfwidth;FF82
-tusmallhiragana;3063
-tusmallkatakana;30C3
-tusmallkatakanahalfwidth;FF6F
-twelvecircle;246B
-twelveparen;247F
-twelveperiod;2493
-twelveroman;217B
-twentycircle;2473
-twentyhangzhou;5344
-twentyparen;2487
-twentyperiod;249B
-two;0032
-twoarabic;0662
-twobengali;09E8
-twocircle;2461
-twocircleinversesansserif;278B
-twodeva;0968
-twodotenleader;2025
-twodotleader;2025
-twodotleadervertical;FE30
-twogujarati;0AE8
-twogurmukhi;0A68
-twohackarabic;0662
-twohangzhou;3022
-twoideographicparen;3221
-twoinferior;2082
-twomonospace;FF12
-twonumeratorbengali;09F5
-twooldstyle;F732
-twoparen;2475
-twoperiod;2489
-twopersian;06F2
-tworoman;2171
-twostroke;01BB
-twosuperior;00B2
-twothai;0E52
-twothirds;2154
-u;0075
-uacute;00FA
-ubar;0289
-ubengali;0989
-ubopomofo;3128
-ubreve;016D
-ucaron;01D4
-ucircle;24E4
-ucircumflex;00FB
-ucircumflexbelow;1E77
-ucyrillic;0443
-udattadeva;0951
-udblacute;0171
-udblgrave;0215
-udeva;0909
-udieresis;00FC
-udieresisacute;01D8
-udieresisbelow;1E73
-udieresiscaron;01DA
-udieresiscyrillic;04F1
-udieresisgrave;01DC
-udieresismacron;01D6
-udotbelow;1EE5
-ugrave;00F9
-ugujarati;0A89
-ugurmukhi;0A09
-uhiragana;3046
-uhookabove;1EE7
-uhorn;01B0
-uhornacute;1EE9
-uhorndotbelow;1EF1
-uhorngrave;1EEB
-uhornhookabove;1EED
-uhorntilde;1EEF
-uhungarumlaut;0171
-uhungarumlautcyrillic;04F3
-uinvertedbreve;0217
-ukatakana;30A6
-ukatakanahalfwidth;FF73
-ukcyrillic;0479
-ukorean;315C
-umacron;016B
-umacroncyrillic;04EF
-umacrondieresis;1E7B
-umatragurmukhi;0A41
-umonospace;FF55
-underscore;005F
-underscoredbl;2017
-underscoremonospace;FF3F
-underscorevertical;FE33
-underscorewavy;FE4F
-union;222A
-universal;2200
-uogonek;0173
-uparen;24B0
-upblock;2580
-upperdothebrew;05C4
-upsilon;03C5
-upsilondieresis;03CB
-upsilondieresistonos;03B0
-upsilonlatin;028A
-upsilontonos;03CD
-uptackbelowcmb;031D
-uptackmod;02D4
-uragurmukhi;0A73
-uring;016F
-ushortcyrillic;045E
-usmallhiragana;3045
-usmallkatakana;30A5
-usmallkatakanahalfwidth;FF69
-ustraightcyrillic;04AF
-ustraightstrokecyrillic;04B1
-utilde;0169
-utildeacute;1E79
-utildebelow;1E75
-uubengali;098A
-uudeva;090A
-uugujarati;0A8A
-uugurmukhi;0A0A
-uumatragurmukhi;0A42
-uuvowelsignbengali;09C2
-uuvowelsigndeva;0942
-uuvowelsigngujarati;0AC2
-uvowelsignbengali;09C1
-uvowelsigndeva;0941
-uvowelsigngujarati;0AC1
-v;0076
-vadeva;0935
-vagujarati;0AB5
-vagurmukhi;0A35
-vakatakana;30F7
-vav;05D5
-vavdagesh;FB35
-vavdagesh65;FB35
-vavdageshhebrew;FB35
-vavhebrew;05D5
-vavholam;FB4B
-vavholamhebrew;FB4B
-vavvavhebrew;05F0
-vavyodhebrew;05F1
-vcircle;24E5
-vdotbelow;1E7F
-vecyrillic;0432
-veharabic;06A4
-vehfinalarabic;FB6B
-vehinitialarabic;FB6C
-vehmedialarabic;FB6D
-vekatakana;30F9
-venus;2640
-verticalbar;007C
-verticallineabovecmb;030D
-verticallinebelowcmb;0329
-verticallinelowmod;02CC
-verticallinemod;02C8
-vewarmenian;057E
-vhook;028B
-vikatakana;30F8
-viramabengali;09CD
-viramadeva;094D
-viramagujarati;0ACD
-visargabengali;0983
-visargadeva;0903
-visargagujarati;0A83
-vmonospace;FF56
-voarmenian;0578
-voicediterationhiragana;309E
-voicediterationkatakana;30FE
-voicedmarkkana;309B
-voicedmarkkanahalfwidth;FF9E
-vokatakana;30FA
-vparen;24B1
-vtilde;1E7D
-vturned;028C
-vuhiragana;3094
-vukatakana;30F4
-w;0077
-wacute;1E83
-waekorean;3159
-wahiragana;308F
-wakatakana;30EF
-wakatakanahalfwidth;FF9C
-wakorean;3158
-wasmallhiragana;308E
-wasmallkatakana;30EE
-wattosquare;3357
-wavedash;301C
-wavyunderscorevertical;FE34
-wawarabic;0648
-wawfinalarabic;FEEE
-wawhamzaabovearabic;0624
-wawhamzaabovefinalarabic;FE86
-wbsquare;33DD
-wcircle;24E6
-wcircumflex;0175
-wdieresis;1E85
-wdotaccent;1E87
-wdotbelow;1E89
-wehiragana;3091
-weierstrass;2118
-wekatakana;30F1
-wekorean;315E
-weokorean;315D
-wgrave;1E81
-whitebullet;25E6
-whitecircle;25CB
-whitecircleinverse;25D9
-whitecornerbracketleft;300E
-whitecornerbracketleftvertical;FE43
-whitecornerbracketright;300F
-whitecornerbracketrightvertical;FE44
-whitediamond;25C7
-whitediamondcontainingblacksmalldiamond;25C8
-whitedownpointingsmalltriangle;25BF
-whitedownpointingtriangle;25BD
-whiteleftpointingsmalltriangle;25C3
-whiteleftpointingtriangle;25C1
-whitelenticularbracketleft;3016
-whitelenticularbracketright;3017
-whiterightpointingsmalltriangle;25B9
-whiterightpointingtriangle;25B7
-whitesmallsquare;25AB
-whitesmilingface;263A
-whitesquare;25A1
-whitestar;2606
-whitetelephone;260F
-whitetortoiseshellbracketleft;3018
-whitetortoiseshellbracketright;3019
-whiteuppointingsmalltriangle;25B5
-whiteuppointingtriangle;25B3
-wihiragana;3090
-wikatakana;30F0
-wikorean;315F
-wmonospace;FF57
-wohiragana;3092
-wokatakana;30F2
-wokatakanahalfwidth;FF66
-won;20A9
-wonmonospace;FFE6
-wowaenthai;0E27
-wparen;24B2
-wring;1E98
-wsuperior;02B7
-wturned;028D
-wynn;01BF
-x;0078
-xabovecmb;033D
-xbopomofo;3112
-xcircle;24E7
-xdieresis;1E8D
-xdotaccent;1E8B
-xeharmenian;056D
-xi;03BE
-xmonospace;FF58
-xparen;24B3
-xsuperior;02E3
-y;0079
-yaadosquare;334E
-yabengali;09AF
-yacute;00FD
-yadeva;092F
-yaekorean;3152
-yagujarati;0AAF
-yagurmukhi;0A2F
-yahiragana;3084
-yakatakana;30E4
-yakatakanahalfwidth;FF94
-yakorean;3151
-yamakkanthai;0E4E
-yasmallhiragana;3083
-yasmallkatakana;30E3
-yasmallkatakanahalfwidth;FF6C
-yatcyrillic;0463
-ycircle;24E8
-ycircumflex;0177
-ydieresis;00FF
-ydotaccent;1E8F
-ydotbelow;1EF5
-yeharabic;064A
-yehbarreearabic;06D2
-yehbarreefinalarabic;FBAF
-yehfinalarabic;FEF2
-yehhamzaabovearabic;0626
-yehhamzaabovefinalarabic;FE8A
-yehhamzaaboveinitialarabic;FE8B
-yehhamzaabovemedialarabic;FE8C
-yehinitialarabic;FEF3
-yehmedialarabic;FEF4
-yehmeeminitialarabic;FCDD
-yehmeemisolatedarabic;FC58
-yehnoonfinalarabic;FC94
-yehthreedotsbelowarabic;06D1
-yekorean;3156
-yen;00A5
-yenmonospace;FFE5
-yeokorean;3155
-yeorinhieuhkorean;3186
-yerahbenyomohebrew;05AA
-yerahbenyomolefthebrew;05AA
-yericyrillic;044B
-yerudieresiscyrillic;04F9
-yesieungkorean;3181
-yesieungpansioskorean;3183
-yesieungsioskorean;3182
-yetivhebrew;059A
-ygrave;1EF3
-yhook;01B4
-yhookabove;1EF7
-yiarmenian;0575
-yicyrillic;0457
-yikorean;3162
-yinyang;262F
-yiwnarmenian;0582
-ymonospace;FF59
-yod;05D9
-yoddagesh;FB39
-yoddageshhebrew;FB39
-yodhebrew;05D9
-yodyodhebrew;05F2
-yodyodpatahhebrew;FB1F
-yohiragana;3088
-yoikorean;3189
-yokatakana;30E8
-yokatakanahalfwidth;FF96
-yokorean;315B
-yosmallhiragana;3087
-yosmallkatakana;30E7
-yosmallkatakanahalfwidth;FF6E
-yotgreek;03F3
-yoyaekorean;3188
-yoyakorean;3187
-yoyakthai;0E22
-yoyingthai;0E0D
-yparen;24B4
-ypogegrammeni;037A
-ypogegrammenigreekcmb;0345
-yr;01A6
-yring;1E99
-ysuperior;02B8
-ytilde;1EF9
-yturned;028E
-yuhiragana;3086
-yuikorean;318C
-yukatakana;30E6
-yukatakanahalfwidth;FF95
-yukorean;3160
-yusbigcyrillic;046B
-yusbigiotifiedcyrillic;046D
-yuslittlecyrillic;0467
-yuslittleiotifiedcyrillic;0469
-yusmallhiragana;3085
-yusmallkatakana;30E5
-yusmallkatakanahalfwidth;FF6D
-yuyekorean;318B
-yuyeokorean;318A
-yyabengali;09DF
-yyadeva;095F
-z;007A
-zaarmenian;0566
-zacute;017A
-zadeva;095B
-zagurmukhi;0A5B
-zaharabic;0638
-zahfinalarabic;FEC6
-zahinitialarabic;FEC7
-zahiragana;3056
-zahmedialarabic;FEC8
-zainarabic;0632
-zainfinalarabic;FEB0
-zakatakana;30B6
-zaqefgadolhebrew;0595
-zaqefqatanhebrew;0594
-zarqahebrew;0598
-zayin;05D6
-zayindagesh;FB36
-zayindageshhebrew;FB36
-zayinhebrew;05D6
-zbopomofo;3117
-zcaron;017E
-zcircle;24E9
-zcircumflex;1E91
-zcurl;0291
-zdot;017C
-zdotaccent;017C
-zdotbelow;1E93
-zecyrillic;0437
-zedescendercyrillic;0499
-zedieresiscyrillic;04DF
-zehiragana;305C
-zekatakana;30BC
-zero;0030
-zeroarabic;0660
-zerobengali;09E6
-zerodeva;0966
-zerogujarati;0AE6
-zerogurmukhi;0A66
-zerohackarabic;0660
-zeroinferior;2080
-zeromonospace;FF10
-zerooldstyle;F730
-zeropersian;06F0
-zerosuperior;2070
-zerothai;0E50
-zerowidthjoiner;FEFF
-zerowidthnonjoiner;200C
-zerowidthspace;200B
-zeta;03B6
-zhbopomofo;3113
-zhearmenian;056A
-zhebrevecyrillic;04C2
-zhecyrillic;0436
-zhedescendercyrillic;0497
-zhedieresiscyrillic;04DD
-zihiragana;3058
-zikatakana;30B8
-zinorhebrew;05AE
-zlinebelow;1E95
-zmonospace;FF5A
-zohiragana;305E
-zokatakana;30BE
-zparen;24B5
-zretroflexhook;0290
-zstroke;01B6
-zuhiragana;305A
-zukatakana;30BA
-#--end
-###############################################################################
-# TeX extensions
-Delta;2206;0394
-Ifractur;2111
-# FFsmall, FFIsmall, FFLsmall, FIsmall, FLsmall: invalid Unicode
-FFsmall;D804
-FFIsmall;D807
-FFLsmall;D808
-FIsmall;D805
-FLsmall;D806
-# Germandbls: invalid Unicode, used for secondary replacement from EC.enc
-Germandbls;D800
-# Germandblssmall: invalid Unicode
-Germandblssmall;D803
-Ng;014A
-Omega;2126;03A9
-Rfractur;211C
-# SS: invalid Unicode, used for secondary replacement from EC.enc
-SS;D800
-# SSsmall: invalid Unicode
-SSsmall;D803
-# altselector: invalid Unicode
-altselector;D802
-angbracketleft;27E8;2329
-angbracketright;27E9;232A
-arrowbothv;2195
-arrowdblbothv;21D5
-arrowleftbothalf;21BD
-arrowlefttophalf;21BC
-arrownortheast;2197
-arrownorthwest;2196
-arrowrightbothalf;21C1
-arrowrighttophalf;21C0
-arrowsoutheast;2198
-arrowsouthwest;2199
-# ascendercompwordmark: taller cwm, invalid Unicode
-ascendercompwordmark;D80A
-bardbl;2225
-# capitalcompwordmark: taller cwm, invalid Unicode
-capitalcompwordmark;D809
-ceilingleft;2308
-ceilingright;2309
-circlecopyrt;20DD;25CB
-circledivide;2298
-circledot;2299
-circleminus;2296
-coproduct;2A3F
-# cwm: Unicode for ZWNJ, used for secondary replacement from EC.enc
-cwm;200C
-dblbracketleft;27E6
-dblbracketright;27E7
-diamond;2662;2666
-diamondmath;22C4
-# 0237 is the proposed allocation for dotless j as of Unicode 4.0
-dotlessj;0237;F6BE
-emptyset;2205;F638
-# emptyslot: invalid Unicode; the user explicitly wants this slot empty
-emptyslot;D801
-epsilon1;03F5
-equivasymptotic;224D
-flat;266D
-floorleft;230A
-floorright;230B
-follows;227B
-followsequal;227D
-greatermuch;226B
-heart;2661;2665
-intersectionsq;2293
-latticetop;22A4
-lessmuch;226A
-lscript;2113
-natural;266E
-negationslash;0338
-ng;014B
-owner;220B
-# XXX phi?
-phi;03D5;03C6
-phi1;03C6
-pi1;03D6
-precedesequal;227C
-prime;2032;02B9
-rho1;03F1
-sharp;266F
-similarequal;2243
-slurabove;2322
-slurbelow;2323
-star;22C6
-subsetsqequal;2291
-supersetsqequal;2292
-triangle;25B3
-triangleinv;25BD
-triangleleft;25B9
-triangleright;25C3
-turnstileleft;22A2
-turnstileright;22A3
-unionmulti;228E
-unionsq;2294
-vector;20D7
-# visualspace: Unicode for OPEN BOX, used for secondary replacement from EC.enc
-visualspace;2423
-wreathproduct;2240
-# -- Marco Kuhlmann reported annoying glyph neologisms in fontinst encodings
-# Dbar = Dcroat
-Dbar;0110
-# compwordmark = cwm
-compwordmark;200C
-# dbar = dcroat
-dbar;0111
-# rangedash = endash
-endash;2013
-# hyphenchar = hyphen
-hyphenchar;002D
-# punctdash = emdash
-punctdash;2014
-# visiblespace = visualspace
-visiblespace;2423
-# -- end TeX extensions
diff --git a/Build/source/texk/texlive/linked_scripts/fontools/font2afm b/Build/source/texk/texlive/linked_scripts/fontools/font2afm
deleted file mode 100755
index b0a60420d23..00000000000
--- a/Build/source/texk/texlive/linked_scripts/fontools/font2afm
+++ /dev/null
@@ -1,190 +0,0 @@
-#!/usr/bin/perl
-
-=pod
-
-=head1 NAME
-
-font2afm - create font metrics (in F<afm> format) for (almost) any font file
-
-=head1 SYNOPSIS
-
-font2afm [options] I<font> ...
-
-font2afm [options] @I<filelist>
-
-=head1 DESCRIPTION
-
-B<font2afm> generates font metrics (in Adobe's F<afm> format) for Type1,
-TrueType and OpenType fonts.
-
-B<font2afm> is just a wrapper script around several utilities (B<cfftot1>,
-B<pf2afm>, B<ttf2afm>, B<pfm2kpx> and B<ot2kpx>) that do the real work.
-All these utilities need to be available on your system.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-f>
-
-Force overwriting of existing F<afm> files.
-
-=back
-
-=head1 FILES
-
-=over 4
-
-=item I<font>
-
-This can be any Type1 (in either F<pfa> or F<pfb> format), TrueType or
-OpenType (both PostScript- and TrueType-flavored) font.
-
-=item I<filelist>
-
-This should contain a newline-separated list of font filenames.
-
-=back
-
-=head1 SEE ALSO
-
-F<pf2afm> (part of I<GhostScript>), F<ttf2afm> (part of I<pdfTeX>),
-F<afm2afm>, F<autoinst>, F<cmap2enc>, F<ot2kpx>, F<pfm2kpx>, F<cfftot1>
-(part of Eddie Kohler's I<LCDF TypeTools>).
-
-=head1 AUTHOR
-
-Marc Penninga <marc@penninga.info>
-
-=head1 HISTORY
-
-=over 12
-
-=item I<2005-04-15>
-
-First version
-
-=item I<2005-04-29>
-
-Improved the documentation
-
-=item I<2005-05-23>
-
-Bugfix.
-
-=item I<2005-07-29>
-
-Added support for PostScript-flavored (F<otf>) OpenType fonts.
-
-=item I<2005-08-08>
-
-Bugfix.
-
-=item I<2010-07-19>
-
-Another small bugfix.
-
-=back
-
-=cut
-
-##############################################################################
-
-use Getopt::Std;
-use integer;
-use warnings; no warnings qw(uninitialized);
-
-getopts "f", \%options;
-
-$0 =~ s!.*/!!;
-die "Usage: $0 fontfile ...\n or: $0 \@fontlist\n" if @ARGV < 1;
-
-if ($ARGV[0] =~ m!^@(.+)!) {
- open LIST, "<$1" or die "Error: can't open `$1' - $!\n";
- chop(@ARGV = <LIST>);
- map {m!\S+! and $_ = $&} @ARGV;
-}
-
-for (@ARGV) {
- if (m!(.+)\.(pfb|pfa|ttf|otf)!) {
- ($base, $ext) = ($1, $2);
- }
- else {
- warn "Warning: unrecognised font file `$_' skipped\n";
- next;
- }
-
- next if -e "${base}.afm" and !$options{f};
-
- if ($ext =~ m!pf(?:a|b)!) {
- if (-e "${base}.pfm") {
- system "pfm2kpx '${base}.pfm'";
- }
- else {
- system "pf2afm '$_'";
- }
- if (-e "${base}.otf") {
- system "ot2kpx '${base}.otf' >'${base}.kpx'";
- open AFM, "<${base}.afm" or
- die "Error: can't open `${base}.afm' - $!\n";
- open KPX, "<${base}.kpx" or
- warn("Warning: can't open `${base}.kpx' - $!\n"), next;
- {
- local $/;
- $afm = <AFM>;
- $kpx = <KPX>;
- }
- close AFM;
- open AFM, ">${base}.afm" or
- die "Error: can't create `${base}.afm' - $!\n";
-
- if ($afm =~ m!^(.+?)(?:StartKernData.+EndKernData\n)?
- EndFontMetrics!sx)
- {
- print AFM "$1${kpx}EndFontMetrics\n";
- }
- else {
- warn "Warning: `${base}.afm' seems rotten - please check\n";
- print AFM $afm;
- }
- unlink "${base}.kpx";
- }
- }
- elsif ($ext =~ m!ttf!) {
- system "ttf2afm -o '${base}.afm' '$_'";
- system "ot2kpx '${base}.ttf' >'${base}.kpx'";
- open AFM, "<${base}.afm" or
- die "Error: can't open `${base}.afm' - $!\n";
- open KPX, "<${base}.kpx" or
- warn("Warning: can't open `${base}.kpx' - $!\n"), next;
- {
- local $/;
- $afm = <AFM>;
- $kpx = <KPX>;
- }
- close AFM;
- open AFM, ">${base}.afm" or
- die "Error: can't create `${base}.afm' - $!\n";
-
- if ($afm =~ m!^(.+?)(?:StartKernData.+EndKernData\n)?
- EndFontMetrics!sx)
- {
- print AFM "$1${kpx}EndFontMetrics\n";
- }
- else {
- warn "Warning: `${base}.afm' seems rotten - please check\n";
- print AFM $afm;
- }
- unlink "${base}.kpx";
- }
- elsif ($ext =~ m!otf!) {
- system "cfftot1 -b -o ${base}.pfb $_";
- $_ = $base . ".pfb";
- redo;
- }
- else {
- die "Error: you've just found a bug in `$0' - congratulations!\n";
- }
-}
-
-__END__
diff --git a/Build/source/texk/texlive/linked_scripts/fontools/ot2kpx b/Build/source/texk/texlive/linked_scripts/fontools/ot2kpx
index b1fce6e72e0..60c2a99b418 100755
--- a/Build/source/texk/texlive/linked_scripts/fontools/ot2kpx
+++ b/Build/source/texk/texlive/linked_scripts/fontools/ot2kpx
@@ -1,103 +1,134 @@
-#!/usr/bin/perl
+#! /usr/bin/env perl
-=pod
-
-=head1 NAME
-
-ot2kpx - extract kerning information from an OpenType font
-
-=head1 SYNOPSIS
-
-ot2kpx I<font>
-
-=head1 DESCRIPTION
-
-In many OpenType fonts, most kerning data is stored in the `GPOS' table rather
-than in the `kern' table. B<ot2kpx> extracts the kerning data from both tables
-and prints it (in F<afm> format) to C<stdout>.
+=begin COPYRIGHT
-=head1 RESTRICTIONS
+----------------------------------------------------------------------------
-=over 2
+ Copyright (C) 2005-2012 Marc Penninga.
-=item B<->
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation, either version 2
+ of the License, or (at your option) any later version.
-B<ot2kpx> prints data from all features named `kern', regardless of script
-and language. Maybe it would be better to let the user choose a script
-and language (defaulting to `latn' and `DFLT') and print only the kerning
-data from features associated with these values.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-=item B<->
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to
+ Free Software Foundation, Inc.,
+ 59 Temple Place,
+ Suite 330,
+ Boston, MA 02111-1307,
+ USA
-B<ot2kpx> uses only the XAdvance data associated with the first glyph in any
-kerning pair; all other data in the ValueRecords is ignored. I'm not sure
-whether this is The Right Thing to Do; however, almost always there is
-no other data, so this approach gives correct results (in fact, the only
-font I know of that does contain data other than XAdvance is Linotype
-Palatino; this also contains XAdvDevice data, which is used (according to
-the OpenType specification) to I<`define subtle, device-dependent adjustments
-at specific font sizes or device resolutions'>. Since there is no way to
-express such adjustments in F<afm> format, ignoring them seems to be the
-only option.)
+----------------------------------------------------------------------------
-=back
+=end COPYRIGHT
-=head1 SEE ALSO
+=cut
-F<afm2afm>, F<autoinst>, F<cmap2enc>, F<font2afm>, F<pfm2kpx>.
+use strict;
+use warnings;
-=head1 AUTHOR
+use integer;
+use List::Util @List::Util::EXPORT_OK;
+use Pod::Usage;
-Marc Penninga <marc@penninga.info>
+use v5.10;
-=head1 HISTORY
+our ($NUM_GLYPHS, $UNITS_PER_EM, %KPX);
-=over 12
+sub main {
+ pod2usage(-verbose => 0) if @ARGV != 1;
-=item I<2005-01-10>
+ my %font = OTF::get_tables($ARGV[0]);
-First version
+ $NUM_GLYPHS = unpack '@4n', $font{maxp};
+ $UNITS_PER_EM = unpack '@18n', $font{head};
-=item I<2005-02-18>
+ my @glyph_name = map { sprintf "index%d", $_ } 0 .. $NUM_GLYPHS - 1;
+ if (defined $font{CFF}) {
+ OTF::CFF::get_glyph_names($font{CFF}, \@glyph_name);
+ }
-Rewrote some of the code
+ if (defined $font{kern}) {
+ OTF::Kern::parse_kerntable($font{kern});
+ }
-=item I<2005-03-08>
+ if (defined $font{GPOS}) {
+ my @lookup_list_indices
+ = OTF::GPOS::get_lookup_list_indices($font{GPOS});
+ my @all_lookups = OTF::GPOS::get_lookups($font{GPOS});
+ my @lookups = @all_lookups[@lookup_list_indices];
+ my @subtables = map { OTF::GPOS::get_subtables($_) } @lookups;
+
+ for my $subtable (@subtables) {
+ my $pos_format = unpack 'n', $subtable;
+ given ($pos_format) {
+ when (1) { OTF::GPOS::parse_pos_format_1($subtable) }
+ when (2) { OTF::GPOS::parse_pos_format_2($subtable) }
+ default {
+ warn "[ERROR] invalid PosFormat $pos_format ignored";
+ }
+ }
+ }
+ }
-Input files searched via B<kpsewhich> (where available)
+ my $num_kernpairs = sum map { scalar keys %{$KPX{$_}} } keys %KPX;
+ print "StartKernData\nStartKernPairs $num_kernpairs\n";
+ for my $first (sort { $a <=> $b } keys %KPX) {
+ my $first_glyph = $glyph_name[$first];
+ for my $second (sort { $a <=> $b } keys %{$KPX{$first}}) {
+ print "KPX $first_glyph $glyph_name[$second] ",
+ "$KPX{$first}{$second}\n";
+ }
+ }
+ print "EndKernPairs\nEndKernData\n";
-=item I<2005-03-15>
+ return;
+}
-Input files searched using B<kpsewhich> or B<findtexmf>
-=item I<2005-03-21>
+########################################################################
-Test if GPOS table is present before trying to read it
-=item I<2005-04-29>
+package OTF;
-Improved the documentation
+#-----------------------------------------------------------------------
+# Return a hash with all tables (as strings) from the font
+#-----------------------------------------------------------------------
+sub get_tables {
+ my $filename = shift;
-=item I<2005-05-25>
+ open my $fontfile, '<:raw', $filename
+ or die "[ERROR] can't open $filename: $!";
+ my $fontdata = do { local $/; <$fontfile> };
+ close $fontfile;
-Changed warning that's given when the font contains no GPOS table, to an
-informational message.
+ my ($sfnt_version, @tables) = unpack 'a4nx6/(a16)', $fontdata;
-=item I<2005-07-29>
+ die "[ERROR] $filename: unknown font type"
+ unless $sfnt_version eq "\x00\x01\x00\x00"
+ || $sfnt_version eq 'OTTO';
-A few updates to the documentation
+ my %table = map { my ($tag, $offset, $length) = unpack 'A4@8N@12N', $_;
+ ($tag => substr $fontdata, $offset, $length);
+ }
+ @tables;
-=back
+ return %table;
+}
-=cut
-##############################################################################
+########################################################################
-use integer;
-use warnings; no warnings qw(uninitialized);
-@StandardStrings = qw(
+package OTF::CFF;
+my @STANDARD_STRINGS = qw(
.notdef space exclam quotedbl
numbersign dollar percent ampersand
quoteright parenleft parenright asterisk
@@ -222,437 +253,602 @@ use warnings; no warnings qw(uninitialized);
Regular Roman Semibold
);
-sub getu($) {
- my $arg = shift;
- my $n = length $arg;
- my $r = 0;
-
- for my $i (0 .. $n - 1) {
- $r = ($r << 8) + unpack("C", substr($arg, $i, 1));
- }
-
- return $r;
-}
+#-----------------------------------------------------------------------
+#
+#-----------------------------------------------------------------------
+sub get_glyph_names {
+ my ($CFF, $glyph_name) = @_;
-sub gets16($) {
- my $v = getu $_[0];
- if ($v > 0x7FFF) {
- $v -= 0x10000;
- }
+ # skip header; parse (and ignore) NAME index
+ my ($rest) = _parse_index(substr $CFF, unpack '@2C', $CFF);
- return $v;
-}
+ # parse TopDict index
+ ($rest, my @top_dict) = _parse_index($rest);
+ if (@top_dict > 1) {
+ warn "[WARNING] multiple fonts in single file not supported";
+ }
+ my %top_dict = _parse_dict($top_dict[0]);
+ if ($NUM_GLYPHS != unpack 'n', substr($CFF, $top_dict{17}, 2)) {
+ die "[ERROR] NumGlyphs different in 'maxp' and 'CFF' tables";
+ }
-sub getnum($) {
- my $i;
- my $r = 0;
+ # parse String index
+ ($rest, my @strings) = _parse_index($rest);
+ @strings = (@STANDARD_STRINGS, @strings);
- if (${$_[0]}[0] == 28) {
- shift(@{$_[0]});
- for $i (0, 1) {
- $r = ($r << 8) | shift(@{$_[0]});
+ my $charset = substr $CFF, $top_dict{15};
+ my $format = unpack 'C', $charset;
+ given ($format) {
+ when (0) {
+ my @codes = unpack "\@1n@{[ $NUM_GLYPHS - 1 ]}", $charset;
+ @$glyph_name = @strings[0, @codes];
+ }
+ when (1) {
+ my $i = 0;
+ $glyph_name->[$i++] = $strings[0];
+ for (my $j = 0; $i < $NUM_GLYPHS; $j++) {
+ my ($first, $n_left)
+ = unpack "\@@{[ 1 + 3*$j ]}nC", $charset;
+ $glyph_name->[$i + $_] = $strings[$first + $_]
+ for 0 .. $n_left;
+ $i += 1 + $n_left;
+ }
}
- }
- elsif (${$_[0]}[0] == 29) {
- shift(@{$_[0]});
- for $i (0 .. 3) {
- $r = ($r << 8) | shift(@{$_[0]});
+ when (2) {
+ my $i = 0;
+ $glyph_name->[$i++] = $strings[0];
+ for (my $j = 0; $i < $NUM_GLYPHS; $j++) {
+ my ($first, $n_left)
+ = unpack "\@@{[ 1 + 4*$j ]}nn", $charset;
+ $glyph_name->[$i + $_] = $strings[$first + $_]
+ for 0 .. $n_left;
+ $i += 1 + $n_left;
+ }
+ }
+ default {
+ warn "[ERROR] invalid CharsetFormat '$format' ignored";
}
- }
- elsif (${$_[0]}[0] == 30) {
- shift @{$_[0]};
- $nibbles = "";
- $nibbles .= sprintf("%02x", shift @{$_[0]}) until $nibbles =~ /f/;
- $nibbles =~ tr/abef/.E-/d;
- $nibbles =~ s/c/E-/g;
- $r = eval $nibbles;
- }
- elsif (${$_[0]}[0] >= 251) {
- $r = -256 * (shift(@{$_[0]}) - 251) - shift(@{$_[0]}) - 108;
- }
- elsif (${$_[0]}[0] >= 247) {
- $r = 256 * (shift(@{$_[0]}) - 247) + shift(@{$_[0]}) + 108;
- }
- else {
- $r = shift(@{$_[0]}) - 139;
}
- return $r;
+ return;
}
-sub getidx($) {
- my $n = getu(substr $_[0], 0, 2);
- my $sz = getu(substr $_[0], 2, 1);
- my(@r, @off, @d, $i);
- for $i (0 .. $n) {
- $off[$i] = getu(substr $_[0], 3 + $i * $sz, $sz);
+#-----------------------------------------------------------------------
+# Parse Adobe's INDEX format (see CFF spec); return "rest" plus data array
+#-----------------------------------------------------------------------
+sub _parse_index {
+ my $index = shift;
+
+ my ($count, $off_size) = unpack 'nC', $index;
+ my @offsets = unpack "\@3(a$off_size)@{[ $count + 1 ]}", $index;
+ given ($off_size) {
+ when (1) { $_ = unpack 'C', $_ for @offsets }
+ when (2) { $_ = unpack 'n', $_ for @offsets }
+ when (4) { $_ = unpack 'N', $_ for @offsets }
+ when (3) {
+ for my $offset (@offsets) {
+ my @bytes = map 'C3', $offset;
+ $offset = ($bytes[0] << 16) + ($bytes[1] << 8) + $bytes[2];
+ }
+ }
+ default {
+ warn "[ERROR] invalid OffSize $off_size ignored";
+ }
}
- for $i (0 .. $n - 1) {
- $d[$i] = substr $_[0], 2 + ($n + 1) * $sz + $off[$i],
- $off[$i + 1] - $off[$i];
+ $_ += 2 + $off_size * ($count + 1) for @offsets;
+
+ my @data;
+ for my $i (0 .. $count - 1) {
+ $data[$i]
+ = substr $index, $offsets[$i], $offsets[$i + 1] - $offsets[$i];
}
- return substr($_[0], 2 + ($n + 1) * $sz + $off[$n]), @d;
+ return substr($index, $offsets[$count]), @data;
}
-sub getcov($) {
- my $Coverage = shift;
- my $CoverageFormat = getu(substr $Coverage, 0, 2);
- my @r = ();
- if ($CoverageFormat == 1) {
- my $GlyphCount = getu(substr $Coverage, 2, 2);
- for my $i (0 .. $GlyphCount - 1) {
- push @r, getu(substr $Coverage, 4 + 2 * $i, 2);
- }
- }
- elsif ($CoverageFormat == 2) {
- my $RangeCount = getu(substr $Coverage, 2, 2);
- for my $i (0 .. $RangeCount - 1) {
- my $RangeRecord = substr $Coverage, 4 + 6 * $i, 6;
- my $Start = getu(substr $RangeRecord, 0, 2);
- my $End = getu(substr $RangeRecord, 2, 2);
- for my $j ($Start .. $End) {
- push @r, $j;
- }
- }
- }
- else {
- warn "Warning: unknown CoverageFormat `$CoverageFormat'\n";
+#-----------------------------------------------------------------------
+# Parse Adobe's DICT format (see CFF spec); return data hash
+#-----------------------------------------------------------------------
+sub _parse_dict {
+ my $dict = shift;
+
+ my @bytes = unpack 'C*', $dict;
+ my (@operands, %dict);
+ while (@bytes) {
+ given ($bytes[0]) {
+ when ([0 .. 11, 13 .. 22]) {
+ my $operator = shift @bytes;
+ ($dict{$operator} = join q{ }, @operands) =~ s/^\s+//xms;
+ @operands = ();
+ }
+ when (12) {
+ my $operator = join q{ }, splice @bytes, 0, 2;
+ ($dict{$operator} = join q{ }, @operands) =~ s/^\s+//xms;
+ @operands = ();
+ }
+ when ([28, 29, 30, 32 .. 254]) {
+ push @operands, _get_number(\@bytes);
+ }
+ default {
+ warn "[ERROR] invalid byte $bytes[0] in DICT ignored";
+ shift @bytes;
+ }
+ }
}
- return @r;
+
+ return %dict;
}
-sub getclass($) {
- my @c = (0) * $NumGlyphs;
- my $ClassFormat = getu(substr $_[0], 0, 2);
- my($i, $j);
-
- if ($ClassFormat == 1) {
- my $StartGlyph = getu(substr $_[0], 2, 2);
- my $GlyphCount = getu(substr $_[0], 4, 2);
-
- for $i (0 .. $GlyphCount - 1) {
- $c[$i + $StartGlyph] = getu(substr $_[0], 6 + 2 * $i, 2);
- }
- }
- elsif ($ClassFormat == 2) {
- my $ClassRangeCount = getu(substr $_[0], 2, 2);
-
- for $i (0 .. $ClassRangeCount - 1) {
- my $ClassRangeRecord = substr $_[0], 4 + 6 * $i, 6;
- my $Start = getu(substr $ClassRangeRecord, 0, 2);
- my $End = getu(substr $ClassRangeRecord, 2, 2);
- my $Class = getu(substr $ClassRangeRecord, 4, 2);
-
- for $j ($Start .. $End) {
- $c[$j] = $Class;
- }
- }
- }
- else {
- warn "Warning: unknown ClassFormat `$ClassFormat'\n";
- }
+#-----------------------------------------------------------------------
+# Parse Adobe's variable-length numbers (see CFF spec); shorten arg array
+#-----------------------------------------------------------------------
+sub _get_number {
+ my $bytes = shift;
- return @c;
+ given (my $b0 = shift @$bytes) {
+ when (28) {
+ my ($b1, $b2) = splice @$bytes, 0, 2;
+ return ($b1 << 8) | $b2;
+ }
+ when (29) {
+ my ($b1, $b2, $b3, $b4) = splice @$bytes, 0, 4;
+ return ((((($b1 << 8) + $b2) << 8) + $b3) << 8) + $b4;
+ }
+ when (30) {
+ # Reals not implemented; just dump appropriate number of bytes
+ until (($b0 & 0xf0) == 0xf0 || ($b0 & 0xf) == 0xf) {
+ $b0 = shift @$bytes;
+ }
+ }
+ when ([ 32 .. 246]) {
+ return $b0 - 139;
+ }
+ when ([247 .. 250]) {
+ my $b1 = shift @$bytes;
+ return 256 * ($b0 - 247) + $b1 + 108;
+ }
+ when ([251 .. 254]) {
+ my $b1 = shift @$bytes;
+ return -256 * ($b0 - 251) - $b1 - 108;
+ }
+ }
}
-##############################################################################
-use integer;
-use warnings; no warnings qw(uninitialized);
-
-$0 =~ s!.*/!!;
-die "Usage: $0 fontfile\n" if @ARGV != 1;
-
-if ((chop($fn = `kpsewhich $ARGV[0] 2>&1`) and -e $fn) or
- (chop($fn = `findtexmf $ARGV[0] 2>&1`) and -e $fn))
-{
- open FONT, "<$fn" or die "Error: can't open `$fn' - $!\n";
-}
-else {
- open FONT, "<$ARGV[0]" or
- die "Error: can't open `$ARGV[0]' - $!\n";
-}
-binmode FONT;
-{
- local $/;
- $FONT = <FONT>;
+########################################################################
+
+
+package OTF::GPOS;
+
+#-----------------------------------------------------------------------
+# Return list of all Lookups from the GPOS table
+#-----------------------------------------------------------------------
+sub get_lookups {
+ my $GPOS = shift;
+
+ my $lookup_list = substr $GPOS, unpack '@8n', $GPOS;
+ my @lookup_offsets = unpack 'n/n', $lookup_list;
+
+ return map { substr $lookup_list, $_ } @lookup_offsets;
}
-$NumTables = getu(substr $FONT, 4, 2);
-for ($i = 0; $i < $NumTables; $i++) {
-$Record = substr $FONT, 12 + 16 * $i, 16;
- ($Name = substr $Record, 0, 4) =~ s/\s//g;
- $Offset = getu(substr $Record, 8, 4);
- $Length = getu(substr $Record, 12, 4);
- $Table{$Name} = substr $FONT, $Offset, $Length;
+#-----------------------------------------------------------------------
+# Return list of all LookupListIndices pointed to by 'kern' feature
+#-----------------------------------------------------------------------
+sub get_lookup_list_indices {
+ my $GPOS = shift;
+
+ my $feature_list = substr $GPOS, unpack '@6n', $GPOS;
+ my %lookup_list_index;
+ for my $feature_record (unpack 'n/(a6)', $feature_list) {
+ my ($tag, $offset) = unpack 'a4n', $feature_record;
+ next if $tag ne 'kern';
+
+ my $feature = substr $feature_list, $offset;
+ my @lookup_list_indices = unpack '@2n/n', $feature;
+ $lookup_list_index{$_} = 1 for @lookup_list_indices;
+ }
+
+ return keys %lookup_list_index;
}
-$UnitsPerEM = getu(substr $Table{head}, 18, 2);
-$NumGlyphs = getu(substr $Table{maxp}, 4, 2);
-
-if (exists $Table{GPOS}) {
- $FeatureList = substr $Table{GPOS}, getu(substr $Table{GPOS}, 6, 2);
- $FeatureCount = getu(substr $FeatureList, 0, 2);
- for $i (0 .. $FeatureCount - 1) {
- $FeatureTag = substr $FeatureList, 2 + 6 * $i, 4;
- $Feature = getu(substr $FeatureList, 6 + 6 * $i, 2);
- $LookupCount = getu(substr $FeatureList, $Feature + 2, 2);
- for $j (0 .. $LookupCount - 1) {
- push @{$LookupListIndex{$FeatureTag}},
- getu(substr $FeatureList, $Feature + 4 + 2 * $j, 2);
- }
+#-----------------------------------------------------------------------
+# Return list of all subtables in Lookup table
+#-----------------------------------------------------------------------
+sub get_subtables {
+ my $lookup = shift;
+
+ my ($lookup_type, @subtable_offsets) = unpack 'n@4n/n', $lookup;
+ if ($lookup_type != 2) {
+ warn "[WARNING] LookupType $lookup_type not implemented";
+ return;
}
- $LookupList = substr $Table{GPOS}, getu(substr $Table{GPOS}, 8, 2);
- $LookupCount = getu(substr $LookupList, 0, 2);
- for $i (0 .. $LookupCount - 1) {
- $Lookup[$i] = substr $LookupList,
- getu(substr $LookupList, 2 + 2 * $i, 2);
+
+ return map { substr $lookup, $_ } @subtable_offsets;
+}
+
+#-----------------------------------------------------------------------
+# Parse subtable in PairPosFormat 1, store kern pairs in global %KPX
+#-----------------------------------------------------------------------
+sub parse_pos_format_1 {
+ my $subtable = shift;
+
+ my ($coverage_offset, $value_format_1, $value_format_2, @pair_set_offsets)
+ = unpack '@2nnnn/n', $subtable;
+
+ my @coverage = _get_coverage(substr $subtable, $coverage_offset);
+ my @pair_sets = map { substr $subtable, $_ } @pair_set_offsets;
+ if (@coverage != @pair_sets) {
+ warn "[ERROR] Coverage table doesn't match PairSet table";
+ return;
}
- for $j (@{$LookupListIndex{kern}}) {
- $LookupTable = $Lookup[$j];
- $LookupType = getu(substr $LookupTable, 0, 2);
- $SubTableCount = getu(substr $LookupTable, 4, 2);
- if ($LookupType != 2) {
- warn "Warning: wrong LookupType `$LookupType', table skipped\n";
- next;
- }
- for $k (0 .. $SubTableCount - 1) {
- $SubTable = substr $LookupTable,
- getu(substr $LookupTable, 6 + 2 * $k, 2);
- $PosFormat = getu(substr $SubTable, 0, 2);
- if ($PosFormat == 1) {
- $Coverage = substr $SubTable, getu(substr $SubTable, 2, 2);
- @Coverage = getcov($Coverage);
- $ValueFormat1 = getu(substr $SubTable, 4, 2);
- $ValueFormat2 = getu(substr $SubTable, 6, 2);
-
- if (!($ValueFormat1 & 0x04) || $ValueFormat2 != 0) {
- warn "Warning: ValueFormat `($ValueFormat1, " .
- "$ValueFormat2)' not implemented\n";
- next;
- }
- $PairValueRecordSize = 4;
- $ValueOffset = 2;
- if ($ValueFormat1 & 0x01) {
- $PairValueRecordSize += 2;
- $ValueOffset += 2;
- }
- if ($ValueFormat1 & 0x02) {
- $PairValueRecordSize += 2;
- $ValueOffset += 2;
- }
- if ($ValueFormat1 & 0x08) {$PairValueRecordSize += 2}
- if ($ValueFormat1 & 0x10) {$PairValueRecordSize += 2}
- if ($ValueFormat1 & 0x20) {$PairValueRecordSize += 2}
- if ($ValueFormat1 & 0x40) {$PairValueRecordSize += 2}
- if ($ValueFormat1 & 0x80) {$PairValueRecordSize += 2}
-
- $GlyphCount = @Coverage;
- $PairSetCount = getu(substr $SubTable, 8, 2);
- if ($GlyphCount != $PairSetCount) {
- warn "ERROR: GlyphCount not equal to PairSetCount\n";
- next;
- }
- for $l (0 .. $#Coverage) {
- $left = $Coverage[$l];
- $PairSet = substr $SubTable,
- getu(substr $SubTable, 10 + 2 * $l, 2);
- $PairValueCount = getu(substr $PairSet, 0, 2);
-
- for $r (0 .. $PairValueCount - 1) {
- $PairValueRecord = substr $PairSet,
- 2 + $r * $PairValueRecordSize,
- $PairValueRecordSize;
- $right = getu(substr $PairValueRecord, 0, 2);
- $Value = getu(substr $PairValueRecord, $ValueOffset, 2);
- $KPX{$left}{$right} ||= $Value * 1000 / $UnitsPerEM;
- }
- }
- }
- elsif ($PosFormat == 2) {
- $Coverage = substr $SubTable, getu(substr $SubTable, 2, 2);
- @Coverage = getcov($Coverage);
-
- $ValueFormat1 = getu(substr $SubTable, 4, 2);
- $ValueFormat2 = getu(substr $SubTable, 6, 2);
-
- if (!($ValueFormat1 & 0x04) || $ValueFormat2 != 0) {
- warn "Warning: ValueFormat `($ValueFormat1, " .
- "$ValueFormat2)' not implemented\n";
- next;
- }
- $Class2RecordSize = 2;
- $ValueOffset = 0;
- if ($ValueFormat1 & 0x01) {
- $Class2RecordSize += 2;
- $ValueOffset += 2;
- }
- if ($ValueFormat1 & 0x02) {
- $Class2RecordSize += 2;
- $ValueOffset += 2;
- }
- if ($ValueFormat1 & 0x08) {$Class2RecordSize += 2}
- if ($ValueFormat1 & 0x10) {$Class2RecordSize += 2}
- if ($ValueFormat1 & 0x20) {$Class2RecordSize += 2}
- if ($ValueFormat1 & 0x40) {$Class2RecordSize += 2}
- if ($ValueFormat1 & 0x80) {$Class2RecordSize += 2}
-
- $ClassDef1 = getu(substr $SubTable, 8, 2);
- $ClassDef2 = getu(substr $SubTable, 10, 2);
- $Class1Count = getu(substr $SubTable, 12, 2);
- $Class2Count = getu(substr $SubTable, 14, 2);
- @Class1 = getclass(substr $SubTable, $ClassDef1);
- @Class2 = getclass(substr $SubTable, $ClassDef2);
-
- for $l (0 .. $Class1Count - 1) {
- $Class1RecordSize = $Class2Count * $Class2RecordSize;
- $Class1Record = substr $SubTable,
- 16 + $Class1RecordSize * $l,
- $Class1RecordSize;
-
- for $m (0 .. $Class2Count - 1) {
- $ValueRecord = substr $Class1Record,
- $Class2RecordSize * $m, $Class2RecordSize;
- $Value[$l][$m] =
- gets16(substr $ValueRecord, $ValueOffset, 2);
- }
- }
-
- for $m (@Coverage) {
- for $n (0 .. $NumGlyphs - 1) {
- if ($Value = $Value[$Class1[$m]][$Class2[$n]]) {
- $KPX{$m}{$n} ||= $Value * 1000 / $UnitsPerEM;
- }
- }
- }
- }
- else {
- warn "Warning: unknown PosFormat `$PosFormat'\n";
- next;
- }
- }
+
+ my ($record_size, $value_offset)
+ = _parse_value_formats($value_format_1, $value_format_2, 2, 2);
+
+ while (1) {
+ my $pair_set = shift @pair_sets or last;
+ my $first = shift @coverage;
+
+ my @pair_value_records = unpack "n/(a$record_size)", $pair_set;
+
+ for my $pair_value_record (@pair_value_records) {
+ my ($second, $value)
+ = unpack "n\@${value_offset}s>", $pair_value_record;
+ next if $value == 0;
+ $KPX{$first}{$second} ||= 1000 * $value / $UNITS_PER_EM;
+ }
}
-}
-
-
-if (exists $Table{kern}) {
- $nTables = getu(substr $Table{kern}, 2, 2);
- $startSubTable = 4;
- for $i (0 .. $nTables - 1) {
- $length = getu(substr $Table{kern}, $startSubTable + 2, 2);
- $coverage = getu(substr $Table{kern}, $startSubTable + 4, 2);
- if ($coverage != 0x01) {
- warn "Warning: format of `kern' table not supported\n";
- $startSubTable += $length;
- next;
- }
- $nPairs = getu(substr $Table{kern}, $startSubTable + 6, 2);
- for $j (0 .. $nPairs - 1) {
- $kernRecord = substr $Table{kern}, $startSubTable + 14 + 6 * $j, 6;
- $left = getu(substr $kernRecord, 0, 2);
- $right = getu(substr $kernRecord, 2, 2);
- $value = gets16(substr $kernRecord, 4, 2);
- $KPX{$left}{$right} ||= $value * 1000 / $UnitsPerEM;
- }
- $startSubTable += $length;
+
+ return;
+}
+
+#-----------------------------------------------------------------------
+# Parse subtable in PairPosFormat 2, store kern pairs in global %KPX
+#-----------------------------------------------------------------------
+sub parse_pos_format_2 {
+ my $subtable = shift;
+
+ my ($coverage_offset, $value_format_1, $value_format_2,
+ $class_def_1, $class_def_2, $class_1_count, $class_2_count)
+ = unpack '@2nnnnnnn', $subtable;
+
+ my @coverage = _get_coverage(substr $subtable, $coverage_offset);
+
+ my ($class_2_record_size, $value_offset)
+ = _parse_value_formats($value_format_1, $value_format_2, 0, 0);
+
+ my @class_1 = _get_class(substr $subtable, $class_def_1);
+ my @class_2 = _get_class(substr $subtable, $class_def_2);
+
+ my $class_1_record_size = $class_2_count * $class_2_record_size;
+ my @class_1_records
+ = unpack "\@16(a$class_1_record_size)$class_1_count", $subtable;
+
+ for my $class_1 (0 .. $class_1_count - 1) {
+ my $class_1_record = $class_1_records[$class_1];
+ my @class_2_records
+ = unpack "(a$class_2_record_size)$class_2_count", $class_1_record;
+
+ for my $class_2 (0 .. $class_2_count - 1) {
+ my $class_2_record = $class_2_records[$class_2];
+ my $value = unpack "\@${value_offset}s>", $class_2_record;
+ next if $value == 0;
+ $value = 1000 * $value / $UNITS_PER_EM;
+
+ my @first = grep { $class_1[$_] == $class_1 } @coverage;
+ my @second = grep { $class_2[$_] == $class_2 } 0 .. $#class_2;
+
+ for my $first (@first) {
+ for my $second (@second) {
+ $KPX{$first}{$second} ||= $value;
+ }
+ }
+ }
}
+
+ return;
}
+#-----------------------------------------------------------------------
+# Get class number for all glyphs
+#-----------------------------------------------------------------------
+sub _get_class {
+ my $class = shift;
-if (exists $Table{CFF}) {
- $HdrSize = getu(substr $Table{CFF}, 2, 1);
- ($CFF, undef) = getidx substr($Table{CFF}, $HdrSize);
- ($CFF, @TopDict) = getidx $CFF;
- @TopDict = map ord, split(//, $TopDict[0]);
- while (@TopDict) {
- if ($TopDict[0] > 21) {
- push @Operands, getnum(\@TopDict);
- }
- elsif ($TopDict[0] == 12) {
- $Operator = shift(@TopDict) . " " . shift(@TopDict);
- ($TopDict{$Operator} = join " ", @Operands) =~ s/^\s*//;
- @Operands = undef;
- }
- else {
- $Operator = shift(@TopDict);
- ($TopDict{$Operator} = join " ", @Operands) =~ s/^\s*//;
- @Operands = undef;
- }
+ my @class = (0) x $NUM_GLYPHS;
+
+ my $class_format = unpack 'n', $class;
+ given ($class_format) {
+ when (1) {
+ my ($start_glyph, @class_value) = unpack '@2nn/n', $class;
+ @class[$start_glyph .. $start_glyph + $#class_value]
+ = @class_value;
+ }
+ when (2) {
+ my @class_ranges = unpack '@2n/(a6)', $class;
+ for my $class_range (@class_ranges) {
+ my ($start, $end, $class) = unpack 'nnn', $class_range;
+ @class[$start .. $end] = ($class) x ($end - $start + 1);
+ }
+ }
+ default {
+ warn "[ERROR] invalid ClassFormat '$class_format' ignored";
+ return;
+ }
}
- ($CFF, @Strings) = getidx $CFF;
- unshift @Strings, @StandardStrings;
- if ($NumGlyphs != getu(substr $Table{CFF}, $TopDict{17}, 2)) {
- die "Error: NumGlyphs in `maxp' different from `CFF'\n";
+
+ return @class;
+}
+
+
+#-----------------------------------------------------------------------
+# Determine size of ValueRecord and offset of XAdvance value in it
+#-----------------------------------------------------------------------
+sub _parse_value_formats {
+ my ($value_format_1, $value_format_2, $record_size, $value_offset) = @_;
+
+ unless ($value_format_1 & 0x4 && $value_format_2 == 0) {
+ warn "[WARNING] ValueFormat ($value_format_1, ",
+ "$value_format_2) not implemented";
+ return;
}
- if ($TopDict{15} == 0) {
- for $i (0 .. 228) {$glyphName[$i] = $Strings[$i]}
- }
- elsif ($TopDict{15} == 1) {
- warn "Warning: predefined CharSet `Expert' not implemented\n";
- }
- elsif ($TopDict{15} == 2) {
- warn "Warning: predefined CharSet `ExpertSubset' not implemented\n";
- }
- else {
- $Charset = substr $Table{CFF}, $TopDict{15};
- $Format = getu(substr $Charset, 0, 1);
- if ($Format == 0) {
- $glyphName[0] = $Strings[0];
- for $j (1 .. $NumGlyphs - 1) {
- $glyphName[$j] = $Strings[getu(substr $Charset, 1 + 2 * $j,2)];
- }
- }
- elsif ($Format == 1) {
- $i = 0;
- $glyphName[$i++] = $Strings[0];
- for ($j = 0; $i < $NumGlyphs; $j++) {
- $first = getu(substr $Charset, 1 + 3 * $j, 2);
- $nLeft = getu(substr $Charset, 3 + 3 * $j, 1);
- for $k (0 .. $nLeft) {
- $glyphName[$i++] = $Strings[$first + $k];
- }
- }
- }
- elsif ($Format == 2) {
- $i = 0;
- $glyphName[$i++] = $Strings[0];
- for ($j = 0; $i < $NumGlyphs; $j++) {
- $first = getu(substr $Charset, 1 + 4 * $j, 2);
- $nLeft = getu(substr $Charset, 3 + 4 * $j, 2);
- for $k (0 .. $nLeft) {
- $glyphName[$i++] = $Strings[$first + $k];
- }
- }
- }
- else {die "Error: unknown CharsetFormat `$Format'\n"}
+
+ for my $bit ((0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80)) {
+ $record_size += 2 if $value_format_1 & $bit;
}
-}
-else {
- for $i (0 .. 0xFF) {
- $glyphName[$i] = sprintf "index0x%02X", $i;
+ for my $bit ((0x1, 0x2)) {
+ $value_offset += 2 if $value_format_1 & $bit;
}
- for $i (0x100 .. $NumGlyphs - 1) {
- $glyphName[$i] = sprintf "index0x%04X", $i;
+
+ return ($record_size, $value_offset);
+}
+
+#-----------------------------------------------------------------------
+# Return a list of GlyphIDs in a Coverage table
+#-----------------------------------------------------------------------
+sub _get_coverage {
+ my $coverage = shift;
+
+ my $coverage_format = unpack 'n', $coverage;
+ given ($coverage_format) {
+ when (1) {
+ return unpack '@2n/n', $coverage;
+ }
+ when (2) {
+ my @range_records = unpack '@2n/(a6)', $coverage;
+
+ return map { my ($start, $end) = unpack 'nn', $_;
+ $start .. $end;
+ }
+ @range_records;
+ }
+ default {
+ warn "[WARNING] unknown CoverageFormat $coverage_format ignored";
+ }
}
}
-for $i (0 .. $NumGlyphs - 1) {
- for $j (0 .. $NumGlyphs - 1) {
- if ($Value = $KPX{$i}{$j}) {
- push @KPX, sprintf("KPX %s %s %d\n",
- $glyphName[$i], $glyphName[$j],
- $Value > 0x7FFF ? $Value - 0x10000 : $Value);
- }
+
+########################################################################
+
+
+package OTF::Kern;
+
+#-----------------------------------------------------------------------
+# Parse "kern"table, store kern pairs in global %KPX
+#-----------------------------------------------------------------------
+sub parse_kerntable {
+ my $kern = shift;
+
+ my $num_tables = unpack '@2n', $kern;
+ my $start_subtable = 4;
+ for my $i (0 .. $num_tables - 1) {
+ my $subtable = substr $kern, $start_subtable;
+ my ($length, $coverage) = unpack '@2nn', $subtable;
+ $start_subtable += $length;
+
+ if ($coverage != 0x1) {
+ warn "[WARNING] kern table format '$coverage' not implemented";
+ next;
+ }
+
+ my @kern_pairs = unpack '@6nx6/(a6)', $subtable;
+ for my $kern_pair (@kern_pairs) {
+ my ($first, $second, $value) = unpack 'nns>', $kern_pair;
+ next if $value == 0;
+
+ $KPX{$first}{$second} ||= 1000 * $value / $UNITS_PER_EM;
+ }
}
+
+ return;
}
-$KPX = @KPX;
-print <<EOF;
-StartKernData
-StartKernPairs $KPX
- @{KPX}EndKernPairs
-EndKernData
-EOF
+
+########################################################################
+
+
+package main;
+
+main();
__END__
+
+
+########################################################################
+
+
+ To create the documentation:
+
+ pod2man --center="Marc Penninga" --release="fontools" --section=1 \
+ ot2kpx - | groff -Tps -man - | ps2pdf - ot2kpx.pdf
+
+=pod
+
+=head1 NAME
+
+ot2kpx - extract kerning information from OpenType fonts
+
+
+=head1 SYNOPSIS
+
+=over 8
+
+=item B<ot2kpx>
+
+B<fontfile>
+
+=back
+
+
+=head1 DESCRIPTION
+
+B<ot2kpx> extract the kerning data from OpenType fonts (both F<otf>
+and F<ttf> formats) and prints it (in F<afm> format) to C<stdout>.
+
+
+=head1 OPTIONS AND ARGUMENTS
+
+=over 4
+
+=item B<fontfile>
+
+The OpenType font (in either F<otf> or F<ttf> format).
+
+=back
+
+
+=head1 RESTRICTIONS
+
+=over 4
+
+=item B<->
+
+B<ot2kpx> doesn't implement all of the OpenType specification.
+Things that are missing include: support for font files containing
+multiple fonts, LookupTables with LookupTypes other than 2,
+"kern" tables with format other than 0 and ValueRecords with
+other types of data than just XAdvance data.
+
+Most of these limitations don't really matter, since the missing features
+are rare (the only fonts I know of that use them are the non-western fonts
+that come with Adobe Reader). Furthermore, some of these features concern
+(according to the OpenType specification) I<"define subtle, device-dependent
+adjustments at specific font sizes or device resolutions">.
+Since there's no way to express such adjustments in F<afm> format,
+ignoring them seems to be the only option anyway.
+
+=item B<->
+
+B<ot2kpx> collects kerning data first from the "kern" table, then from
+all LookupTables associated with the "kern" feature; if a kerning pair
+occurs multiple times, the first value seen is chosen.
+There are (or may be) several issues with this approach:
+
+=over 4
+
+=item -
+
+The OpenType specification says that fonts in F<otf> format shouldn't
+use the "kern" table at all, just the lookups from the "GPOS" table.
+Many such fonts do, however, contain a "kern" table, but no "GPOS" table;
+so we use the "kern" table anyway.
+
+=item -
+
+Instead of reading all LookupTables, it might be better to let the user
+specify a script and language and process only the LookupTables for
+those values.
+However, at least in the fonts I checked, all script/language combinations
+eventually point to the I<same> "kern" LookupTables, so this approach
+wouldn't make any difference (apart from further complicating the code).
+
+=back
+
+=back
+
+
+=head1 AUTHOR
+
+Marc Penninga <marcpenninga@gmail.com>
+
+
+=head1 COPYRIGHT
+
+Copyright (C) 2005-2012 Marc Penninga.
+
+
+=head1 LICENSE
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published
+by the Free Software Foundation, either version 2 of the License,
+or (at your option) any later version.
+A copy of the GNU General Public License is included with B<autoinst>;
+see the file F<GPLv2.txt>.
+
+
+=head1 DISCLAIMER
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+See the GNU General Public License for more details.
+
+
+=head1 RECENT CHANGES
+
+(See the source code for the rest of the story.)
+
+=over 12
+
+=item I<2012-02-01>
+
+Refactored the code, and fixed a number of bugs in the process.
+Updated the documentation.
+
+=back
+
+
+=begin Really_old_history
+
+=over 12
+
+=item I<2005-01-10>
+
+First version
+
+=item I<2005-02-18>
+
+Rewrote some of the code
+
+=item I<2005-03-08>
+
+Input files searched via B<kpsewhich> (where available)
+
+=item I<2005-03-15>
+
+Input files searched using B<kpsewhich> or B<findtexmf>
+
+=item I<2005-03-21>
+
+Test if GPOS table is present before trying to read it
+
+=item I<2005-04-29>
+
+Improved the documentation
+
+=item I<2005-05-25>
+
+Changed warning that's given when the font contains no GPOS table, to an
+informational message.
+
+=item I<2005-07-29>
+
+A few updates to the documentation
+
+=back
+
+=cut
+
diff --git a/Build/source/texk/texlive/linked_scripts/fontools/pfm2kpx b/Build/source/texk/texlive/linked_scripts/fontools/pfm2kpx
deleted file mode 100755
index a2202bcd680..00000000000
--- a/Build/source/texk/texlive/linked_scripts/fontools/pfm2kpx
+++ /dev/null
@@ -1,299 +0,0 @@
-#!/usr/bin/perl
-
-=pod
-
-=head1 NAME
-
-pfm2kpx - extract correct kerning information from F<pfm>
-(Printer Font Metrics) files
-
-=head1 SYNOPSIS
-
-pfm2kpx [options] I<pfm>
-
-=head1 DESCRIPTION
-
-Many PostScript Type1 fonts contain only
-F<pfb> and F<pfm> files, but no F<afm> (Adobe Font Metrics) files. These can be
-generated with I<pf2afm> (which comes with I<GhostScript>), but
-this might not yield all kerning pairs from the F<pfm> file. The reason
-for this is that I<pf2afm> interprets C<dfCharSet = 0x00> to mean that
-the Adobe StandardEncoding has been used, whereas many fonts (or font
-creation tools) instead use the Windows ANSI (aka codepage 1252) encoding.
-(You know you've hit this problem when B<pf2afm> complains "C<.notdef
-character ocurred among kern pairs -- you'd better check the resulting
-AFM file>".) In this case, the resulting F<afm> is incomplete and contains
-wrong kerning pairs.
-
-B<pfm2kpx> extracts the correct kerning pairs from such F<pfm> files and
-repairs the F<afm> (if necessary creating it first by running I<pf2afm>).
-If for some reason it can't update the F<afm>, it prints the kerning pairs to
-C<stdout> instead.
-
-When I<pf2afm> doesn't complain about the kerning pairs, B<pfm2kpx>
-thinks the resulting F<afm> file is fine and quits; this can be
-changed by specifying the B<-f> option (see below).
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<-f>
-
-Force updating of the F<afm> file, even if I<pf2afm> doesn't complain.
-
-=back
-
-=head1 SEE ALSO
-
-F<pf2afm> (part of GhostScript), F<afm2afm>, F<autoinst>, F<cmap2enc>,
-F<font2afm>, F<ot2kpx>.
-
-=head1 AUTHOR
-
-Marc Penninga <marc@penninga.info>
-
-=head1 HISTORY
-
-=over 12
-
-=item I<2005-02-17>
-
-First version
-
-=item I<2005-02-18>
-
-Added C<binmode PFM> to make B<pfm2kpx> work on Windows platforms
-
-=item I<2005-03-08>
-
-Input files searched via B<kpsewhich> (where available)
-
-=item I<2005-03-14>
-
-Rewrote some of the code to make it more robust, added the B<-f> option
-
-=item I<2005-03-15>
-
-Input files searched using B<kpsewhich> or B<findtexmf>
-
-=item I<2005-04-29>
-
-Improved the documentation
-
-=item I<2005-05-24>
-
-Bugfix.
-
-=item I<2005-07-29>
-
-Some updates to the documentation.
-
-=back
-
-=cut
-
-##############################################################################
-
-@winansi = qw(
-
- .notdef .notdef .notdef .notdef
- .notdef .notdef .notdef .notdef
- .notdef .notdef .notdef .notdef
- .notdef .notdef .notdef .notdef
-
- .notdef .notdef .notdef .notdef
- .notdef .notdef .notdef .notdef
- .notdef .notdef .notdef .notdef
- .notdef .notdef .notdef .notdef
-
- space exclam quotedbl numbersign
- dollar percent ampersand quotesingle
- parenleft parenright asterisk plus
- comma hyphen period slash
-
- zero one two three
- four five six seven
- eight nine colon semicolon
- less equal greater question
-
- at A B C
- D E F G
- H I J K
- L M N O
-
- P Q R S
- T U V W
- X Y Z bracketleft
- backslash bracketright asciicircum underscore
-
- grave a b c
- d e f g
- h i j k
- l m n o
-
- p q r s
- t u v w
- x y z braceleft
- bar braceright asciitilde .notdef
-
- Euro .notdef quotesinglbase florin
- quotedblbase ellipsis dagger daggerdbl
- circumflex perthousand Scaron guilsinglleft
- OE .notdef Zcaron .notdef
-
- .notdef quoteleft quoteright quotedblleft
- quotedblright bullet endash emdash
- tilde trademark scaron guilsignlright
- oe .notdef zcaron Ydieresis
-
- .notdef exclamdown cent sterling
- currency yen brokenbar section
- dieresis copyright ordfeminine guillemotleft
- logicalnot .notdef registered macron
-
- degree plusminus twosuperior threesuperior
- acute mu paragraph periodcentered
- cedilla onesuperior ordmasculine guillemotright
- onequarter onehalf threequarters questiondown
-
- Agrave Aacute Acircumflex Atilde
- Adieresis Aring AE Ccedilla
- Egrave Eacute Ecircumflex Edieresis
- Igrave Iacute Icircumflex Idieresis
-
- Eth Ntilde Ograve Oacute
- Ocircumflex Otilde Odieresis multiply
- Oslash Ugrave Uacute Ucircumflex
- Udieresis Yacute Thorn germandbls
-
- agrave aacute acircumflex atilde
- adieresis aring ae ccedilla
- egrave eacute ecircumflex edieresis
- igrave iacute icircumflex idieresis
-
- eth ntilde ograve oacute
- ocircumflex otilde odieresis divide
- oslash ugrave uacute ucircumflex
- udieresis yacute thorn ydieresis
-);
-
-sub getword($) {
- my @bytes = reverse(split(//, substr($_[0], 0, 2)));
- my $r = 0;
-
- for (@bytes) {
- $r = ($r << 8) + unpack "C", $_;
- }
-
- return $r >= 32768 ? $r - 65536 : $r;
-}
-
-sub getdword($) {
- my @bytes = reverse(split(//, substr($_[0], 0, 4)));
- my $r = 0;
-
- for (@bytes) {
- $r = ($r << 8) + unpack "C", $_;
- }
-
- return $r;
-}
-
-##############################################################################
-
-use Getopt::Std;
-use integer;
-use warnings; no warnings qw(uninitialized);
-
-getopts "f", \%options;
-
-$0 =~ s!.*/!!;
-die "Usage: $0 pfmfile\n" if @ARGV != 1;
-
-($base = $ARGV[0]) =~ s!.*/|\.pfm!!g;
-unless (-e "${base}.afm") {
- $errmsg = `pf2afm '${base}.pfb'`;
- if ($errmsg !~ /\.notdef character ocurred among kern pairs/ and
- not exists $options{f})
- {
- warn "Warning: output from <pf2afm> seems OK; skipping `$ARGV[0]'.\n",
- " If you disagree, rerun $0 with the `-f' option\n";
- exit 0;
- }
-}
-
-if ((chop($fn = `kpsewhich '$ARGV[0]' 2>&1`) and -e $fn) or
- (chop($fn = `findtexmf '$ARGV[0]' 2>&1`) and -e $fn))
-{
- open PFM, "<$fn" or die "Error: can't open `$fn' - $!\n";
-}
-else {
- open PFM, "<$ARGV[0]" or
- die "Error: can't open `$ARGV[0]' - $!\n";
-}
-binmode PFM;
-{
- local $/;
- $pfm = <PFM>;
-}
-
-$dfCharSet = unpack "C", substr($pfm, 85, 1);
-if ($dfCharSet != 0) {
- die "Error: `dfCharSet' is $dfCharSet, not 0\n";
-}
-
-$dfPairKernTable = getdword(substr $pfm, 131, 4);
-$etmKernPairs = getword(substr $pfm, 195, 2);
-if ($dfPairKernTable == 0 or $etmKernPairs == 0) {
- warn "Warning: no kerning pairs found in `$ARGV[0]'\n";
- exit;
-}
-$pairkern = substr $pfm, $dfPairKernTable;
-$n = getword(substr $pairkern, 0, 2);
-if ($n != $etmKernPairs) {
- warn "Warning: incorrect number of kerning pairs in `$ARGV[0]';\n",
- " please check the resulting AFM file!\n";
-}
-for $i (0 .. $n - 1) {
- $pair = substr $pairkern, 2 + 4 * $i, 4;
- $left = unpack "C", substr($pair, 0, 1);
- $right = unpack "C", substr($pair, 1, 1);
- $kern = getword(substr($pair, 2, 2));
-
- push @KPX, "KPX $winansi[$left] $winansi[$right] $kern\n";
-}
-
-if (open AFM, "<${base}.afm") {
- {
- local $/;
- $afm = <AFM>;
- }
- $afm =~ s/StartKernData.*//s;
- $afm =~ s/\r\n*/\n/gs;
- $time = localtime;
- $afm =~ s/(?<=Comment ).*?$/Converted at $time by $0 from $ARGV[0]/m;
- if (open AFM, ">${base}.afm") {select AFM}
- else {
- warn "Warning: can't create `${base}.afm' - $!\n" .
- " printing to <STDOUT> instead\n";
- }
- print <<EOF;
-${afm}
-StartKernData
-StartKernPairs $n
- @{KPX}EndKernPairs
-EndKernData
-
-EndFontMetrics
-EOF
-}
-else {
- warn "Warning: file `${base}.afm' not found, " .
- "printing only kerning pairs\n";
- print "StartKernData\nStartKernPairs $n\n";
- map print, @KPX;
- print "EndKernPairs\nEndKernData\n";
-}
-
-__END__
diff --git a/Build/source/texk/texlive/linked_scripts/fontools/showglyphs b/Build/source/texk/texlive/linked_scripts/fontools/showglyphs
deleted file mode 100755
index 1622ebe432f..00000000000
--- a/Build/source/texk/texlive/linked_scripts/fontools/showglyphs
+++ /dev/null
@@ -1,184 +0,0 @@
-#!/usr/bin/perl
-
-=pod
-
-=head1 NAME
-
-showglyphs - create a F<pdf> file that shows all glyphs in a font
-
-=head1 SYNOPSIS
-
-showglyphs I<fontfile>
-
-=head1 DESCRIPTION
-
-This program creates a F<pdf> file that shows all glyphs in a given font.
-
-=head1 FILES
-
-=over 4
-
-=item I<font>
-
-This can be any Type 1 or TrueType font; OpenType fonts are not (yet?)
-supported.
-
-=back
-
-=head1 RESTRICTIONS
-
-=over 4
-
-=item B<->
-
-B<showglyphs> only works on Unix/Linux systems.
-
-=item B<->
-
-B<showglyphs> needs a working, TDS-compliant Tex installation
-
-=back
-
-=head1 SEE ALSO
-
-F<afm2afm>, F<autoinst>, F<cmap2enc>, F<pfm2kpx>, F<enc2etx>,
-F<etx2enc>, F<ot2kpx>.
-
-=head1 AUTHOR
-
-Marc Penninga <marc@penninga.info>
-
-=head1 HISTORY
-
-=over 12
-
-=item I<2005-04-28>
-
-First version
-
-=item I<2005-04-29>
-
-A few bugfixes; B<showglyphs> now works with glyphnames containing underscores
-
-=item I<2005-05-24>
-
-Another bugfix
-
-=item I<2005-07-29>
-
-A few updates to the documentation
-
-=back
-
-=cut
-
-use integer;
-use warnings; no warnings qw(uninitialized);
-
-$0 =~ s!.*/!!g;
-die "Usage: $0 fontfile\n" if @ARGV != 1;
-
-system "mkdir -p ./showglyphs/";
-system "cp $ARGV[0] ./showglyphs/";
-chdir "./showglyphs";
-
-system "font2afm $ARGV[0]";
-$ARGV[0] =~ /([\w-]+)\./ and $fontname = $1;
-
-open AFM, "<${fontname}.afm" or
- die "Error: can't open `${fontname}.afm' - $!\n";
-{
- local $/;
- $_ = <AFM>;
-}
-
-(/StartCharMetrics (\d+)/m and $num_glyphs = $1) or $num_glyphs = 255;
-@vec = (".notdef") x (($num_glyphs / 256 + 1) * 256);
-
-for (/(WX.*?$)/gm) {/N\s+([\w.]+)/ and $vec[$i++] = $1}
-
-system "cp `locate pdftex.map` .";
-open TEX, ">tmp.tex" or die "Error: can't create `tmp.tex' - $!\n";
-print TEX <<EOF;
-\\documentclass[a4paper]{article}
-\\setlength\\parindent{0pt}
-\\setlength\\parskip{0pt}
-\\raggedbottom\\frenchspacing
-
-\\newlength\\tempdima
-\\makeatletter
-\\setlength\\textheight{\\paperheight}
-\\addtolength\\textheight{-2in}
-\\setlength\\textwidth{\\paperwidth}
-\\addtolength\\textwidth{-2in}
-
-\\setlength\\oddsidemargin{0pt}
-\\setlength\\evensidemargin{0pt}
-
-\\setlength\\topmargin{0pt}
-\\addtolength\\topmargin{-\\headheight}
-\\addtolength\\topmargin{-\\headsep}
-\\makeatother
-
-\\newcommand*{\\printglyph}[2]{%
- \\frame{%
- \\settodepth{\\tempdima}{#1}%
- \\makebox[2em][l]{%
- \\rule[-18pt]{0pt}{48pt}%
- \\makebox[0pt][l]{%
- \\raisebox{-14pt}{\\makebox[2em][c]{\\tiny#2}}}%
- \\raisebox{-\\tempdima}{%
- \\makebox[2em][c]{\\linethickness{0pt}\\frame{#1}}}}}}
-
-\\begin{document}
-EOF
-
-for ($i = 0; $i < $num_glyphs / 256 + 1; $i++) {
- $filename = sprintf "%s%03d", $fontname, $i + 1;
-
- open ENC, ">$filename.enc" or
- die "Error: can't create `$filename.enc' - $!\n";
-
- print ENC "%\n% Created ", scalar localtime,
- " by $0 from `${fontname}.afm'\n";
- print ENC "%\n/", $filename, " [\n";
-
- for ($j = 0; $j < 256; $j += 16) {
- printf ENC "%% 0x%04x\n", $j;
- for ($k = 0; $k < 16; $k += 4) {
- print ENC "\t";
- for ($l = 0; $l < 4; $l++) {
- print ENC "/$vec[$i * 256 + $j + $k + $l] ";
- }
- print ENC "\n";
- }
- }
-
- print ENC "] def\n";
- close ENC;
-
- system "afm2afm -e '${filename}.enc' -o '${filename}.afm' " .
- "'${fontname}.afm' >>./pdftex.map";
- system "afm2tfm '${fontname}.afm' -T '${filename}.enc' '${filename}.tfm'"
- . ">/dev/null";
-
- for (@vec[256 * $i..256*($i+1)]) {s/(?<!\\)_/\\_/g}
- print TEX "\\font\\test=${filename} at 24pt\\test\n";
- for $j (0 .. 31) {
- for $k (0 .. 7) {
- print TEX "\\printglyph{\\char", 8 * $j + $k,
- "}{$vec[$i * 256 + 8 * $j + $k]} ";
- }
- print TEX "\\par\n";
- last if 256 * $i + 8 * ($j + 1) >= $num_glyphs;
- }
-}
-print TEX "\n\\end{document}\n";
-close TEX;
-
-system "pdflatex tmp >/dev/null";
-chdir "../";
-system "mv showglyphs/tmp.pdf './${fontname}.pdf'";
-system "/bin/rm -r ./showglyphs/";
-
-__END__