#! /usr/bin/perl -w # # Copyright (C) 1994-2021 Werner Lemberg # # 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 # This script creates virtual subfonts in Unicode encoding for Wadalab # subfonts. It can merge a JIS X 0208 and JIS X 0212 family into a single # set of Unicode subfonts. # # As prerequisites, it needs the files `JIS0208.TXT' and `JIS0212.TXT' from # the `OBSOLETE' directory in the `MAPPINGS' tree on ftp.unicode.org. It # also needs the file `DNP.sfd' which gives the relationship between JIS X # 0208 (and JIS X 0212) in EUC encoding and wadalab's DNP font encoding. # The program `vptovf' must be available (and in the path). # # Call the script as # # perl makeuniwada.pl namestem1 [namestem2] uni_namestem # # `namestem1' is the font in JIS X 0208 encoding. The optional `namestem2' # argument is the font in JIS X 0212, and `uni_namestem' holds the prefix # for the Unicode subfonts. `makeuniwada.pl' reads all AFM files from the # given wadalab font families. # # Example: # # perl makeuniwada.pl dmj mc2j udmj # # This call mixes the mincho-0-12 (dmj) with mincho-1-8 (mc2j) families. use strict; my $prog = $0; $prog =~ s@.*/@@; if ($#ARGV < 1 || $#ARGV > 2) { die("usage: $prog namestem1 [namestem2] uni_namestem\n"); } my $namestem1; my $namestem2; my $two_encodings = 0; my @args = @ARGV; $namestem1 = $ARGV[0]; if ($#ARGV == 2) { $namestem2 = $ARGV[1]; $two_encodings = 1; shift; } my $uninamestem = $ARGV[1]; # Read `DNP.sfd'. my %sfd; my @subfonts; read_sfdfile("DNP.sfd", \%sfd, \@subfonts); # Read encoding files. # # The files `JIS0208.TXT' and `JIS0212.TXT' are from the `OBSOLETE' # directory in the `MAPPINGS' tree on ftp.unicode.org. my %jisx0208; my %jisx0212; read_encfile("JIS0208.TXT", \%jisx0208, 1); if ($two_encodings) { read_encfile("JIS0212.TXT", \%jisx0212, 0); } # Read AFM files. my @unicode; foreach my $sub (@subfonts) { my $afmname = "$namestem1$sub.afm"; if (-f $afmname) { read_afmfile($afmname, \@unicode, \%sfd, \%jisx0208, $sub); } } if ($two_encodings) { foreach my $sub (@subfonts) { my $afmname = "$namestem2$sub.afm"; if (-f $afmname) { read_afmfile($afmname, \@unicode, \%sfd, \%jisx0212, $sub); } } } # Write VPL files. my $index = 0; foreach my $i (0 .. 255) { my @entries; foreach my $j (0 .. 255) { if (defined ($unicode[$index])) { push(@entries, "$j $unicode[$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 hash key 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"); # This loop doesn't handle the complete syntax of SFD files yet. while () { chop; my @field = split(" "); next if ($#field < 0); next if ($field[0] =~ /^#/); my $suffix = $field[0]; push(@{$sfdarray}, $suffix); shift(@field); my $index = 0; while (@field) { if ($field[0] =~ /(.*):$/) { $index = $1; } elsif ($field[0] =~ /(0x[0-9A-Fa-f]+)_(0x[0-9A-Fa-f]+)/) { foreach my $i (hex($1) .. hex($2)) { $sfdhash->{"$suffix $index"} = $i; $index++; } } shift(@field); } } close(SFD); } # Read encoding file. # # $1: Name of the encoding file. # $2: Reference to the target hash file, mapping from the charset # to Unicode. # $3: Set to 1 if the needed mapping data is not in field 1 and 2, but in # field 2 and 3. sub read_encfile { my ($encfile, $enchash, $doshift) = @_; print("Reading encoding file \`$encfile'...\n"); open(ENC, $encfile) || die("$prog: can't open \`$encfile': $!\n"); while () { chop; my @field = split(" "); next if ($#field < 0); next if ($field[0] =~ /^#/); if ($doshift) { shift(@field); } my $unicode = $field[1]; $unicode =~ s/0x//; my $value = hex($field[0]) + 0x8080; $enchash->{$value} = hex($unicode); } close(ENC); } # Read AFM file. # # $1: Name of the AFM file. # $2: Reference to the target array which maps from Unicode to the string # " ". # $3: Reference to the SFD hash (as extracted by `read_sfdfile'). # $4: Reference to the encoding hash (as extracted by `read_encfile'). # $5: Suffix. sub read_afmfile { my ($afmfile, $unicarray, $sfdhash, $enchash, $suffix) = @_; print("Reading metric file \`$afmfile'...\n"); open(AFM, $afmfile) || die("$prog: can't open \`$afmfile': $!\n"); $afmfile =~ s/\.[^.]*$//; while () { if (/^C (\d+) ;/) { my $key = "$suffix $1"; my $value = $sfdhash->{$key}; my $unicvalue = $enchash->{$value}; my $s = "$afmfile $1"; # Add advance width. / WX (.*?) ;/; $s .= " $1"; # Add glyph height and depth. / B .*? (.*?) .*? (.*?) ;/; $s .= " $1 $2"; $unicarray->[$unicvalue] = $s; } } close(AFM); } # Write VPL file. # # $1: Name of the VPL file. # $2: Reference to list which holds the font entries. An entry has the # form ` '. sub write_vplfile { my ($vplfile, $glypharray) = @_; my %subfonts; my $subcount = 0; foreach my $entry (@{$glypharray}) { 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(" ", @args) . "')\n"); print("(FAMILY TEX-\U$uninamestem\E)\n"); print("(CODINGSCHEME DNPUNICODE)\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 $subfont)\n"); print(" )\n"); } foreach my $entry (@{$glypharray}) { my @field = split(" ", $entry); my $index = $field[0]; my $subnumber = $subfonts{$field[1]}; my $subindex = $field[2]; my $adv_width = $field[3] / 1000.0; my $depth = $field[4] / -1000.0; my $height = $field[5] / 1000.0; print("(CHARACTER D $index\n"); print(" (CHARWD R $adv_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