texlive[45357] trunk: jfmutil (20sep17)

commits+karl at tug.org commits+karl at tug.org
Thu Sep 21 00:36:51 CEST 2017


Revision: 45357
          http://tug.org/svn/texlive?view=revision&revision=45357
Author:   karl
Date:     2017-09-21 00:36:51 +0200 (Thu, 21 Sep 2017)
Log Message:
-----------
jfmutil (20sep17)

Modified Paths:
--------------
    trunk/Build/source/texk/texlive/linked_scripts/jfmutil/jfmutil.pl
    trunk/Master/texmf-dist/doc/fonts/jfmutil/README-ja.md
    trunk/Master/texmf-dist/doc/fonts/jfmutil/README.md
    trunk/Master/texmf-dist/scripts/jfmutil/jfmutil.pl

Modified: trunk/Build/source/texk/texlive/linked_scripts/jfmutil/jfmutil.pl
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/jfmutil/jfmutil.pl	2017-09-20 22:36:37 UTC (rev 45356)
+++ trunk/Build/source/texk/texlive/linked_scripts/jfmutil/jfmutil.pl	2017-09-20 22:36:51 UTC (rev 45357)
@@ -2770,8 +2770,8 @@
 #================================================= BEGIN
 use Encode qw(encode decode);
 my $prog_name = 'jfmutil';
-my $version = '1.0.1';
-my $mod_date = '2017/07/21';
+my $version = '1.1.0';
+my $mod_date = '2017/09/16';
 #use Data::Dump 'dump';
 #
 my ($sw_hex, $sw_uptool, $sw_noencout, $inenc, $exenc);
@@ -2860,9 +2860,13 @@
 }
 
 sub show_usage {
-  my ($v, $m) = @_;
+  print(usage_message());
+  exit;
+}
+sub usage_message {
+  my ($v, $m);
   ($v, $m) = textool_version() or error();
-  print <<"END"; exit;
+  return <<"END";
 This is $prog_name v$version <$mod_date> by 'ZR'.
 [ZRTeXtor library v$v <$m> by 'ZR']
 Usage: $prog_name vf2zvp0 [<options>] <in.vf> [<out.zvp0>]
@@ -2871,7 +2875,11 @@
        $prog_name zvp2vf [<options>] <in.zvp> [<out.vf> <out.tfm>]
        $prog_name zpl2tfm [<options>] <in.zvp0> [<out.vf>]
        $prog_name tfm2zpl [<options>] <in.zvp0> [<out.vf>]
-  VF and TFM files are searched by kpsewhich.
+Arguments:
+  <in.xxx>        input files
+    N.B. Input TFM/VF files are searched by Kpathsea. (ZVP/ZVP9 are not.)
+  <out.xxx>       output files
+Options:
        --hex      output charcode in 'H' form [default]
   -o / --octal    output charcode in 'O' form
   --uptool        use upTeX tools (uppltotf etc.)
@@ -2981,6 +2989,156 @@
 
 #================================================= END
 
+#------------------------------------------------- pxcopyfont interfaces
+
+*usage_message_org = \&usage_message;
+
+*usage_message = sub {
+  local $_ = usage_message_org();
+  my ($part1, $part2) = (<<"EOT1", <<"EOT2");
+
+* ZVP Conversion
+EOT1
+
+* VF Replication
+Usage: $prog_name vfcopy [<options>] <in.vf> <out.zvf> <out_base.tfm>...
+       $prog_name vfinfo [<options>] <in.vf>
+Arguments:
+  <in.vf>       input virtual font name
+    N.B. Input TFM/VF files are searched by Kpathsea.
+  <out.vf>      output virtual font name
+  <out_base.tfm>  names of raw TFMs referred by the output virtual font;
+                each entry replaces a font mapping in the input font in
+                the given order, so the exactly same number of entries
+                must be given as font mappings
+Options:
+  -z / --zero     change first fontmap id in vf to zero
+EOT2
+  s/(Usage:)/$part1$1/; s/$/$part2/;
+  return $_;
+};
+
+%procs = (%procs,
+  vfinfo  => \&main_vfinfo,
+  vfcopy  => \&main_vfcopy,
+);
+
+sub main_vfinfo {
+  PXCopyFont::read_option(1);
+  PXCopyFont::info_vf();
+}
+
+sub main_vfcopy {
+  PXCopyFont::read_option(0);
+  PXCopyFont::copy_vf();
+}
+
+#------------------------------------------------- pxcopyfont stuffs
+package PXCopyFont;
+
+*info = *main::show_info;
+*error = *main::error;
+
+our ($src_main, $dst_main, @dst_base, $op_zero);
+
+sub copy_vf {
+  local $_ = main::read_whole_file(main::kpse("$src_main.vf"), 1) or error();
+  my $vfc = parse_vf($_);
+  my ($nb, $nb1) = (scalar(@{$vfc->[0]}), scalar(@dst_base));
+  info("number of base TFMs in '$src_main'", $nb);
+  if ($dst_base[-1] eq '...' && $nb1 <= $nb) {
+    foreach ($nb1-1 .. $nb-1) { $dst_base[$_] = $vfc->[0][$_][1]; }
+  } elsif ($nb != $nb1) {
+    error("wrong number of base TFMs given", $nb1);
+  }
+  main::write_whole_file("$dst_main.vf", form_vf($vfc), 1) or error();
+  main::write_whole_file("$dst_main.tfm",
+      main::read_whole_file(main::kpse("$src_main.tfm"), 1), 1) or error();
+  foreach my $k (0 .. $#dst_base) {
+    my $sfn = $vfc->[0][$k][1]; my $dfn = $dst_base[$k];
+    ($sfn ne $dfn) or next;
+    main::write_whole_file("$dfn.tfm",
+      main::read_whole_file(main::kpse("$sfn.tfm"), 1), 1) or error();
+  }
+}
+
+sub parse_vf {
+  my ($vf) = @_; my (@fs, @lst, $pos);
+  @fs = unpack("CCC", $vf);
+  ($fs[0] == 0xf7 && $fs[1] == 0xca) or return;
+  $pos = $fs[2] + 11; my $hd = substr($vf, 0, $pos);
+  while (1) {
+    @fs = unpack("CC", substr($vf, $pos, 2));
+    (243 <= $fs[0] && $fs[0] <= 246) or last;
+    my $fid = ($fs[0] == 243) ? $fs[1] : 999;
+    my $t = $fs[0] - 242 + 13;
+    @fs = unpack("a${t}CC", substr($vf, $pos, 260));
+    my $l = $fs[1] + $fs[2]; my $n = substr($vf, $pos + $t + 2, $l);
+    $pos += $t + 2 + $l; push(@lst, [ $fs[0], $n, $fid ]);
+    if ($n !~ m/^[\x21-\x7e]+$/) {
+      $n =~ s/([^\x21-\x5b\x5d-\x7e])/sprintf("\\x%02x", ord($1))/g;
+      error("bad tfm name recorded in VF", $n);
+    }
+  }
+  my $ft = substr($vf, $pos); $ft =~ s/\xf8+\z//g;
+  return [ \@lst, $hd, $ft ];
+}
+
+sub info_vf {
+  local $_ = main::read_whole_file(main::kpse("$src_main.vf"), 1) or error();
+  my $vfc = parse_vf($_);
+  foreach (@{$vfc->[0]}) {
+    printf("%d=%s\n", $_->[2], $_->[1]);
+  }
+}
+
+sub form_vf {
+  my ($vfc) = @_; my (@lst);
+  if ($op_zero) {{
+    my $t = $vfc->[0][0] or last;
+    ($t->[2] == 0) and last; # already zero
+    info("change first fontmap id to zero (from " . $t->[2] . ")");
+    substr($t->[0], 1, 1) = "\0"; $t->[2] = 0;
+  }}
+  foreach my $k (0 .. $#{$vfc->[0]}) {
+    my $t = $vfc->[0][$k]; my $sfn = $t->[1];
+    my $dfn = $dst_base[$k];
+    (length($dfn) < 256) or error("TFM name too long", $dfn);
+    info("id=".$t->[2], $sfn, $dfn);
+    push(@lst, $t->[0], "\0" . chr(length($dfn)), $dfn);
+  }
+  my $tfm = join('', $vfc->[1], @lst, $vfc->[2]);
+  return $tfm . ("\xf8" x (4 - length($tfm) % 4));
+}
+
+sub read_option {
+  my ($op_info) = @_;
+  $op_zero = 0;
+  while ($ARGV[0] =~ m/^-/) {
+    my $opt = shift(@ARGV);
+    if ($opt =~ m/--?h(elp)?/) {
+      show_usage();
+    } elsif ($opt eq '-z' || $opt eq '--zero') {
+      $op_zero = 1;
+    } else {
+      error("invalid option", $opt);
+    }
+  }
+  ($src_main, $dst_main, @dst_base) = @ARGV;
+  $src_main =~ s/\.vf$//;
+  (defined $src_main) or error("no argument given");
+  (!!$op_info == (!defined $dst_main))
+    or error("wrong number of arguments");
+  if (defined $dst_main) {
+    $dst_main =~ s/\.vf$//;
+    foreach (@dst_base) { s/\.tfm$//; }
+    ($src_main ne $dst_main)
+      or error("output vf name is same as input");
+    (@dst_base) or error("no base tfm name given");
+  }
+}
+
 #------------------------------------------------- go to main
+package main;
 main();
 ## EOF

Modified: trunk/Master/texmf-dist/doc/fonts/jfmutil/README-ja.md
===================================================================
--- trunk/Master/texmf-dist/doc/fonts/jfmutil/README-ja.md	2017-09-20 22:36:37 UTC (rev 45356)
+++ trunk/Master/texmf-dist/doc/fonts/jfmutil/README-ja.md	2017-09-20 22:36:51 UTC (rev 45357)
@@ -13,6 +13,8 @@
     ことが期待できる。
   - ZVP 中の VF に直接対応する部分を抜き出した「ZVP0 形式」と VF (和文/
     欧文)との間の相互変換。
+  - 仮想フォントの別名での複製。この場合、VF 中に記録された参照 TFM 名も
+    適切に変更される。
 
 ### 前提環境
 
@@ -21,13 +23,30 @@
       - kpsewhich
       - pltotf, tftopl
 
+### 参考サイト
+
+  - PXutil パッケージ  
+    En toi Pythmeni tes TeXnopoleos ~電脳世界の奥底にて~  
+    <http://zrbabbler.sp.land.to/pxutil.html>  
+    pxutil を用いた和文仮想フォントの改変の方法について解説されている。
+    jfmutil は pxutil の上位互換なので、この記事の内容は単にコマンド名を
+    `pxutil` から `jfmutil` に変えることでそのまま通用する。
+
+  - PXcopyfont パッケージ  
+    En toi Pythmeni tes TeXnopoleos ~電脳世界の奥底にて~  
+    <http://zrbabbler.sp.land.to/pxcopyfont.html>  
+    pxcopyfont を用いた仮想フォントの複製の方法について解説されている。
+    pxcopyfont と jfmutil の関係については後述。
+
 ### pxutil との関係
 
-jfmutil の機能は pxutil と等価である。pxutil の動作のためには ZRTeXtor
-モジュールを別途インストールする必要があった。CTAN に登録するにあたって
-単体で動作するプログラムの方がよいと考え、pxutil に ZRTeXtor のコードの
-一部を併合したものがこの jfmutil である。
+jfmutil の ZVP 関連の機能は [pxutil] と等価である。pxutil の動作のためには
+ZRTeXtor モジュールを別途インストールする必要があった。CTAN に登録するに
+あたって単体で動作するプログラムの方がよいと考え、pxutil に ZRTeXtor の
+コードの一部を併合したものが当初の jfmutil である。
 
+[pxutil]: https://github.com/zr-tex8r/PXutil
+
 jfmutil と pxutil の相違点は次のとおりである:
 
   - jfmutil は ZRTeXtor の設定ファイル(`ZRTeXtor.cfg`)を参照しない。
@@ -37,13 +56,62 @@
   - なお、ZRTeXtor の 1.4.0 版より、設定項目 `tftopl`/`pltotf` の既定値は
     `ptftopl`/`ppltotf` となっている。
 
+### pxcopyfont との関係
+
+jfmutil の仮想フォント複製の機能は [pxcopyfont] から移植したものである。
+
+  - `jfmutil vfinfo in[.vf]`(VF ファイルの情報出力)は  
+    `pxcopyfont in` と情報を出力する。ただし出力形式は両者で異なる。
+  - `jfmutil vfcopy in[.vf] out[.vf] base[.tfm]...`(VF 複製)は  
+    `pxcopyfont in out base...` と等価である。
+
 ### ライセンス
 
 MIT ライセンス
 
-機能解説
---------
 
+機能解説:VF 複製
+-----------------
+
+仮想フォント(VF と TFM の組)のファイルを別の名前でコピーする。一般に、
+VF ファイルの中には参照する TFM の名前が記録されているが、コピーの際には
+この TFM 名はコピー先ものに変更される。(従って、VF ファイルについては、
+コピー元とコピー先はバイナリ同一にはならない。)
+
+### 使用法
+
+    jfmutil vfcopy [<オプション>] <入力.vf> <出力.vf> <出力.tfm>...
+    jfmutil vfinfo [<オプション>] <入力.vf>
+
+※既定の拡張子は省略可能。
+
+`vfinfo` サブコマンドは `入力.vf` の参照 TFM の情報を出力する。例えば、
+upTeX 標準の `upjpnrm-h.vf` の場合、以下の出力になる:
+
+    0=uprml-h
+    2=upjisr-hq
+
+`vfcopy` サブコマンドは `入力.vf` とそれが参照する TFM 群の組を、
+`出力.vf` とその後の引数で指定した TFM 群にコピーする。例えば
+
+    jfmutil vfcopy upjpnrm-h myjpnrm-h myrml-h myjisr-hq
+
+は以下の動作を行う:
+
+  - `upjpnrm-h.vf` を `myjpnrm-h.vf` に改変付でコピーする。
+  - `uprml-h.tfm` を `myrml-h.tfm` にコピーする。
+  - `upjisr-hq.tfm` を `myjisr-hq.tfm` にコピーする。
+
+引数中の出力 TFM ファイル名の列は途中に `...` を書いて以降を省略できる。
+この場合、対応する入力 TFM ファイル(入力 VF に記録されたもの)と同じ名前
+が使われる。
+
+※TFM について入力と出力の名前が同じ場合は、ファイルのコピーは行わない。
+
+
+機能解説:ZVP 変換
+------------------
+
 ### TeX のフォントファイルの形式
 
 <pre>
@@ -392,6 +460,9 @@
 更新履歴
 --------
 
+  * Version 1.1.0 〈2017/09/16〉
+      - pxcopyfont 由来の機能(`vfinfo`、`vfcopy` サブコマンド)を追加。
+
   * Version 1.0.1 〈2017/07/21〉
       - shebang 行を追加。
 

Modified: trunk/Master/texmf-dist/doc/fonts/jfmutil/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/fonts/jfmutil/README.md	2017-09-20 22:36:37 UTC (rev 45356)
+++ trunk/Master/texmf-dist/doc/fonts/jfmutil/README.md	2017-09-20 22:36:51 UTC (rev 45357)
@@ -13,6 +13,8 @@
     as counterpart to vftovp/vptovf programs.
   - The mutual conversion between VF files alone and files in the “ZVP0
     format”, which is a subset of the ZVP format.
+  - The replication of virtual fonts with different names, where the
+    referred TFM names in the VF will be suitably revised.
 
 ### SYSTEM REQUIREMENTS
 
@@ -29,6 +31,8 @@
 
     This is jfmutil v1.x.x <2017/xx/xx> by 'ZR'.
     [ZRTeXtor library v1.x.x <2017/xx/xx> by 'ZR']
+
+    * ZVP Conversion
     Usage: jfmutil vf2zvp0 [<options>] <in.vf> [<out.zvp0>]
            jfmutil zvp02vf [<options>] <in.zvp0> [<out.vf>]
            jfmutil vf2zvp [<options>] <in.vf> [<in.tfm> <out.zvp>]
@@ -35,7 +39,11 @@
            jfmutil zvp2vf [<options>] <in.zvp> [<out.vf> <out.tfm>]
            jfmutil zpl2tfm [<options>] <in.zvp0> [<out.vf>]
            jfmutil tfm2zpl [<options>] <in.zvp0> [<out.vf>]
-      VF and TFM files are searched by kpsewhich.
+    Arguments:
+      <in.xxx>        input files
+        N.B. Input TFM/VF files are searched by Kpathsea. (ZVP/ZVP9 are not.)
+      <out.xxx>       output files
+    Options:
            --hex      output charcode in 'H' form [default]
       -o / --octal    output charcode in 'O' form
       --uptool        use upTeX tools (uppltotf etc.)
@@ -45,12 +53,29 @@
       -j / --jis      == --kanji=jis --kanji-internal=jis
       -u / --unicode  == --kanji=utf8 --kanji-internal=unicode
       -E / --no-encoding == --kanji=none --kanji-internal=none
+    * VF Replication
+    Usage: jfmutil vfcopy [<options>] <in.vf> <out.zvf> <out_base.tfm>...
+           jfmutil vfinfo [<options>] <in.vf>
+    Arguments:
+      <in.vf>       input virtual font name
+        N.B. Input TFM/VF files are searched by Kpathsea.
+      <out.vf>      output virtual font name
+      <out_base.tfm>  names of raw TFMs referred by the output virtual font;
+                    each entry replaces a font mapping in the input font in
+                    the given order, so the exactly same number of entries
+                    must be given as font mappings
+    Options:
+      -z / --zero     change first fontmap id in vf to zero
 
+
 Please refer to README-ja.md (in Japanese) for detail.
 
 Revision History
 ----------------
 
+  * Version 1.1.0 〈2017/09/16〉
+      - Add subcommands `vfinfo` and `vfcopy`.
+
   * Version 1.0.1 〈2017/07/21〉
       - Add shebang line.
 

Modified: trunk/Master/texmf-dist/scripts/jfmutil/jfmutil.pl
===================================================================
--- trunk/Master/texmf-dist/scripts/jfmutil/jfmutil.pl	2017-09-20 22:36:37 UTC (rev 45356)
+++ trunk/Master/texmf-dist/scripts/jfmutil/jfmutil.pl	2017-09-20 22:36:51 UTC (rev 45357)
@@ -2770,8 +2770,8 @@
 #================================================= BEGIN
 use Encode qw(encode decode);
 my $prog_name = 'jfmutil';
-my $version = '1.0.1';
-my $mod_date = '2017/07/21';
+my $version = '1.1.0';
+my $mod_date = '2017/09/16';
 #use Data::Dump 'dump';
 #
 my ($sw_hex, $sw_uptool, $sw_noencout, $inenc, $exenc);
@@ -2860,9 +2860,13 @@
 }
 
 sub show_usage {
-  my ($v, $m) = @_;
+  print(usage_message());
+  exit;
+}
+sub usage_message {
+  my ($v, $m);
   ($v, $m) = textool_version() or error();
-  print <<"END"; exit;
+  return <<"END";
 This is $prog_name v$version <$mod_date> by 'ZR'.
 [ZRTeXtor library v$v <$m> by 'ZR']
 Usage: $prog_name vf2zvp0 [<options>] <in.vf> [<out.zvp0>]
@@ -2871,7 +2875,11 @@
        $prog_name zvp2vf [<options>] <in.zvp> [<out.vf> <out.tfm>]
        $prog_name zpl2tfm [<options>] <in.zvp0> [<out.vf>]
        $prog_name tfm2zpl [<options>] <in.zvp0> [<out.vf>]
-  VF and TFM files are searched by kpsewhich.
+Arguments:
+  <in.xxx>        input files
+    N.B. Input TFM/VF files are searched by Kpathsea. (ZVP/ZVP9 are not.)
+  <out.xxx>       output files
+Options:
        --hex      output charcode in 'H' form [default]
   -o / --octal    output charcode in 'O' form
   --uptool        use upTeX tools (uppltotf etc.)
@@ -2981,6 +2989,156 @@
 
 #================================================= END
 
+#------------------------------------------------- pxcopyfont interfaces
+
+*usage_message_org = \&usage_message;
+
+*usage_message = sub {
+  local $_ = usage_message_org();
+  my ($part1, $part2) = (<<"EOT1", <<"EOT2");
+
+* ZVP Conversion
+EOT1
+
+* VF Replication
+Usage: $prog_name vfcopy [<options>] <in.vf> <out.zvf> <out_base.tfm>...
+       $prog_name vfinfo [<options>] <in.vf>
+Arguments:
+  <in.vf>       input virtual font name
+    N.B. Input TFM/VF files are searched by Kpathsea.
+  <out.vf>      output virtual font name
+  <out_base.tfm>  names of raw TFMs referred by the output virtual font;
+                each entry replaces a font mapping in the input font in
+                the given order, so the exactly same number of entries
+                must be given as font mappings
+Options:
+  -z / --zero     change first fontmap id in vf to zero
+EOT2
+  s/(Usage:)/$part1$1/; s/$/$part2/;
+  return $_;
+};
+
+%procs = (%procs,
+  vfinfo  => \&main_vfinfo,
+  vfcopy  => \&main_vfcopy,
+);
+
+sub main_vfinfo {
+  PXCopyFont::read_option(1);
+  PXCopyFont::info_vf();
+}
+
+sub main_vfcopy {
+  PXCopyFont::read_option(0);
+  PXCopyFont::copy_vf();
+}
+
+#------------------------------------------------- pxcopyfont stuffs
+package PXCopyFont;
+
+*info = *main::show_info;
+*error = *main::error;
+
+our ($src_main, $dst_main, @dst_base, $op_zero);
+
+sub copy_vf {
+  local $_ = main::read_whole_file(main::kpse("$src_main.vf"), 1) or error();
+  my $vfc = parse_vf($_);
+  my ($nb, $nb1) = (scalar(@{$vfc->[0]}), scalar(@dst_base));
+  info("number of base TFMs in '$src_main'", $nb);
+  if ($dst_base[-1] eq '...' && $nb1 <= $nb) {
+    foreach ($nb1-1 .. $nb-1) { $dst_base[$_] = $vfc->[0][$_][1]; }
+  } elsif ($nb != $nb1) {
+    error("wrong number of base TFMs given", $nb1);
+  }
+  main::write_whole_file("$dst_main.vf", form_vf($vfc), 1) or error();
+  main::write_whole_file("$dst_main.tfm",
+      main::read_whole_file(main::kpse("$src_main.tfm"), 1), 1) or error();
+  foreach my $k (0 .. $#dst_base) {
+    my $sfn = $vfc->[0][$k][1]; my $dfn = $dst_base[$k];
+    ($sfn ne $dfn) or next;
+    main::write_whole_file("$dfn.tfm",
+      main::read_whole_file(main::kpse("$sfn.tfm"), 1), 1) or error();
+  }
+}
+
+sub parse_vf {
+  my ($vf) = @_; my (@fs, @lst, $pos);
+  @fs = unpack("CCC", $vf);
+  ($fs[0] == 0xf7 && $fs[1] == 0xca) or return;
+  $pos = $fs[2] + 11; my $hd = substr($vf, 0, $pos);
+  while (1) {
+    @fs = unpack("CC", substr($vf, $pos, 2));
+    (243 <= $fs[0] && $fs[0] <= 246) or last;
+    my $fid = ($fs[0] == 243) ? $fs[1] : 999;
+    my $t = $fs[0] - 242 + 13;
+    @fs = unpack("a${t}CC", substr($vf, $pos, 260));
+    my $l = $fs[1] + $fs[2]; my $n = substr($vf, $pos + $t + 2, $l);
+    $pos += $t + 2 + $l; push(@lst, [ $fs[0], $n, $fid ]);
+    if ($n !~ m/^[\x21-\x7e]+$/) {
+      $n =~ s/([^\x21-\x5b\x5d-\x7e])/sprintf("\\x%02x", ord($1))/g;
+      error("bad tfm name recorded in VF", $n);
+    }
+  }
+  my $ft = substr($vf, $pos); $ft =~ s/\xf8+\z//g;
+  return [ \@lst, $hd, $ft ];
+}
+
+sub info_vf {
+  local $_ = main::read_whole_file(main::kpse("$src_main.vf"), 1) or error();
+  my $vfc = parse_vf($_);
+  foreach (@{$vfc->[0]}) {
+    printf("%d=%s\n", $_->[2], $_->[1]);
+  }
+}
+
+sub form_vf {
+  my ($vfc) = @_; my (@lst);
+  if ($op_zero) {{
+    my $t = $vfc->[0][0] or last;
+    ($t->[2] == 0) and last; # already zero
+    info("change first fontmap id to zero (from " . $t->[2] . ")");
+    substr($t->[0], 1, 1) = "\0"; $t->[2] = 0;
+  }}
+  foreach my $k (0 .. $#{$vfc->[0]}) {
+    my $t = $vfc->[0][$k]; my $sfn = $t->[1];
+    my $dfn = $dst_base[$k];
+    (length($dfn) < 256) or error("TFM name too long", $dfn);
+    info("id=".$t->[2], $sfn, $dfn);
+    push(@lst, $t->[0], "\0" . chr(length($dfn)), $dfn);
+  }
+  my $tfm = join('', $vfc->[1], @lst, $vfc->[2]);
+  return $tfm . ("\xf8" x (4 - length($tfm) % 4));
+}
+
+sub read_option {
+  my ($op_info) = @_;
+  $op_zero = 0;
+  while ($ARGV[0] =~ m/^-/) {
+    my $opt = shift(@ARGV);
+    if ($opt =~ m/--?h(elp)?/) {
+      show_usage();
+    } elsif ($opt eq '-z' || $opt eq '--zero') {
+      $op_zero = 1;
+    } else {
+      error("invalid option", $opt);
+    }
+  }
+  ($src_main, $dst_main, @dst_base) = @ARGV;
+  $src_main =~ s/\.vf$//;
+  (defined $src_main) or error("no argument given");
+  (!!$op_info == (!defined $dst_main))
+    or error("wrong number of arguments");
+  if (defined $dst_main) {
+    $dst_main =~ s/\.vf$//;
+    foreach (@dst_base) { s/\.tfm$//; }
+    ($src_main ne $dst_main)
+      or error("output vf name is same as input");
+    (@dst_base) or error("no base tfm name given");
+  }
+}
+
 #------------------------------------------------- go to main
+package main;
 main();
 ## EOF



More information about the tex-live-commits mailing list