summaryrefslogtreecommitdiff
path: root/language/chinese/CJK/cjk-4.8.5/utils/subfonts
diff options
context:
space:
mode:
Diffstat (limited to 'language/chinese/CJK/cjk-4.8.5/utils/subfonts')
-rw-r--r--language/chinese/CJK/cjk-4.8.5/utils/subfonts/clonevf.pl122
-rw-r--r--language/chinese/CJK/cjk-4.8.5/utils/subfonts/hlatex2agl.pl477
-rw-r--r--language/chinese/CJK/cjk-4.8.5/utils/subfonts/makefdx.pl340
-rw-r--r--language/chinese/CJK/cjk-4.8.5/utils/subfonts/sfd2uni.pl348
-rw-r--r--language/chinese/CJK/cjk-4.8.5/utils/subfonts/subfonts.pe95
-rw-r--r--language/chinese/CJK/cjk-4.8.5/utils/subfonts/uni2sfd.pl312
-rw-r--r--language/chinese/CJK/cjk-4.8.5/utils/subfonts/vertical.pe108
-rw-r--r--language/chinese/CJK/cjk-4.8.5/utils/subfonts/vertref.pe121
8 files changed, 1923 insertions, 0 deletions
diff --git a/language/chinese/CJK/cjk-4.8.5/utils/subfonts/clonevf.pl b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/clonevf.pl
new file mode 100644
index 0000000000..74a7964a42
--- /dev/null
+++ b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/clonevf.pl
@@ -0,0 +1,122 @@
+#! /usr/bin/perl -w
+#
+# This script clones a virtual font from a TFM file.
+#
+# As prerequisites, it needs the programs `tftopl' and `vptovf', which must
+# be in the path.
+#
+# Call the script as
+#
+# perl clonevf.pl tfm-name vf-name
+#
+# Example:
+#
+# perl clonevf.pl bsmiuv bsmilpv
+
+# Copyright (C) 1994-2021 Werner Lemberg <wl@gnu.org>
+#
+# 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 in doc/COPYING; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301 USA
+
+use strict;
+
+my $prog = $0;
+$prog =~ s@.*/@@;
+
+if ($#ARGV != 1) {
+ die("usage: $prog tfm-name vf-name\n");
+}
+
+my $tfmname = $ARGV[0];
+my $vfname = $ARGV[1];
+
+
+# Create PL file.
+
+print("Processing metrics file \`$tfmname.tfm'...\n");
+
+my $arg = "tftopl $tfmname.tfm > $tfmname.pl";
+system($arg) == 0
+|| die("$prog: calling \`$arg' failed: $?\n");
+
+
+# Create VPL file.
+
+print("Writing virtual property list file \`$vfname.vpl'...\n");
+
+open(PL, "$tfmname.pl")
+|| die("$prog: can't open \`$tfmname.pl': $!\n");
+
+open(VPL, ">", "$vfname.vpl")
+|| die("$prog: can't open \`$vfname.vpl': $!\n");
+
+print(VPL "(VTITLE Created by \`$prog " . join(" ", @ARGV) . "')\n");
+print(VPL "(FAMILY TEX-\U$vfname\E)\n");
+
+my $have_mapfont = 0;
+while (<PL>) {
+ next if /^\(FAMILY/;
+ next if /^\(CHECKSUM/;
+
+ if (/^\(CHARACTER (.*)/) {
+ if (!$have_mapfont) {
+ print(VPL "(MAPFONT D 0\n");
+ print(VPL " (FONTNAME $tfmname)\n");
+ print(VPL " )\n");
+ $have_mapfont = 1;
+ }
+
+ my $char = $1;
+
+ print(VPL $_);
+
+ $_ = <PL>;
+ if (/CHARWD/) {
+ print(VPL $_);
+ $_ = <PL>;
+ }
+ if (/CHARHT/) {
+ print(VPL $_);
+ $_ = <PL>;
+ }
+ if (/CHARDP/) {
+ print(VPL $_);
+ $_ = <PL>;
+ }
+
+ print(VPL " (MAP\n");
+ print(VPL " (SELECTFONT D 0)\n");
+ print(VPL " (SETCHAR $char)\n");
+ print(VPL " )\n");
+ }
+
+ print(VPL $_);
+}
+
+close(PL);
+close(VPL);
+
+print("Processing \`$vfname.vpl'\n");
+$arg = "vptovf $vfname.vpl";
+system($arg) == 0
+|| die("$prog: calling \`$arg' failed: $?\n");
+
+print("Removing \`$tfmname.pl'...\n");
+unlink("$tfmname.pl");
+print("Removing \`$vfname.vpl'...\n");
+unlink("$vfname.vpl");
+
+
+# eof
diff --git a/language/chinese/CJK/cjk-4.8.5/utils/subfonts/hlatex2agl.pl b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/hlatex2agl.pl
new file mode 100644
index 0000000000..d0b0ffea02
--- /dev/null
+++ b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/hlatex2agl.pl
@@ -0,0 +1,477 @@
+#! /usr/bin/perl -w
+#
+# This script adds AGL compliant glyph names to fonts from the HLaTeX
+# package version 0.97 or newer. Note that only glyphs actually used in the
+# (virtual) HLaTeX subfonts get new names; additionally, the used glyph
+# shapes in the HLaTeX fonts aren't always correct -- consider this script
+# as an auxiliary means, not a definitive solution. At least the Hangul and
+# Hanja shapes are correct.
+#
+# As prerequisites, it needs the programs `t1asm' and `t1disasm' (from the
+# t1utils package) and `vftovp' which must be in the path. The subfont
+# definition file `UKS-HLaTeX.sfd' (from the ttf2pk package) and the file
+#
+# http://partners.adobe.com/public/developer/en/opentype/aglfn13.txt
+#
+# are necessary also.
+#
+# Call the script as
+#
+# perl hlatex2agl.pl virtual-namestem real-namestem sfd-file
+#
+# `virtual-namestem' specifies the name stem of the virtual subfonts
+# directly used by LaTeX; both the VF and TFM files are needed.
+# `real-namestem' gives the name stem of the real subfonts used by the
+# virtual fonts; TFM, AFM, and PFB files are needed.
+#
+# Example:
+#
+# perl hlatex2agl.pl wmj umj UKS-HLaTeX.sfd
+
+# Copyright (C) 1994-2021 Werner Lemberg <wl@gnu.org>
+#
+# 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 in doc/COPYING; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301 USA
+
+use strict;
+
+my $prog = $0;
+$prog =~ s@.*/@@;
+
+if ($#ARGV != 2) {
+ die("usage: $prog virtual-namestem real-namestem sfd-file\n");
+}
+
+my $virtnamestem = $ARGV[0];
+my $realnamestem = $ARGV[1];
+my $sfdfile = $ARGV[2];
+
+
+# Read UKS-HLaTeX.sfd.
+
+my @sfd;
+my @virtsubfonts;
+
+read_sfdfile($sfdfile, \@sfd, \@virtsubfonts);
+
+
+# Read AGL file.
+
+my %agl;
+
+read_aglfile("aglfn13.txt", \%agl);
+
+
+# Read VF files.
+
+my %vpl;
+my %subfonts;
+
+for my $suffix (@virtsubfonts) {
+ read_vffile("$virtnamestem$suffix.vf", $suffix, \%vpl, \%subfonts);
+}
+
+
+# Decompose all Hangul syllables.
+
+my @hangul;
+
+decompose_hangul(\@hangul);
+
+
+# Build glyph names.
+
+my %names;
+
+build_glyphnames(\%names);
+
+
+# Process AFM files.
+
+foreach my $suffix (sort (keys %subfonts)) {
+ process_afmfile("$realnamestem$suffix.afm", $suffix);
+}
+
+
+# Process PFB files.
+
+foreach my $suffix (sort (keys %subfonts)) {
+ process_pfbfile("$realnamestem$suffix.pfb", $suffix);
+}
+
+
+# Read an SFD file.
+#
+# $1: Name of the SFD file.
+# $2: Reference to the target array, mapping from Unicode to the subfont.
+# The format of the array values is the concatenation of the subfont
+# suffix, a space, and the index.
+# $3: Reference to a target array which holds the subfont suffixes.
+
+sub read_sfdfile {
+ my ($sfdfile, $sfdarray, $subarray) = @_;
+
+ print("Reading subfont definition file \`$sfdfile'...\n");
+
+ open(SFD, $sfdfile)
+ || die("$prog: can't open \`$sfdfile': $!\n");
+
+ my $line;
+ my $continuation = 0;
+ while (<SFD>) {
+ chop;
+
+ next if /^\s*$/;
+ next if /^#/;
+
+ if ($continuation) {
+ $line .= $_;
+ }
+ else {
+ $line = $_;
+ }
+ $continuation = 0;
+
+ if ($line =~ s/\\$//) {
+ $continuation = 1;
+ next;
+ }
+
+ $_ = $line;
+ my @field = split(" ");
+
+ my $suffix = $field[0];
+ push(@{$subarray}, $suffix);
+
+ shift(@field);
+ my $index = 0;
+
+ while (@field) {
+ if ($field[0] =~ /(.*):$/) {
+ $index = $1;
+ }
+ elsif ($field[0] =~ /(.*)_(.*)/) {
+ my $start = $1;
+ my $end = $2;
+ $start = oct($start) if ($start =~ /^0/);
+ $end = oct($end) if ($end =~ /^0/);
+ foreach my $i ($start .. $end) {
+ $sfdarray->[$i] = "$suffix $index";
+ $index++;
+ }
+ }
+ else {
+ my $value = $field[0];
+ $value = oct($value) if ($value =~ /^0/);
+ $sfdarray->[$value] = "$suffix $index";
+ $index++;
+ }
+ shift(@field);
+ }
+ }
+ close(SFD);
+}
+
+
+# Read an AGL file.
+#
+# $1: Name of the AGL file.
+# $2: Reference to the target hash file, mapping from the Unicode value
+# to the glyph name.
+
+sub read_aglfile {
+ my ($aglfile, $aglhash) = @_;
+
+ print("Reading Adobe Glyph List file \`$aglfile'...\n");
+
+ open(AGL, $aglfile)
+ || die("$prog: can't open \`$aglfile': $!\n");
+
+ while (<AGL>) {
+ chop;
+
+ next if /^\s*$/;
+ next if /^#/;
+
+ my @field = split(";");
+ $aglhash->{hex($field[0])} = $field[1];
+ }
+ close(AGL);
+}
+
+
+# Read a VF file.
+#
+# $1: Name of the VF file.
+# $2: Subfont suffix.
+# $3: Reference to a target hash, mapping from the virtual subfont to the
+# real subfonts. The format of the key is the concatenation of the
+# subfont suffix, a space, and the index. The format of the hash value
+# is `<suffix1> <idx1>[,<suffix2> <idx2>[,...]]'.
+# $4: Reference to a target hash, collecting the suffixes of the real
+# subfonts.
+
+sub read_vffile {
+ my ($vffile, $vfsuffix, $vplhash, $subfonthash) = @_;
+ my $vplfile = "$vffile.vpl";
+
+ print("Creating virtual property list file \`$vplfile'...\n");
+ my $arg = "vftovp -charcode-format=octal $vffile > $vplfile";
+ system("$arg") == 0
+ || die("$prog: calling \`$arg' failed: $?");
+
+ print("Reading \`$vplfile'...\n");
+ open(VPL, $vplfile)
+ || die("$prog: can't open \`$vplfile': $!\n");
+
+ my @subfonts;
+ my $subindex;
+ my $index;
+ my $currfont;
+ my $map = "";
+
+ while (<VPL>) {
+ if (/\(MAPFONT D ([0-9]+)/) {
+ $subindex = $1;
+ }
+ elsif (/\(FONTNAME $realnamestem(.*?)\)/) {
+ $subfonts[$subindex] = $1;
+ if (!defined ($subfonthash->{$1})) {
+ $subfonthash->{$1} = 1;
+ }
+ }
+ elsif (/\(CHARACTER O ([0-7]+)/) {
+ # Save data from previous CHARACTER block.
+ $vplhash->{"$vfsuffix $index"} = $map if ($map);
+
+ # Reset variables.
+ $index = oct($1);
+ $currfont = 0;
+ $map = "";
+ }
+ elsif (/\(SELECTFONT D ([0-9]+)\)/) {
+ $currfont = $1;
+ }
+ elsif (/\(SETCHAR O ([0-7]+)\)/) {
+ $map .= "," if ($map);
+ $map .= "$subfonts[$currfont] " . oct($1);
+ }
+ }
+
+ # Save data from last CHARACTER block.
+ $vplhash->{"$vfsuffix $index"} = $map if ($map);
+
+ close(VPL);
+ unlink($vplfile);
+}
+
+
+# Decompose all Unicode Hangul syllables into Jamo elements.
+#
+# $1: The target array, mapping from Unicode value to a list of Jamos (in
+# Unicode), separated by commata.
+#
+# This follows the algorithm given in the Unicode standard.
+
+sub decompose_hangul {
+ my ($hangularray) = @_;
+
+ my $s_base = 0xAC00;
+ my $l_base = 0x1100;
+ my $v_base = 0x1161;
+ my $t_base = 0x11A7;
+
+ my $s_count = 11172;
+ my $l_count = 19;
+ my $v_count = 21;
+ my $t_count = 28;
+
+ my $n_count = $v_count * $t_count;
+
+ for my $s ($s_base .. ($s_base + $s_count - 1)) {
+ my $s_index = $s - $s_base;
+
+ my $l = $l_base + int($s_index / $n_count);
+ my $v = $v_base + int(($s_index % $n_count) / $t_count);
+ my $t = $t_base + $s_index % $t_count;
+
+ my $jamos = "$l,$v";
+ $jamos .= ",$t" if ($t != $t_base);
+ $hangularray->[$s] = $jamos;
+ }
+}
+
+
+# Build glyph names.
+#
+# $1: The target hash which maps from real subfonts to glyph names. Keys
+# are of the form `<suffix> <index>', hash values are AGL compliant
+# glyph names. Glyph variants get a trailing suffix of the form `.N',
+# where is is a running number starting with 1. Example: `uni1100.24'.
+
+sub build_glyphnames {
+ my ($nameshash) = @_;
+
+ my @entries;
+
+ foreach my $unicode (0 .. 0xFFFF) {
+ next if !defined ($sfd[$unicode]);
+
+ my $virtdata = $sfd[$unicode];
+
+ # We assume that only Hangul syllables are composed of more than
+ # a single element.
+ if (defined ($hangul[$unicode])) {
+ my @unijamos = split(",", $hangul[$unicode]);
+ my @jamos = split(",", $vpl{$virtdata});
+
+ foreach my $i (0 .. $#jamos) {
+ if (!defined ($nameshash->{$jamos[$i]})) {
+ if (defined ($entries[$unijamos[$i]])) {
+ $nameshash->{$jamos[$i]} = sprintf("uni%04X.%d",
+ $unijamos[$i],
+ $entries[$unijamos[$i]]);
+ $entries[$unijamos[$i]] += 1;
+ }
+ else {
+ $nameshash->{$jamos[$i]} = sprintf("uni%04X", $unijamos[$i]);
+ $entries[$unijamos[$i]] = 1;
+ }
+ }
+ }
+ }
+ else {
+ if (defined ($agl{$unicode})) {
+ $nameshash->{$vpl{$virtdata}} = $agl{$unicode};
+ }
+ else {
+ $nameshash->{$vpl{$virtdata}} = sprintf("uni%04X", $unicode);
+ }
+ }
+ }
+}
+
+
+# Process AFM file.
+#
+# $1: Name of the AFM file to process. The file is first saved, then all
+# glyph names are replaced for which an AGL compliant glyph name is
+# known.
+# $2: The suffix.
+
+sub process_afmfile {
+ my ($afmfile, $sub) = @_;
+
+ print("Processing \`$afmfile'...\n");
+
+ if (!-f $afmfile) {
+ die("$prog: \`$afmfile' doesn't exist\n");
+ }
+
+ rename($afmfile, "$afmfile.old");
+
+ open(INFILE, "$afmfile.old")
+ || die("$prog: can't open \`$afmfile.old': $!\n");
+ open(OUTFILE, ">", "$afmfile")
+ || die("$prog: can't open \`$afmfile': $!\n");
+
+ while (<INFILE>) {
+ # Replace the `kxx' entries.
+ if (/ N k(.*?) ;/) {
+ my $index = hex($1);
+ if (defined ($names{"$sub $index"})) {
+ s/ N .*? ;/ N $names{"$sub $index"} ;/;
+ }
+ }
+
+ # Update version number.
+ s/001\.000/001.001/;
+ s/Altsys\ Fontographer\ 4\.1\ 1\/10\/95$/001.001/;
+
+ print(OUTFILE $_);
+
+ # Add comment.
+ if (/^Comment\ UniqueID/ || /^Comment\ Generated/) {
+ print(OUTFILE "Comment AGL compliant glyph names added "
+ . "by script $prog 2005-Jul-27.\n");
+ }
+ }
+
+ close(INFILE);
+ close(OUTFILE);
+}
+
+
+# Process PFB file.
+#
+# $1: Name of the PFB file to process. The file is first saved, then all
+# glyph names are replaced for which an AGL compliant glyph name is
+# known.
+# $2: The suffix.
+
+sub process_pfbfile {
+ my ($pfbfile, $sub) = @_;
+ my $arg;
+
+ print("Processing \`$pfbfile'...\n");
+
+ if (!-f $pfbfile) {
+ die("$prog: \`$pfbfile' doesn't exist\n");
+ }
+
+ rename($pfbfile, "$pfbfile.old");
+
+ $arg = "t1disasm < $pfbfile.old > $pfbfile.disasm.old";
+ system("$arg") == 0
+ || die("$prog: calling \`$arg' failed: $?");
+
+ open(INFILE, "$pfbfile.disasm.old")
+ || die("$prog: can't open \`$pfbfile.disasm.old': $!\n");
+ open(OUTFILE, ">", "$pfbfile.disasm")
+ || die("$prog: can't open \`$pfbfile.disasm': $!\n");
+
+ while (<INFILE>) {
+ # Replace the `kxx' entries.
+ if (m@/k(.*?) @) {
+ my $index = hex($1);
+ if (defined ($names{"$sub $index"})) {
+ s@/k.*? @/$names{"$sub $index"} @;
+ }
+ }
+
+ # Update version number.
+ s/001\.000/001.001/;
+
+ print(OUTFILE $_);
+
+ # Add comment.
+ if (/^%%CreationDate/) {
+ print(OUTFILE "% AGL compliant glyph names added "
+ . "by script $prog 2005-Jul-27.\n");
+ }
+ }
+
+ close(INFILE);
+ close(OUTFILE);
+
+ $arg = "t1asm < $pfbfile.disasm > $pfbfile";
+ system("$arg") == 0
+ || die("$prog: calling \`$arg' failed: $?");
+
+ unlink("$pfbfile.disasm.old", "$pfbfile.disasm");
+}
+
+
+# eof
diff --git a/language/chinese/CJK/cjk-4.8.5/utils/subfonts/makefdx.pl b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/makefdx.pl
new file mode 100644
index 0000000000..5363e5b63d
--- /dev/null
+++ b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/makefdx.pl
@@ -0,0 +1,340 @@
+#! /usr/bin/perl -w
+#
+# This script creates proper entries for an FDX file as used by the CJK
+# package for LaTeX.
+#
+# As a prerequisite, it needs the file
+#
+# http://partners.adobe.com/public/developer/en/opentype/aglfn13.txt
+#
+# which must be located in the current directory.
+#
+# Call the script as
+#
+# perl [-u] makefdx.pl vertref-afm-file sfd-file encoding font-name
+#
+# `vertref-afm-file' is an AFM file as produced by the script `vertref.pe'.
+# The subfont definition file `sfd-file' gives the subfont scheme to get the
+# proper entries in the FDX file. `encoding' and `font-name' are TeX font
+# parameters as used by the CJK package; the scripts uses the concatenation
+# of those two values as the name of the FDX file (with suffix `.fdx').
+#
+# The switch `-u' makes the script add a macro to the FDX file (which is
+# used by the CJKutf8.sty) to provide a proper /ToUnicode cmap to pdftex.
+#
+# Note that the created FDX file has to be completed manually.
+#
+# Examples:
+#
+# perl makefdx.pl bsmiuvr.afm UBig5.sfd c00 bsmi
+#
+# The result of this call is the file `c00bsmi.fdx' (you get some warnings
+# because not all glyphs contained in bsmiuvr.afm can be accessed with Big5
+# encoding).
+#
+# perl makefdx.pl -u bsmiuvr.afm Unicode.sfd c70 bsmi
+#
+# The result of this call is the file `c70bsmi.fdx'.
+#
+# A collection of useful subfont definition files for CJK fonts can be found
+# in the ttf2pk package.
+
+# Copyright (C) 1994-2021 Werner Lemberg <wl@gnu.org>
+#
+# 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 in doc/COPYING; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301 USA
+
+use strict;
+
+my $prog = $0;
+$prog =~ s@.*/@@;
+
+my $is_unicode = 0;
+if ($ARGV[0] eq "-u") {
+ $is_unicode = 1;
+ shift @ARGV;
+}
+
+if ($#ARGV != 3) {
+ die("usage: $prog [-u] vertref-afm-file sfd-file encoding font-name\n");
+}
+
+my $vertrefafmfile = $ARGV[0];
+my $sfdfile = $ARGV[1];
+my $encoding = $ARGV[2];
+my $fontname = $ARGV[3];
+
+my $fdxfile = $encoding . $fontname . ".fdx";
+
+# Read AGL file.
+
+my %agl;
+
+read_aglfile("aglfn13.txt", \%agl);
+
+
+# Read AFM file.
+
+my @vertref;
+
+read_afmfile($vertrefafmfile, \@vertref);
+
+
+# Read subfont definition file.
+
+my @sfd;
+
+read_sfdfile($sfdfile, \@sfd);
+
+
+# Write FDX file.
+
+print("Writing extended font definition file \`$fdxfile'...\n");
+
+open(FDX, ">", $fdxfile)
+|| die("$prog: can't open \`$fdxfile': $!\n");
+my $oldfh = select(FDX);
+
+print("% This is the file $fdxfile of the CJK package
+% for using Asian logographs (Chinese/Japanese/Korean) with LaTeX2e
+%
+% created by the script makefdx.pl for CJK Version 4.8.5 (16-Oct-2021).
+
+\\def\\fileversion{4.8.5}
+\\def\\filedate{2021/10/16}
+\\ProvidesFile{$fdxfile}[\\filedate\\space\\fileversion]
+
+\\CJKvdef{fullheight}{1em}
+\\CJKvdef{height}{.88em}
+\\CJKvdef{offset}{.6em}
+
+% Uncomment if necessary.
+%\\CJKvdef{norotate}{}
+");
+
+my @unicodes;
+my $mapping_count = 0;
+
+foreach my $index (0 .. $#vertref) {
+ my $glyphnameref = $vertref[$index];
+ my $unicode;
+
+ if (defined ($agl{$glyphnameref})) {
+ $unicode = $agl{$glyphnameref};
+ }
+ elsif ($glyphnameref =~ /^uni([0-9A-F]{4})$/) {
+ $unicode = hex($1);
+ }
+ elsif ($glyphnameref =~ /^u([0-9A-F]{4,6})$/) {
+ $unicode = hex($1);
+ }
+ else {
+ $unicode = -1;
+ }
+ if ($unicode == -1
+ || ($unicode >= 0xD800 && $unicode <= 0xDFFF)
+ || $unicode > 0x10FFFF) {
+ print(STDERR "Can't map glyph name \`$glyphnameref' to Unicode.\n");
+ $unicodes[$index] = -1;
+ next;
+ }
+ $unicodes[$index] = $unicode;
+
+ my $sfdentry;
+
+ if (defined ($sfd[$unicode])) {
+ $sfdentry = $sfd[$unicode];
+ }
+ else {
+ $unicodes[$index] = -1;
+ printf(STDERR "\`%s' (U+%04X) not in subfont encoding\n",
+ $glyphnameref, $unicode);
+ next;
+ }
+
+ $mapping_count++;
+
+ print("\\CJKvdef{m/n/$sfdentry}");
+ print("{\\def\\CJK\@plane{v}\\selectfont\\CJKsymbol{$index}}\n");
+ print("\\CJKvlet{bx/n/$sfdentry}");
+ print("{m/n/$sfdentry}\n");
+}
+
+if ($is_unicode) {
+ print("
+\\gdef\\CJK\@cmap\@${fontname}v{
+ \\expandafter\\ifx\\csname CJK\@CMap\@${fontname}v\\endcsname \\relax
+ \\immediate\\pdfobj stream {
+ /CIDInit\\space/ProcSet\\space findresource\\space begin\\space
+ 12\\space dict\\space begin\\space
+ begincmap\\space
+ /CIDSystemInfo\\space <<\\space
+ /Registry\\space (TeX)\\space
+ /Ordering\\space (${fontname}v)\\space
+ /Supplement\\space 0\\space >>\\space def\\space
+ /CMapName\\space /TeX-${fontname}v-0\\space def\\space
+ 1\\space begincodespacerange\\space
+ <00>\\space <FF>\\space
+ endcodespacerange\\space
+ $mapping_count\\space beginbfchar\\space
+");
+
+ foreach my $index (0 .. $#vertref) {
+ if ($unicodes[$index] != -1) {
+ printf(" <%02X>\\space <%04X>\\space\n",
+ $index, $unicodes[$index]);
+ }
+ }
+
+ print(" endbfchar\\space
+ endcmap\\space
+ CMapName\\space currentdict\\space /CMap\\space defineresource\\space
+ pop\\space
+ end\\space
+ end\\space}
+ \\expandafter\\xdef\\csname CJK\@CMap\@${fontname}v\\endcsname{
+ \\the\\pdflastobj}
+ \\fi
+ \\pdffontattr\\font\@name{
+ /ToUnicode\\space\\csname CJK\@CMap\@${fontname}v\\endcsname\\space 0\\space R}
+}
+
+\\endinput
+");
+}
+
+
+# Read an AGL file.
+#
+# $1: Name of the AGL file.
+# $2: Reference to the target hash file, mapping from the glyph name
+# to the Unicode value.
+
+sub read_aglfile {
+ my ($aglfile, $aglhash) = @_;
+
+ print("Reading Adobe Glyph List file \`$aglfile'...\n");
+
+ open(AGL, $aglfile)
+ || die("$prog: can't open \`$aglfile': $!\n");
+
+ while (<AGL>) {
+ chop;
+
+ next if /^\s*$/;
+ next if /^#/;
+
+ my @field = split(";");
+ $aglhash->{$field[1]} = hex($field[0]);
+ }
+ close(AGL);
+}
+
+
+# Read an SFD file.
+#
+# $1: Name of the SFD file.
+# $2: Reference to the target array file, mapping from the character code
+# to the subfont index. The format of an array value is the
+# concatenation of the subfont suffix, a slash, and the index.
+
+sub read_sfdfile {
+ my ($sfdfile, $sfdarray) = @_;
+
+ print("Reading subfont definition file \`$sfdfile'...\n");
+
+ open(SFD, $sfdfile)
+ || die("$prog: can't open \`$sfdfile': $!\n");
+
+ my $line;
+ my $continuation = 0;
+ while (<SFD>) {
+ chop;
+
+ next if /^\s*$/;
+ next if /^#/;
+
+ if ($continuation) {
+ $line .= $_;
+ }
+ else {
+ $line = $_;
+ }
+ $continuation = 0;
+
+ if ($line =~ s/\\$//) {
+ $continuation = 1;
+ next;
+ }
+
+ $_ = $line;
+ my @field = split(" ");
+
+ my $suffix = $field[0];
+
+ shift(@field);
+ my $index = 0;
+
+ while (@field) {
+ if ($field[0] =~ /(.*):$/) {
+ $index = $1;
+ }
+ elsif ($field[0] =~ /(.*)_(.*)/) {
+ my $start = $1;
+ my $end = $2;
+ $start = oct($start) if ($start =~ /^0/);
+ $end = oct($end) if ($end =~ /^0/);
+ foreach my $i ($start .. $end) {
+ $sfdarray->[$i] = "$suffix/$index";
+ $index++;
+ }
+ }
+ else {
+ my $value = $field[0];
+ $value = oct($value) if ($value =~ /^0/);
+ $sfdarray->[$value] = "$suffix/$index";
+ $index++;
+ }
+ shift(@field);
+ }
+ }
+ close(SFD);
+}
+
+
+# Read an AFM file.
+#
+# $1: Name of the AFM file.
+# $2: Reference to array which maps glyph indices to glyph names.
+
+sub read_afmfile {
+ my ($afmfile, $maparray) = @_;
+
+ print("Reading metrics file \`$afmfile'\n");
+
+ open(AFM, $afmfile)
+ || die("$prog: can't open \`$afmfile': $!\n");
+
+ while (<AFM>) {
+ if (/^C \d+ ;/) {
+ / N (.*?) ;/;
+ push (@$maparray, $1);
+ }
+ }
+ close(AFM);
+}
+
+
+# eof
diff --git a/language/chinese/CJK/cjk-4.8.5/utils/subfonts/sfd2uni.pl b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/sfd2uni.pl
new file mode 100644
index 0000000000..5aa1946d32
--- /dev/null
+++ b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/sfd2uni.pl
@@ -0,0 +1,348 @@
+#! /usr/bin/perl -w
+#
+# This script creates virtual subfonts in Unicode encoding for a font
+# encoding given by a subfont definition file (which must use Unicode
+# code points).
+#
+# As prerequisites it needs the programs `tftopl' and `vptovf' which must be
+# in the path.
+#
+# Call the script as
+#
+# perl sfd2uni.pl sfd-file namestem uni-namestem codingscheme
+#
+# `sfd-file' is the subfont definition file, `namestem' is the name stem
+# of the subfonts defined in `sfd-file', and `uni-namestem' holds the prefix
+# for the Unicode subfonts. `codingscheme' (converted to uppercase) is used
+# for the CODINGSCHEME parameter in the resulting TFM files.
+#
+# `sfd2uni.pl' reads all TFM files from the font family with name stem
+# `namestem'.
+#
+# Example:
+#
+# perl sfd2uni.pl UKS-HLaTeX.sfd wmj uwmj HLATEX
+#
+# A collection of useful subfont definition files for CJK fonts can be found
+# in the ttf2pk package.
+
+# Copyright (C) 1994-2021 Werner Lemberg <wl@gnu.org>
+#
+# 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 in doc/COPYING; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301 USA
+
+use strict;
+
+my $prog = $0;
+$prog =~ s@.*/@@;
+
+if ($#ARGV != 3) {
+ die("usage: $prog sfd-file namestem uni-namestem codingscheme\n");
+}
+
+my $sfdfile = $ARGV[0];
+my $namestem = $ARGV[1];
+my $uninamestem = $ARGV[2];
+my $codingscheme = $ARGV[3];
+
+
+# Read subfont definition file.
+
+my %sfd;
+my @subfonts;
+
+read_sfdfile($sfdfile, \%sfd, \@subfonts);
+
+
+# Read TFM files.
+
+my @unicmetrics;
+
+foreach my $sub (@subfonts) {
+ my $tfmname = "$namestem$sub.tfm";
+
+ read_tfmfile($tfmname, \@unicmetrics, \%sfd, $sub);
+}
+
+
+# Read FONTDIMEN block.
+
+my $fontdimen = read_fontdimen("$namestem$subfonts[0].tfm");
+
+
+# Write VPL files.
+
+my $index = 0;
+foreach my $i (0 .. 255) {
+ my @entries;
+
+ foreach my $j (0 .. 255) {
+ if (defined ($unicmetrics[$index])) {
+ push(@entries, "$j $unicmetrics[$index]");
+ }
+ $index++;
+ }
+
+ if ($#entries >= 0) {
+ write_vplfile($uninamestem . sprintf("%02x.vpl", $i), \@entries);
+ }
+}
+
+
+# Generate VF and TFM files, then remove the VPL files.
+
+my @vplfiles = glob("$uninamestem*.vpl");
+foreach my $vplfile (@vplfiles) {
+ print("Processing \`$vplfile'...\n");
+ my $arg = "vptovf $vplfile";
+ system($arg) == 0
+ || die("$prog: calling \`$arg' failed: $?");;
+ print("Removing \`$vplfile'...\n");
+ unlink($vplfile);
+}
+
+
+# Read an SFD file.
+#
+# $1: Name of the SFD file.
+# $2: Reference to the target hash file, mapping from the subfont index to
+# the character code. The format of the key value is the concatenation
+# of the subfont suffix, a space, and the index.
+# $3: Reference to a target array which holds the subfont suffixes.
+
+sub read_sfdfile {
+ my ($sfdfile, $sfdhash, $sfdarray) = @_;
+
+ print("Reading subfont definition file \`$sfdfile'...\n");
+
+ open(SFD, $sfdfile)
+ || die("$prog: can't open \`$sfdfile': $!\n");
+
+ my $line;
+ my $continuation = 0;
+ while (<SFD>) {
+ chop;
+
+ next if /^\s*$/;
+ next if /^#/;
+
+ if ($continuation) {
+ $line .= $_;
+ }
+ else {
+ $line = $_;
+ }
+ $continuation = 0;
+
+ if ($line =~ s/\\$//) {
+ $continuation = 1;
+ next;
+ }
+
+ $_ = $line;
+ my @field = split(" ");
+
+ my $suffix = $field[0];
+ push(@{$sfdarray}, $suffix);
+
+ shift(@field);
+ my $index = 0;
+
+ while (@field) {
+ if ($field[0] =~ /(.*):$/) {
+ $index = $1;
+ }
+ elsif ($field[0] =~ /(.*)_(.*)/) {
+ my $start = $1;
+ my $end = $2;
+ $start = oct($start) if ($start =~ /^0/);
+ $end = oct($end) if ($end =~ /^0/);
+ foreach my $i ($start .. $end) {
+ $sfdhash->{"$suffix $index"} = $i;
+ $index++;
+ }
+ }
+ else {
+ my $value = $field[0];
+ $value = oct($value) if ($value =~ /^0/);
+ $sfdhash->{"$suffix $index"} = $value;
+ $index++;
+ }
+ shift(@field);
+ }
+ }
+ close(SFD);
+}
+
+
+# Read TFM file.
+#
+# $1: Name of the TFM file.
+# $2: Reference to the target array holding metric information in the form
+# `<subfont> <subfont_index> <width> <heigth> <depth>'.
+# $3: Reference to a hash created by `read_sfdfile'.
+# $4: Subfont suffix.
+
+sub read_tfmfile {
+ my ($tfmfile, $unicarray, $sfdhash, $sub) = @_;
+
+ print("Processing metrics file \`$tfmfile'...\n");
+ my $arg = "tftopl $tfmfile > $tfmfile.pl";
+ system($arg) == 0
+ || die("$prog: calling \`$arg' failed: $?\n");
+
+ print("Reading property list file \`$tfmfile.pl'...\n");
+ open(PL, "$tfmfile.pl")
+ || die("$prog: can't open \`$tfmfile.pl': $!\n");
+
+ while (<PL>) {
+ my $index;
+ if (/^\(CHARACTER O (\d+)/) {
+ $index = oct($1);
+ }
+ elsif (/^\(CHARACTER C (.)/) {
+ $index = ord($1);
+ }
+ else {
+ next;
+ }
+
+ my $wd = "0";
+ my $ht = "0";
+ my $dp = "0";
+
+ $_ = <PL>;
+ if (/\(CHARWD R (.*)\)/) {
+ $wd = "$1";
+ $_ = <PL>;
+ }
+ if (/\(CHARHT R (.*)\)/) {
+ $ht = "$1";
+ $_ = <PL>;
+ }
+ if (/\(CHARDP R (.*)\)/) {
+ $dp = "$1";
+ }
+
+ if (defined ($sfdhash->{"$sub $index"})) {
+ $unicarray->[$sfdhash->{"$sub $index"}] = "$sub $index $wd $ht $dp";
+ }
+ }
+ close(PL);
+ print("Removing \`$tfmfile.pl'...\n");
+ unlink("$tfmfile.pl");
+}
+
+
+# Read FONTDIMEN block of a TFM file.
+#
+# $1: Name of the TFM file.
+#
+# Return the block as a string.
+
+sub read_fontdimen {
+ my ($tfmfile) = @_;
+
+ print("Processing metrics file \`$tfmfile'...\n");
+ my $arg = "tftopl $tfmfile > $tfmfile.pl";
+ system($arg) == 0
+ || die("$prog: calling \`$arg' failed: $?\n");
+
+ print("Reading property list file \`$tfmfile.pl'...\n");
+ open(PL, "$tfmfile.pl")
+ || die("$prog: can't open \`$tfmfile.pl': $!\n");
+
+ my $s = "";
+ my $have_fontdimen = 0;
+
+ while (<PL>) {
+ if (/^\(FONTDIMEN/) {
+ $have_fontdimen = 1;
+ }
+
+ if ($have_fontdimen) {
+ $s .= $_;
+
+ last if (/^ \)/);
+ }
+ }
+
+ close(PL);
+ print("Removing \`$tfmfile.pl'...\n");
+ unlink("$tfmfile.pl");
+
+ return $s;
+}
+
+
+# Write VPL file.
+#
+# $1: Name of the VPL file.
+# $2: Reference to list which holds the font entries. An entry has the
+# form `<idx> <subfont> <subfont_idx> <width> <height> <depth>'.
+
+sub write_vplfile {
+ my ($vplfile, $metricsarray) = @_;
+
+ my %subfonts;
+ my $subcount = 0;
+
+ foreach my $entry (@{$metricsarray}) {
+ my @field = split(" ", $entry);
+ my $subfont = $field[1];
+ if (!defined ($subfonts{$subfont})) {
+ $subfonts{$subfont} = $subcount;
+ $subcount++;
+ }
+ }
+
+ print("Writing virtual property list file \`$vplfile'...\n");
+
+ open(VPL, ">", $vplfile)
+ || die("$prog: can't open \`$vplfile': $!\n");
+ my $oldfh = select(VPL);
+
+ print("(VTITLE Created by \`$prog " . join(" ", @ARGV) . "')\n");
+ print("(FAMILY TEX-\U$uninamestem\E)\n");
+ print("(CODINGSCHEME \U$codingscheme\E)\n");
+ print $fontdimen;
+
+ foreach my $subfont
+ (sort { $subfonts{$a} <=> $subfonts{$b} } keys %subfonts) {
+ print("(MAPFONT D $subfonts{$subfont}\n");
+ print(" (FONTNAME $namestem$subfont)\n");
+ print(" )\n");
+ }
+
+ foreach my $entry (@{$metricsarray}) {
+ my ($index, $subnumber, $subindex, $wd, $ht, $dp) = split(" ", $entry);
+
+ print("(CHARACTER D $index\n");
+ print(" (CHARWD R $wd)\n");
+ print(" (CHARHT R $ht)\n");
+ print(" (CHARDP R $dp)\n");
+ print(" (MAP\n");
+ print(" (SELECTFONT D $subfonts{$subnumber})\n");
+ print(" (SETCHAR D $subindex)\n");
+ print(" )\n");
+ print(" )\n");
+ }
+
+ close(VPL);
+ select($oldfh);
+}
+
+
+# eof
diff --git a/language/chinese/CJK/cjk-4.8.5/utils/subfonts/subfonts.pe b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/subfonts.pe
new file mode 100644
index 0000000000..347e53b6df
--- /dev/null
+++ b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/subfonts.pe
@@ -0,0 +1,95 @@
+# Generate CJK subfonts from master font.
+# The fonts are created in the current directory.
+#
+# $1: The master font (e.g., `bsmi00lp.ttf').
+# $2: The name stem for the subfonts (e.g., `bsmilp').
+# $3: The subfont definition file, mapping from Unicode to whatever
+# (e.g., `UBig5.sfd', which maps to Big 5).
+#
+# A collection of useful subfont definition files for CJK fonts can be found
+# in the ttf2pk package.
+
+# Copyright (C) 1994-2021 Werner Lemberg <wl@gnu.org>
+#
+# 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 in doc/COPYING; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301 USA
+
+if (Strtol($version) < 20071105)
+ Print("Can't use FontForge version before 2007-11-05. Aborting.");
+ Quit(1);
+endif;
+
+if ($argc != 4)
+ Print("usage: [fontforge -script] ", $0, " master-font name-stem SFD-file");
+ Quit(1);
+endif;
+
+Print("Loading ", $1, "...");
+Open($1);
+
+if ($cidfontname != "")
+ CIDFlatten();
+endif;
+
+Reencode("ucs4");
+
+copyright = $copyright \
+ + Chr(10) + Chr(10) \
+ + "Subfont version " \
+ + Strftime("%F", 1, "C") \
+ + ".";
+SetFontNames("", "", "", "", copyright, "");
+
+Print("Ensure third order curves...");
+SetFontOrder(3);
+
+Print("Scaling to PostScript units...");
+ScaleToEm(900, 100);
+
+num_chars = CharCnt();
+count = 0;
+delta = 100;
+
+while (count + delta < num_chars)
+ Print(count, "/", num_chars - 1, ":");
+ Select(count, count + delta);
+
+ Print(" Add extrema...");
+ AddExtrema();
+
+ Print(" Simplifying outlines...");
+ Simplify(0, 2);
+
+ count += delta;
+endloop;
+
+Print(count, "/", num_chars - 1, ":");
+Select(count, num_chars - 1);
+
+Print(" Add extrema...");
+AddExtrema();
+
+Print(" Simplifying outlines...");
+Simplify(0, 2);
+
+SelectAll();
+
+# generate AFM and TFM files, no PS hints, and rounded PS coordinates
+Print("Generating subfonts...");
+Generate($2 + "%s.pfb", "", \
+ 0x1 | 0x100 | 0x10000 | 0x80000 | 0x200000, \
+ -1, $3);
+
+Quit(0);
diff --git a/language/chinese/CJK/cjk-4.8.5/utils/subfonts/uni2sfd.pl b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/uni2sfd.pl
new file mode 100644
index 0000000000..fc89bf7017
--- /dev/null
+++ b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/uni2sfd.pl
@@ -0,0 +1,312 @@
+#! /usr/bin/perl -w
+#
+# This script creates virtual subfonts in a font encoding given by a subfont
+# definition file, based on Unicode subfonts.
+#
+# As prerequisites, it needs the programs `tftopl' and `vptovf' which must
+# be in the path.
+#
+# Call the script as
+#
+# perl uni2sfd.pl uni-namestem sfd-file namestem codingscheme
+#
+# `uni-namestem' is the namestem of the Unicode subfonts; `uni2sfd.pl'
+# appends the Unicode suffixes and reads the corresponding TFM files.
+# `sfd-file' is the subfont definition file which maps Unicode input
+# characters to the target subfont scheme using `namestem' as the namestem.
+# `codingscheme' gives the value for the CODINGSCHEME parameter in the
+# VF files (always converted to uppercase).
+#
+# Example:
+#
+# perl uni2sfd.pl bsmiu UBig5.sfd bsmilp cjkbig5
+#
+# A collection of useful subfont definition files for CJK fonts can be found
+# in the ttf2pk package.
+
+# Copyright (C) 1994-2021 Werner Lemberg <wl@gnu.org>
+#
+# 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 in doc/COPYING; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301 USA
+
+use strict;
+
+my $prog = $0;
+$prog =~ s@.*/@@;
+
+if ($#ARGV != 3) {
+ die("usage: $prog uni-namestem sfd-file namestem codingscheme\n");
+}
+
+my $uninamestem = $ARGV[0];
+my $sfdfile = $ARGV[1];
+my $namestem = $ARGV[2];
+my $codingscheme = $ARGV[3];
+
+
+# Read subfont definition file.
+
+my %sfd;
+my @subfonts;
+
+read_sfdfile($sfdfile, \%sfd, \@subfonts);
+
+
+# Read TFM files.
+
+my @unimetrics;
+
+foreach my $sub (0 .. 0xFF) {
+ my $suffix = sprintf("%02x", $sub);
+ my $tfmname = "$uninamestem$suffix.tfm";
+
+ if (-f $tfmname) {
+ read_tfmfile($tfmname, \@unimetrics, $suffix);
+ }
+}
+
+
+# Write VPL files.
+
+foreach my $sub (@subfonts) {
+ my @entries;
+
+ foreach my $i (0 .. 255) {
+ if (defined ($sfd{"$sub $i"})) {
+ my $index = $sfd{"$sub $i"};
+ if (defined ($unimetrics[$index])) {
+ push(@entries, "$i $index $unimetrics[$index]");
+ }
+ }
+ }
+
+ if ($#entries >= 0) {
+ write_vplfile("$namestem$sub.vpl", \@entries);
+ }
+}
+
+
+# Generate VF and TFM files, then remove the VPL files.
+
+my @vplfiles = glob("$namestem*.vpl");
+foreach my $vplfile (@vplfiles) {
+ print("Processing \`$vplfile'...\n");
+ my $arg = "vptovf $vplfile";
+ system($arg) == 0
+ || die("$prog: calling \`$arg' failed: $?\n");
+ print("Removing \`$vplfile'...\n");
+ unlink($vplfile);
+}
+
+
+# Read an SFD file.
+#
+# $1: Name of the SFD file.
+# $2: Reference to the target hash file, mapping from the character code
+# to the subfont index. The format of the key value is the
+# concatenation of the subfont suffix, a space, and the index.
+# $3: Reference to a target array which holds the subfont suffixes.
+
+sub read_sfdfile {
+ my ($sfdfile, $sfdhash, $sfdarray) = @_;
+
+ print("Reading subfont definition file \`$sfdfile'...\n");
+
+ open(SFD, $sfdfile)
+ || die("$prog: can't open \`$sfdfile': $!\n");
+
+ my $line;
+ my $continuation = 0;
+ while (<SFD>) {
+ chop;
+
+ next if /^\s*$/;
+ next if /^#/;
+
+ if ($continuation) {
+ $line .= $_;
+ }
+ else {
+ $line = $_;
+ }
+ $continuation = 0;
+
+ if ($line =~ s/\\$//) {
+ $continuation = 1;
+ next;
+ }
+
+ $_ = $line;
+ my @field = split(" ");
+
+ my $suffix = $field[0];
+ push(@{$sfdarray}, $suffix);
+
+ shift(@field);
+ my $index = 0;
+
+ while (@field) {
+ if ($field[0] =~ /(.*):$/) {
+ $index = $1;
+ }
+ elsif ($field[0] =~ /(.*)_(.*)/) {
+ my $start = $1;
+ my $end = $2;
+ $start = oct($start) if ($start =~ /^0/);
+ $end = oct($end) if ($end =~ /^0/);
+ foreach my $i ($start .. $end) {
+ $sfdhash->{"$suffix $index"} = $i;
+ $index++;
+ }
+ }
+ else {
+ my $value = $field[0];
+ $value = oct($value) if ($value =~ /^0/);
+ $sfdhash->{"$suffix $index"} = $value;
+ $index++;
+ }
+ shift(@field);
+ }
+ }
+ close(SFD);
+}
+
+
+# Read TFM file.
+#
+# $1: Name of the TFM file.
+# $2: Reference to the target array holding metric information in the form
+# `<width> <heigth> <depth>'.
+# $3: Subfont suffix.
+
+sub read_tfmfile {
+ my ($tfmfile, $unicarray, $suffix) = @_;
+
+ print("Processing metrics file \`$tfmfile'...\n");
+ my $arg = "tftopl $tfmfile > $tfmfile.pl";
+ system($arg) == 0
+ || die("$prog: calling \`$arg' failed: $?\n");
+
+ print("Reading property list file \`$tfmfile.pl'...\n");
+ open(PL, "$tfmfile.pl")
+ || die("$prog: can't open \`$tfmfile.pl': $!\n");
+
+ while (<PL>) {
+ my $idx;
+ if (/^\(CHARACTER O (\d+)/) {
+ $idx = oct($1);
+ }
+ elsif (/^\(CHARACTER C (.)/) {
+ $idx = ord($1);
+ }
+ else {
+ next;
+ }
+ $idx += hex($suffix) * 256;
+
+ my $wd = "0";
+ my $ht = "0";
+ my $dp = "0";
+
+ $_ = <PL>;
+ if (/\(CHARWD R (.*)\)/) {
+ $wd = "$1";
+ $_ = <PL>;
+ }
+ if (/\(CHARHT R (.*)\)/) {
+ $ht = "$1";
+ $_ = <PL>;
+ }
+ if (/\(CHARDP R (.*)\)/) {
+ $dp = "$1";
+ }
+
+ $unicarray->[$idx] = "$wd $ht $dp";
+ }
+ close(PL);
+ print("Removing \`$tfmfile.pl'...\n");
+ unlink("$tfmfile.pl");
+}
+
+
+# Write VPL file.
+#
+# $1: Name of the VPL file.
+# $2: Reference to list which holds the font entries. An entry has the
+# form `<index> <Unicode> <width> <height> <depth>'.
+
+sub write_vplfile {
+ my ($vplfile, $glypharray) = @_;
+
+ my %subfonts;
+ my $subcount = 0;
+
+ foreach my $entry (@{$glypharray}) {
+ my @field = split(" ", $entry);
+ my $subfont = int($field[1] / 256);
+ if (!defined ($subfonts{$subfont})) {
+ $subfonts{$subfont} = $subcount;
+ $subcount++;
+ }
+ }
+
+ print("Writing virtual property list file \`$vplfile'...\n");
+
+ open(VPL, ">", $vplfile)
+ || die("$prog: can't open \`$vplfile': $!\n");
+ my $oldfh = select(VPL);
+
+ print("(VTITLE Created by \`$prog " . join(" ", @ARGV) . "')\n");
+ print("(FAMILY TEX-\U$namestem\E)\n");
+ print("(CODINGSCHEME \U$codingscheme\E)\n");
+ print("(FONTDIMEN\n");
+ print(" (SPACE R 0.5)\n");
+ print(" (XHEIGHT R 0.4)\n");
+ print(" (QUAD R 1)\n");
+ print(" )\n");
+
+ foreach my $subfont
+ (sort { $subfonts{$a} <=> $subfonts{$b} } keys %subfonts) {
+ print("(MAPFONT D $subfonts{$subfont}\n");
+ print(" (FONTNAME $uninamestem" . sprintf("%02x", $subfont) . ")\n");
+ print(" )\n");
+ }
+
+ foreach my $entry (@{$glypharray}) {
+ my @field = split(" ", $entry);
+ my $index = $field[0];
+ my $subnumber = $subfonts{int($field[1] / 256)};
+ my $subindex = $field[1] % 256;
+ my $width = $field[2];
+ my $height = $field[3];
+ my $depth = $field[4];
+
+ print("(CHARACTER D $index\n");
+ print(" (CHARWD R $width)\n");
+ print(" (CHARHT R $height)\n");
+ print(" (CHARDP R $depth)\n");
+ print(" (MAP\n");
+ print(" (SELECTFONT D $subnumber)\n");
+ print(" (SETCHAR D $subindex)\n");
+ print(" )\n");
+ print(" )\n");
+ }
+
+ close(VPL);
+ select($oldfh);
+}
+
+
+# eof
diff --git a/language/chinese/CJK/cjk-4.8.5/utils/subfonts/vertical.pe b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/vertical.pe
new file mode 100644
index 0000000000..a10faef088
--- /dev/null
+++ b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/vertical.pe
@@ -0,0 +1,108 @@
+# Generate a font which contains vertical glyph representations.
+# The font is created in the current directory.
+#
+# $1: The master font (e.g., `bsmi00lp.ttf').
+# $2: The name of the vertical font (e.g., `bsmilpv').
+
+# Copyright (C) 1994-2007 Werner Lemberg <wl@gnu.org>
+#
+# 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 in doc/COPYING; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301 USA
+
+if (Strtol($version) < 20071105)
+ Print("Can't use FontForge version before 2007-11-05. Aborting.";
+ Quit(1);
+endif;
+
+if ($argc != 3)
+ Print("usage: [fontforge -script] ", $0, " master-font vertical-fontname");
+ Quit(1);
+endif;
+
+Print("Loading ", $1, "...");
+Open($1);
+
+fontname = $2;
+fullname = $fullname + " vertical";
+copyright = $copyright \
+ + Chr(10) + Chr(10) \
+ + "Vertical glyph representations version " \
+ + Strftime("%F", 1, "C") \
+ + ".";
+SetFontNames(fontname, "", fullname, "", copyright, "");
+
+SelectAll();
+ApplySubstitution("*", "*", "vert");
+
+if (!$fontchanged)
+ Print("No vertical glyph representation forms found.");
+ Quit(1);
+endif;
+
+SelectChanged();
+
+SelectInvert();
+DetachAndRemoveGlyphs();
+
+Print("Ensure third order curves...");
+SetFontOrder(3);
+
+Print("Scaling to PostScript units...");
+ScaleToEm(900, 100);
+
+num_chars = CharCnt();
+count = 0;
+delta = 100;
+
+while (count + delta < num_chars)
+ Print(count, "/", num_chars - 1, ":");
+ Select(count, count + delta);
+
+ Print(" Add extrema...");
+ AddExtrema();
+
+ Print(" Simplifying outlines...");
+ Simplify(0, 2);
+
+ count += delta;
+endloop;
+
+Print(count, "/", num_chars - 1, ":");
+Select(count, num_chars - 1);
+
+Print(" Add extrema...");
+AddExtrema();
+
+Print(" Simplifying outlines...");
+Simplify(0, 2);
+
+SelectAll();
+foreach
+ unicode = GlyphInfo("Unicode");
+ if (unicode > 0)
+ SetUnicodeValue(unicode);
+ name = GlyphInfo("Name");
+ SetGlyphName(name + ".vert", 0);
+ endif
+endloop;
+
+Reencode("original");
+
+# generate AFM and TFM files, no PS hints, and rounded PS coordinates
+Print("Generating font...");
+Generate($2 + ".pfb", "", \
+ 0x1 | 0x100 | 0x10000 | 0x80000 | 0x200000);
+
+Quit(0);
diff --git a/language/chinese/CJK/cjk-4.8.5/utils/subfonts/vertref.pe b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/vertref.pe
new file mode 100644
index 0000000000..63533f9473
--- /dev/null
+++ b/language/chinese/CJK/cjk-4.8.5/utils/subfonts/vertref.pe
@@ -0,0 +1,121 @@
+# Generate a font with glyphs which have vertical glyph representations (but
+# don't include the vertical glyph representations itself). This is used by
+# the perl script `makefdx.pl' to create an FDX file as used by the CJK
+# package for LaTeX.
+#
+# The font is created in the current directory.
+#
+# $1: The master font (e.g., `bsmi00lp.ttf').
+# $2: The name of the target font (e.g., `bsmilpvr').
+
+# Copyright (C) 1994-2007 Werner Lemberg <wl@gnu.org>
+#
+# 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 in doc/COPYING; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301 USA
+
+if (Strtol($version) < 20071105)
+ Print("Can't use FontForge version before 2007-11-05. Aborting.";
+ Quit(1);
+endif;
+
+if ($argc != 3)
+ Print("usage: [fontforge -script] ", $0, " master-font fontname");
+ Quit(1);
+endif;
+
+Print("Loading ", $1, "...");
+Open($1);
+
+fontname = $2;
+fullname = $fullname + " vertical reference";
+copyright = $copyright \
+ + Chr(10) + Chr(10) \
+ + "Vertical glyph reference font version " \
+ + Strftime("%F", 1, "C") \
+ + ".";
+SetFontNames(fontname, "", fullname, "", copyright, "");
+
+lookups = GetLookups("GSUB");
+
+i = 0;
+result = -1;
+while (i < SizeOf(lookups))
+ if (Strstr(lookups[i], "'vert'") >= 0)
+ result = i;
+ endif;
+ i++;
+endloop;
+
+if (result == -1)
+ Print("This font doesn't contain a GSUB table with a `vert' feature.");
+ Quit(1);
+endif;
+
+subtables = GetLookupSubtables(lookups[result]);
+
+i = 0;
+result = -1;
+while (i < SizeOf(subtables))
+ if (Strstr(subtables[i], "'vert'") >= 0)
+ result = i;
+ endif;
+ i++;
+endloop;
+
+SelectByPosSub(subtables[result], 1);
+
+SelectInvert();
+DetachAndRemoveGlyphs();
+
+Print("Ensure third order curves...");
+SetFontOrder(3);
+
+Print("Scaling to PostScript units...");
+ScaleToEm(900, 100);
+
+num_chars = CharCnt();
+count = 0;
+delta = 100;
+
+while (count + delta < num_chars)
+ Print(count, "/", num_chars - 1, ":");
+ Select(count, count + delta);
+
+ Print(" Add extrema...");
+ AddExtrema();
+
+ Print(" Simplifying outlines...");
+ Simplify(0, 2);
+
+ count += delta;
+endloop;
+
+Print(count, "/", num_chars - 1, ":");
+Select(count, num_chars - 1);
+
+Print(" Add extrema...");
+AddExtrema();
+
+Print(" Simplifying outlines...");
+Simplify(0, 2);
+
+Reencode("original");
+
+# generate AFM and TFM files, no PS hints, and rounded PS coordinates
+Print("Generating font...");
+Generate($2 + ".pfb", "", \
+ 0x1 | 0x100 | 0x10000 | 0x80000 | 0x200000);
+
+Quit(0);