diff options
Diffstat (limited to 'Master/texmf-dist/scripts')
-rwxr-xr-x | Master/texmf-dist/scripts/fontools/afm2afm | 216 | ||||
-rwxr-xr-x | Master/texmf-dist/scripts/fontools/autoinst | 1714 | ||||
-rwxr-xr-x | Master/texmf-dist/scripts/fontools/cmap2enc | 5307 | ||||
-rwxr-xr-x | Master/texmf-dist/scripts/fontools/font2afm | 185 | ||||
-rwxr-xr-x | Master/texmf-dist/scripts/fontools/ot2kpx | 658 | ||||
-rwxr-xr-x | Master/texmf-dist/scripts/fontools/pfm2kpx | 299 | ||||
-rwxr-xr-x | Master/texmf-dist/scripts/fontools/showglyphs | 184 |
7 files changed, 8563 insertions, 0 deletions
diff --git a/Master/texmf-dist/scripts/fontools/afm2afm b/Master/texmf-dist/scripts/fontools/afm2afm new file mode 100755 index 00000000000..80ca105ed90 --- /dev/null +++ b/Master/texmf-dist/scripts/fontools/afm2afm @@ -0,0 +1,216 @@ +#!/usr/bin/perl + +use Getopt::Std; +use integer; +use warnings; no warnings qw(uninitialized); + +getopts "e:o:", \%options; + +$0 =~ s!.*/!!; +die "Usage: $0 -e encoding [-o output] afmfile\n" if + @ARGV != 1 or !$options{e}; + +if ($options{o} and -e $options{o}) { + die "$0: output file exists\n"; +} + +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"; +} +{ + local $/; + $_ = <AFM>; +} + +$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"; +} +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"; + } + 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"; + } +} + +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 qq($o $FontName <$f.$x <[$e "$n ReEncodeFont"\n); + + if (open OUT, ">$options{o}") { + select OUT; + } + else { + warn "Warning: can't create `$options{o}' - $!\n", + " printing to <STDOUT> instead\n"; + } +} + +$WX = @WX; +$KPX = @KPX; +print <<EOF; +$FontInfo +StartCharMetrics $WX + @{WX}EndCharMetrics + +StartKernData +StartKernPairs $KPX + @{KPX}EndKernPairs +EndKernData +EndFontMetrics +EOF + +__END__ + +=pod + +=head1 NAME + +afm2afm - reencode an F<afm> file + +=head1 SYNOPSIS + +afm2afm B<-e> I<encoding> [B<-o> I<output>] I<afmfile> + +=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). + +Glyphs that are absent from the chosen encoding aren't written to the output, +which yields much smaller output files. + +The program also generates an entry for a F<dvips>-style map file. + +=head1 OPTIONS + +Option names were chosen to match those of F<ttf2afm>. + +=over 4 + +=item B<-e> I<encoding> + +Reencode using the encoding given in file I<encoding>. + +=item B<-o> I<output> + +Write the reencoded F<afm> to file I<output> instead of C<stdout>. +The mapfile entry will still be written to C<stdout>. + +=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. + +=head1 SEE ALSO + +F<autoinst>, F<cmap2enc>, F<font2afm>, F<ot2kpx>, F<pfm2kpx>. + +=head1 AUTHOR + +Marc Penninga <marc@penninga.info> + +=head1 HISTORY + +=over 12 + +=item I<2005-01-10> + +First version + +=item I<2005-01-25> + +Added printing of mapfile entry + +=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> (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, +pfb is assumed. + +=item I<2005-04-20> + +Program quits if the specified output file exists + +=item I<2005-04-29> + +Improved the documentation + +=item I<2005-07-29> + +Some updates to the documentation + +=item I<2006-01-12> + +A few minor changes to the code + +=back + +=cut + diff --git a/Master/texmf-dist/scripts/fontools/autoinst b/Master/texmf-dist/scripts/fontools/autoinst new file mode 100755 index 00000000000..7939246d91c --- /dev/null +++ b/Master/texmf-dist/scripts/fontools/autoinst @@ -0,0 +1,1714 @@ +#!/usr/bin/perl + +=begin COPYRIGHT ------------------------------------------------------------- + + Copyright (c) 2005-2009 Marc Penninga. + + 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. + + 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 strict; +use warnings; + +use Getopt::Long; + + +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 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 + whether these exist (apart from Computer Modern, of course). + +=end + +=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', +); + +my %FD_WIDTH = ( + ultracondensed => 'uc', + extracondensed => 'ec', + condensed => 'c', + semicondensed => 'sc', + regular => '', + semiextended => 'sx', + extended => 'x', +); + +my %FD_SHAPE = ( + roman => 'n', + italic => 'it', + oblique => 'it', + slanted => 'it', + romani => 'n', + romanii => 'it', # Map one of Silentium Pro's two roman shapes to 'it' +); + +=begin Comment --------------------------------------------------------------- + + The following tables are used for 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). + + + Each key in the %FIGURE_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 + of these features. + nice A list of optional OpenType features; + these are used if the font supports them, but don't + prevent this style from being built when missing. + 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: + code An anonymous hash with two possible keys: + 'n' -> the NFSS code to use for this variant shape + 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) + 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 + 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, + to make it unique. + +=end + +=cut + +my %FIGURE_STYLE = ( + TLF => { + reqd => [], + nice => ['lnum', 'tnum'], + extra => '', + shapes => ['normal', 'smallcaps', 'swash', 'titling', 'textcomp'], + }, + LF => { + reqd => ['pnum'], + nice => ['lnum'], + extra => '', + shapes => ['normal', 'smallcaps', 'swash', 'titling', 'textcomp'], + }, + TOsF => { + reqd => ['onum'], + nice => ['tnum'], + extra => '', + shapes => ['normal', 'smallcaps', 'swash', 'textcomp'], + }, + OsF => { + reqd => ['onum','pnum'], + nice => [], + extra => '', + shapes => ['normal', 'smallcaps', 'swash', 'textcomp'], + }, + Sup => { + reqd => ['sups'], + nice => [], + extra => '--ligkern="* {KL} *"', + shapes => ['normal'], + }, + Inf => { + reqd => ['sinf'], + nice => [], + extra => '--ligkern="* {KL} *"', + shapes => ['normal'], + }, + Numr => { + reqd => ['numr'], + nice => [], + extra => '--ligkern="* {KL} *"', + shapes => ['normal'], + }, + Dnom => { + reqd => ['dnom'], + nice => [], + extra => '--ligkern="* {KL} *"', + shapes => ['normal'], + }, + Orn => { + reqd => ['ornm'], + nice => [], + extra => '--ligkern="* {KL} *"', + shapes => ['normal'], + }, +); + +my %SHAPE = ( + normal => { + code => {n => 'n', it => 'it'}, + reqd => [], + nice => ['kern', 'liga'], + extra => '', + name => '', + }, + smallcaps => { + code => {n => 'sc', it => 'scit'}, + reqd => ['smcp'], + nice => ['kern', 'liga'], + extra => '--unicoding="germandbls =: SSsmall"', + name => 'sc', + }, + swash => { + code => {n => 'nw', it => 'sw'}, + reqd => ['swsh', 'dlig'], + nice => ['kern', 'liga'], + extra => '--include-alternates="*.swash" -faalt', + name => 'swash', + }, + titling => { + code => {n => 'tl', it => 'tlit'}, + reqd => ['titl', 'case', 'cpsp'], + nice => ['kern', 'liga'], + extra => '', + name => 'titling', + }, + textcomp => { + code => {n => 'n', it => 'it'}, + reqd => [], + nice => ['onum'], + extra => '', + name => '', + }, +); + + +# 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]; + + +# ----------------------- subroutine definitions ----------------------- + + +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; + } + + 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}}; + } + + 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), + $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}, + ; + } + } + } + } + } + + # 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}; + + write_style_file($fd_line[0], @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]); + } + + 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"; + } + printf {$FD} "\\DeclareFontShape{%s}{%s-%s}{%s}{%s}{\n", + @fd_line[1, 0, 2, 3, 4]; + } + + # Write fontshape entry + printf {$FD} " %s \\%s\@\@scale %s\n", + sprintf("%5s-%-5s", '<' . $fd_line[5], $fd_line[6] . '>'), + $fd_line[0], + $fd_line[7], + ; + + @fd_prev = @fd_line; + } + + end_fd_file($FD) if $fd_prev[0]; + + # Remove the --no-updmap option from the last command for each family + map { $_->[-1] =~ s/--no-updmap//xms } values %commands; + + # Print or execute the generated commands + if ($ARGV{manual}) { + while (my ($fam, $cmds_ref) = each %commands) { + open my $BAT, '>', "$fam.bat" + or die "ERROR: can't create '$fam.bat' - $!"; + map { print {$BAT} "$_\n" } @{$cmds_ref}; + close $BAT; + } + } + else { + 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 + } + } + } +} + +# ------------------------------------------------------------------------ + +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}, + ) + or die "$USAGE"; + + die "$USAGE" unless @ARGV; + + if (!$ARGV{smallcaps}) { delete $SHAPE{smallcaps} } + 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)} } + + $ARGV{encoding} =~ s/\s+//xmsg; + my @textencodings = grep { $_ ne 'TS1' } + 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 + )) { + delete $SHAPE{textcomp}; + } + + if ($ARGV{verbose}) { + print <<"END_ARGUMENTS"; + +$cmdline + + +I'm using the following options: + + encoding(s): @{[ join ', ', @{$ARGV{encoding}} ]} + NFSS: $ARGV{nfss} @{[ $ARGV{nfss} eq 'rm' ? '(serif)' + : $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' ]} + + extra: @{[ $ARGV{extra} || 'empty' ]} + + auto/manual: @{[ $ARGV{manual} ? 'manual' : 'automatic' ]} + verbosity: @{[ $ARGV{verbose} ? 'verbose' : 'silent' ]} + +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; + } + + $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; + } + } + + 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; + } + } + 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; + } + } + + # 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); + } + } + 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; + } + } + 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; + } + print "\n"; + } + + return %fontinfo; +} + + +=begin Comment --------------------------------------------------------------- + + 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. + +=end + +=cut + +sub make_ornament_encoding { + my (%fontinfo) = @_; + + my $fontfile = $fontinfo{filename}; + my $enc_name = $fontinfo{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"; + 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 } + @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; + } + + return $enc_name; +} + +# ------------------------------------------------------------------------ + +sub write_style_file { + my ($family, @fd_data) = @_; + + my (%seen_enc, %seen_style, %seen_series); + + LINE: + for my $line_ref (@fd_data) { + my ($fam, $enc, $style, $series) = @{$line_ref}[0 .. 3]; + next LINE if $fam ne $family; + $seen_enc{$enc} = 1; + $seen_style{$style} = 1; + $seen_series{$series} = 1; + } + + open my $STYLE, '>', "$family.sty" + or die "ERROR: can't create '$family.sty' - $!"; + print {$STYLE} <<"END_STY_HEADER"; +%%Generayed by autoinst on $date +%% +\\NeedsTeXFormat{LaTeX2e} +\\ProvidesPackage{$family} + [$date (autoinst) Style file for $family.] + +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'; +\IfFileExists{fontaxes.sty}{ + \RequirePackage{fontaxes} + \providecommand{\tldefault}{tl} + \DeclareRobustCommand\tlshape{\not@math@alphabet\tlshape\relax + \fontsecondaryshape\tldefault\selectfont} + \DeclareTextFontCommand{\texttl}{\tlshape} + \let\texttitling\texttl + \fa@naming@exception{shape}{{n}{tl}}{tl} + \fa@naming@exception{shape}{{it}{tl}}{tlit} + + \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} + + \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 + + \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 + + \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}} + + \fa@naming@exception{figures}{{numerators}{proportional}}{Numr} + \fa@naming@exception{figures}{{numerators}{tabular}}{Numr} + + \fa@naming@exception{figures}{{denominators}{proportional}}{Dnom} + \fa@naming@exception{figures}{{denominators}{tabular}}{Dnom} +}{} + +END_STY_FONTAXES + + print {$STYLE} <<"END_STY_XKEYVAL"; +\\IfFileExists{xkeyval.sty}{ + \\newcommand*{\\$family\@scale}{1} + \\RequirePackage{xkeyval} + \\DeclareOptionX{scaled}{\\renewcommand*{\\$family\@scale}{##1}} +}{ + \\let\\DeclareOptionX\\DeclareOption + \\let\\ExecuteOptionsX\\ExecuteOptions + \\let\\ProcessOptionsX\\ProcessOptions +} + +END_STY_XKEYVAL + + if ($seen_style{LF} or $seen_style{TLF}) { + print {$STYLE} + "\\DeclareOptionX{lining}{\\edef\\$family\@figurestyle{LF}}\n"; + } + if ($seen_style{OsF} or $seen_style{TOsF}) { + print {$STYLE} + "\\DeclareOptionX{oldstyle}{\\edef\\$family\@figurestyle{OsF}}\n"; + } + if ($seen_style{TLF} or $seen_style{TOsF}) { + print {$STYLE} + "\\DeclareOptionX{tabular}{\\edef\\$family\@figurealign{T}}\n"; + } + if ($seen_style{LF} or $seen_style{OsF}) { + print {$STYLE} + "\\DeclareOptionX{proportional}{\\edef\\$family\@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"; + + my $default_bold; + for my $series ( + qw(ultrablack ultrabold heavy extrablack black + extrabold demibold semibold bold)) { + if ($seen_series{$FD_WEIGHT{$series}}) { + printf {$STYLE} + "\\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} + "\\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"; +\\ExecuteOptionsX{$defaults} +\\ProcessOptionsX\\relax + +\\renewcommand* + {\\$ARGV{nfss}default} + {$family-\\$family\@figurealign\\$family\@figurestyle} +\\renewcommand*{\\familydefault}{\\$ARGV{nfss}default} + +\\endinput +END_STYLE_REST + + close $STYLE; +} + +# ------------------------------------------------------------------------ + +sub start_fd_file { + my ($fam, $enc, $fig) = @_; + + 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 +%% +\\ProvidesFile{$enc$fam-$fig.fd} + [$date (autoinst) Font definitions for $enc/$fam-$fig.] + +\\expandafter\\ifx\\csname $fam\@scale\\endcsname\\relax + \\let\\$fam\@\@scale\\\@empty +\\else + \\edef\\$fam\@\@scale{s*[\\csname $fam\@scale\\endcsname]}% +\\fi + +\\DeclareFontFamily{$enc}{$fam-$fig}{} + +END_FD_HEADER + + return $FD; +} + +# ------------------------------------------------------------------------ + +sub end_fd_file { + my ($FD) = @_; + + print {$FD} "}{}\n\n\\endinput\n"; + close $FD; +} + + +main() + + +__END__ + + + pod2man --center="fontools" --date=`date +"%Y-%m-%d"` \ + --release="fontools" --section=1 autoinst autoinst.1 + + man -t ./autoinst.1 | ps2pdf - autoinst.pdf + + +=pod + +=head1 NAME + +autoinst - wrapper script around the F<LCDF TypeTools>, +for installing OpenType fonts in LaTeX. + + +=head1 SYNOPSIS + +autoinst [options] I<fontfile> [I<fontfile> ...] + + +=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. All the user then needs +to do is move these files to a suitable location +(C<< $LOCALTEXMF/tex/latex/<Supplier>/<FontFamily>/ >> being the +canonical choice) and update TeX's filename database. + +Given a family of font files (in either F<.ttf> or F<.otf> format), +B<autoinst> will create several LaTeX font families: + +=over 2 + +=over 2 + +=item B<-> + +Four text families (with lining and oldstyle figures, in tabular and +proportional variants), each with the following shapes: + +=over 2 + +=over 4 + +=item I<n> + +Roman text + +=item I<sc> + +Small caps + +=item I<nw> + +`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. + +=item I<it> + +Italic or oblique text + +=item I<scit> + +Italic small caps + +=item I<sw> + +Swash + +=item I<tlit> + +Italic titling + +=back + +=back + +=item B<-> + +For each text family: a family of TS1-encoded symbol fonts, +in roman and italic shapes. + +=item B<-> + +Four families with superiors, inferiors, numerators and denominators, +in roman and italic shapes. + +=item B<-> + +An ornament family, in roman and italic shapes. + +=back + +=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). + +The generated font families are named I<< <FontFamily>-<Suffix> >>, +where I<< <Suffix> >> is one of + +=over 8 + +=item I<LF> + +proportional (i.e., figures have varying widths) lining figures + +=item I<TLF> + +tabular (i.e., all figures have the same width) lining figures + +=item I<OsF> + +proportional oldstyle figures + +=item I<TOsF> + +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) + +=item I<Inf> + +inferior characters; usually only figures and punctuation, +normal forms for the other characters + +=item I<Orn> + +ornaments + +=item I<Numr> + +numerators + +=item I<Dnom> + +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>. + + +=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. + +A different encoding can be selected using the B< --encoding> +command line option (see below). + + +=head2 Using the fonts with LaTeX + +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 +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. + +This style file defines a number of options: + +=over 4 + +=item I<lining, oldstyle, tabular, proportional> + +Choose which figures 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 +(i.e., the value of C<\bfdefault>). + +=item I<light, medium, regular> + +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> >>. +For example: to increase the size of the font by 5%, use the command +C<\usepackage[scaled=1.05]{MyriadPro}>. + +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<base-v2.zip> +(F<http://www.ctan.org/tex-archive/fonts/minionpro/base-v2.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 end of the current group) of its own: + + + DECLARATION COMMAND SHORT FORM OF COMMAND + + \tlshape \texttitling \texttl + \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, +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, +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>). + +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, or even plain TeX's C<\font> primitive +(and it's called `primitive' for a reason!) + + +=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. + + +=head2 NFSS codes + +In NFSS, weight and width are concatenated into a single `series' attribute. +(I<Note:> versions of B<autoinst> before 2007-07-27 erroneously formed +the series as `width plus weight' instead of the reverse.) +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] + + +=over 4 + +=item [1] + +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. + +=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. + +=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; this usually means editing some +configuration file. + +Furthermore, 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 TeXLive +(F<http://tug.org/ftp/texlive/Contents/live/bin/win32/>) don't have this +problem. + + +=head1 COMMAND-LINE OPTIONS + +=over 4 + +=item B< --encoding>=I<encoding[,encoding]> + +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 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> + +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> + +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< --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. + +=item B< --smallcaps> + +=item B< --nosmallcaps> + +Turn the creation of small caps fonts on or off. The default is +B< --smallcaps>. + +=item B< --swash> + +=item B< --noswash> + +Turn the creation of swash fonts on or off. The default is B< --swash>. + +=item B< --titling> + +=item B< --notitling> + +Turn the creation of titling fonts on or off. The default is B< --notitling>. + +=item B< --superiors> + +=item B< --nosuperiors> + +Turn the creation of fonts with superior characters on or off. +The default is B< --superiors>. + +=item B< --inferiors> + +=item B< --noinferiors> + +Turn the creation of fonts with inferior figures on or off. +The default is B< --noinferiors>. + +=item B< --fractions> + +=item B< --nofractions> + +Turn the creation of fonts with numerators and denominators on or off. +The default is B< --nofractions>. + +=item B< --ornaments> + +=item B< --noornaments> + +Turn the creation of ornament fonts on or off. The default is B< --ornaments>. + +=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 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. + +=item B< --verbose> + +Verbose mode; print detailed info about what B<autoinst> thinks it's doing. + +=item B< --extra>=I<text> + +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. + +=back + + +=head1 SEE ALSO + +Eddie Kohler's TypeTools (F<http://www.lcdf.org/type>). + +Perl is usually pre-installed on Linux and Unix systems; +for Windows, good (and free) Perl implementations are +Strawberry Perl (F<http://strawberryperl.com>) and +ActivePerl (available from F<http://www.activestate.com>); + +John Owens' F<otfinst> (F<http://www.ece.ucdavis.edu/~jowens/code/otfinst/>; +also available from CTAN) is another wrapper around F<otftotfm>, +and may work for you when B<autoinst> doesn't. + +Ready-made support files for MinionPro, providing more options and features +than B<autoinst> ever will (including math), are available from +F<http://developer.berlios.de/projects/minionpro/>. + +XeTeX (F<http://scripts.sil.org/xetex>) is a TeX extension that can use +any font installed in the operating system (including both flavours of +OpenType fonts) without additional support files. +It also isn't hindered by standard TeX's limitation to 8-bit fonts, +so it is especially well suited to fonts with many ligatures and +alternate glyphs, such as Bickham, Poetica and Zapfino. + + +=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 + + autoinst I<(... all options and files ...)> >autoinst.log 2>&1 + + +=head1 COPYRIGHT + +Copyright (c) 2005-2009 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 RECENT CHANGES + +(See the source code for the full story.) + +=over 12 + +=item I<2009-04-09> + +Prefixed the filenames of the included encoding files with +`fontools_', to prevent name clashes with other packages. + +=item I<2009-04-06> + +A small patch to the make_ornament_encoding subroutine; +it now also recognises the I<bullet.xxx> ornament glyphs +in Adobe's Kepler Pro. + + +=begin Really_old_history + + +=item I<2007-08-07> + +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'. +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). +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. + +=item I<2007-06-10> + +Bugfix: silently replacing \DeclareOption, \ProcessOptions and +\ExecuteOptions with their counterparts from the xkeyval package +caused problems for some other packages. + +=item I<2007-06-04> + +Added the F< --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>) +to the generated style file. +Extended the output of the F< --verbose> option. + +=item I<2007-02-08> + +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. +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. +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 +(to make the previous change possible); +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>); +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 +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 +and some non-Adobe fonts; +added the B< --sanserif> and B< --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; +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. + +=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. +Added F<nfssext.sty>-like commands to the generated style file. +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 +for OT1, T1, LY1 and user-specific encodings; extended the output generated by +the B< --verbose> option; and rewrote and extended the documentation. + +=item I<2005-06-16> + +Did some more finetuning to the filename-parsing code. + +=item I<2005-05-31> + +Generate correct fontname for OT1-encoded fonts. + +=item I<2005-05-18> + +Tried to make the filename-parsing code a bit more robust by adding several +weights and widths; changed the error that's displayed when filename parsing +fails; commented the code. + +=item I<2005-04-29> + +Rewrote large parts of the code (yes it I<was> even worse). + +=item I<2005-04-18> + +Changed default text-encoding to T1, added TS1. + +=item I<2005-03-29> + +Added support for font families with multiple widths. + +=item I<2005-03-15> + +First version. + +=back + +=end Really_old_history diff --git a/Master/texmf-dist/scripts/fontools/cmap2enc b/Master/texmf-dist/scripts/fontools/cmap2enc new file mode 100755 index 00000000000..4ba6842e179 --- /dev/null +++ b/Master/texmf-dist/scripts/fontools/cmap2enc @@ -0,0 +1,5307 @@ +#!/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/Master/texmf-dist/scripts/fontools/font2afm b/Master/texmf-dist/scripts/fontools/font2afm new file mode 100755 index 00000000000..fe52e33c9ac --- /dev/null +++ b/Master/texmf-dist/scripts/fontools/font2afm @@ -0,0 +1,185 @@ +#!/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. + +=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 $_"; + redo; + } + else { + die "Error: you've just found a bug in `$0' - congratulations!\n"; + } +} + +__END__ diff --git a/Master/texmf-dist/scripts/fontools/ot2kpx b/Master/texmf-dist/scripts/fontools/ot2kpx new file mode 100755 index 00000000000..b1fce6e72e0 --- /dev/null +++ b/Master/texmf-dist/scripts/fontools/ot2kpx @@ -0,0 +1,658 @@ +#!/usr/bin/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>. + +=head1 RESTRICTIONS + +=over 2 + +=item B<-> + +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. + +=item B<-> + +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 + +=head1 SEE ALSO + +F<afm2afm>, F<autoinst>, F<cmap2enc>, F<font2afm>, F<pfm2kpx>. + +=head1 AUTHOR + +Marc Penninga <marc@penninga.info> + +=head1 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 + +############################################################################## + +use integer; +use warnings; no warnings qw(uninitialized); + +@StandardStrings = qw( + + .notdef space exclam quotedbl + numbersign dollar percent ampersand + quoteright 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 quoteleft 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 + + exclamdown cent sterling fraction + yen florin section currency + quotesingle quotedblleft guillemotleft guilsinglleft + guilsinglright fi fl endash + + dagger daggerdbl periodcentered paragraph + bullet quotesinglbase quotedblbase quotedblright + guillemotright ellipsis perthousand questiondown + grave acute circumflex tilde + + macron breve dotaccent dieresis + ring cedilla hungarumlaut ogonek + caron emdash AE ordfeminine + Lslash Oslash OE ordmasculine + + ae dotlessi lslash oslash + oe germandbls onesuperior logicalnot + mu trademark Eth onehalf + plusminus Thorn onequarter divide + + brokenbar degree thorn threequarters + twosuperior registered minus eth + multiply threesuperior copyright Aacute + Acircumflex Adieresis Agrave Aring + + Atilde Ccedilla Eacute Ecircumflex + Edieresis Egrave Iacute Icircumflex + Idieresis Igrave Ntilde Oacute + Ocircumflex Odieresis Ograve Otilde + + Scaron Uacute Ucircumflex Udieresis + Ugrave Yacute Ydieresis Zcaron + aacute acircumflex adieresis agrave + aring atilde ccedilla eacute + + ecircumflex edieresis egrave iacute + icircumflex idieresis igrave ntilde + oacute ocircumflex odieresis ograve + otilde scaron uacute ucircumflex + + udieresis ugrave yacute ydieresis + zcaron exclamsmall Hungarumlautsmall dollaroldstyle + dollarsuperior ampersandsmall Acutesmall parenleftsuperior + parenrightsuperior twodotenleader onedotenleader zerooldstyle + + oneoldstyle twooldstyle threeoldstyle fouroldstyle + fiveoldstyle sixoldstyle sevenoldstyle eightoldstyle + nineoldstyle commasuperior threequartersemdash periodsuperior + questionsmall asuperior bsuperior centsuperior + + dsuperior esuperior isuperior lsuperior + msuperior nsuperior osuperior rsuperior + ssuperior tsuperior ff ffi + ffl parenleftinferior parenrightinferior Circumflexsmall + + hyphensuperior Gravesmall Asmall Bsmall + Csmall Dsmall Esmall Fsmall + Gsmall Hsmall Ismall Jsmall + Ksmall Lsmall Msmall Nsmall + + Osmall Psmall Qsmall Rsmall + Ssmall Tsmall Usmall Vsmall + Wsmall Xsmall Ysmall Zsmall + colonmonetary onefitted rupiah Tildesmall + + exclamdownsmall centoldstyle Lslashsmall Scaronsmall + Zcaronsmall Dieresissmall Brevesmall Caronsmall + Dotaccentsmall Macronsmall figuredash hypheninferior + Ogoneksmall Ringsmall Cedillasmall questiondownsmall + + oneeighth threeeighths fiveeighths seveneighths + onethird twothirds zerosuperior foursuperior + fivesuperior sixsuperior sevensuperior eightsuperior + ninesuperior zeroinferior oneinferior twoinferior + + threeinferior fourinferior fiveinferior sixinferior + seveninferior eightinferior nineinferior centinferior + dollarinferior periodinferior commainferior Agravesmall + Aacutesmall Acircumflexsmall Atildesmall Adieresissmall + + Aringsmall AEsmall Ccedillasmall Egravesmall + Eacutesmall Ecircumflexsmall Edieresissmall Igravesmall + Iacutesmall Icircumflexsmall Idieresissmall Ethsmall + Ntildesmall Ogravesmall Oacutesmall Ocircumflexsmall + + Otildesmall Odieresissmall OEsmall Oslashsmall + Ugravesmall Uacutesmall Ucircumflexsmall Udieresissmall + Yacutesmall Thornsmall Ydieresissmall 001.000 + 001.001 001.002 001.003 Black + + Bold Book Light Medium + 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 gets16($) { + my $v = getu $_[0]; + if ($v > 0x7FFF) { + $v -= 0x10000; + } + + return $v; +} + +sub getnum($) { + my $i; + my $r = 0; + + if (${$_[0]}[0] == 28) { + shift(@{$_[0]}); + for $i (0, 1) { + $r = ($r << 8) | shift(@{$_[0]}); + } + } + elsif (${$_[0]}[0] == 29) { + shift(@{$_[0]}); + for $i (0 .. 3) { + $r = ($r << 8) | shift(@{$_[0]}); + } + } + 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; +} + +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); + } + for $i (0 .. $n - 1) { + $d[$i] = substr $_[0], 2 + ($n + 1) * $sz + $off[$i], + $off[$i + 1] - $off[$i]; + } + + return substr($_[0], 2 + ($n + 1) * $sz + $off[$n]), @d; +} + +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; +} + +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"; + } + + return @c; +} + +############################################################################## + +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>; +} + +$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; +} + +$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); + } + } + $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); + } + 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; + } + } + } +} + + +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; + } +} + + +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; + } + } + ($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"; + } + 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"} + } +} +else { + for $i (0 .. 0xFF) { + $glyphName[$i] = sprintf "index0x%02X", $i; + } + for $i (0x100 .. $NumGlyphs - 1) { + $glyphName[$i] = sprintf "index0x%04X", $i; + } +} + +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); + } + } +} + +$KPX = @KPX; +print <<EOF; +StartKernData +StartKernPairs $KPX + @{KPX}EndKernPairs +EndKernData +EOF + +__END__ diff --git a/Master/texmf-dist/scripts/fontools/pfm2kpx b/Master/texmf-dist/scripts/fontools/pfm2kpx new file mode 100755 index 00000000000..a2202bcd680 --- /dev/null +++ b/Master/texmf-dist/scripts/fontools/pfm2kpx @@ -0,0 +1,299 @@ +#!/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/Master/texmf-dist/scripts/fontools/showglyphs b/Master/texmf-dist/scripts/fontools/showglyphs new file mode 100755 index 00000000000..1622ebe432f --- /dev/null +++ b/Master/texmf-dist/scripts/fontools/showglyphs @@ -0,0 +1,184 @@ +#!/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__ |