読者です 読者をやめる 読者になる 読者になる

TeX Alchemist Online

TeX を使って化学のお仕事をしています。

(u)pTeX における和文多書体の実現 〜Sierraの全和文フォント出力を例として〜

f:id:doraTeX:20161204101316p:plain

この記事は TeX & LaTeX Advent Calendar 2016 の6日目の記事です。 2日目に続く今年2回目のエントリーとなります。 5日目はaminophenさんでした。 7日目もaminophenさんです。

前記事では,TeX Live 2016 の LuaTeX-ja を使って,Sierra の全和文フォントを同時出力する例を示しました

doratex.hatenablog.jp

また,前記事の最後には,「専用の tfm/vf を用意すれば (u)pTeX + dvipdfmx のワークフローでも Sierra の全和文フォントを同時出力できる」と述べました

本記事では,専用の tfm/vf を用意して (u)pTeX で和文多書体を実現するための具体的な手順を説明します。 この手順は,Macユーザでなくても,(u)pTeX で和文多書体を実現したいと考える人に参考になるでしょう。

さらに本記事の後半では,この方法を応用し,和文フォントを簡単に追加するためのパッケージ,そして Sierra の全和文フォントを一斉使用するためのパッケージを作成してゆきます。本記事で作成したパッケージを利用すれば,ライトユーザでも比較的手軽に (u)pTeX での和文多書体環境を実現することができるようになるはずです。

目次

準備

ZRさんの PXcopyfontパッケージ をダウンロードし,zipを展開して pxcopyfont.pl を取得します。

Mac 環境のデフォルト状態では,この pxcopyfont.pl を実行すると

Can't locate Data/Dump.pm in @INC

というエラーが出てしまいます。CPAN から Dump.pm をダウンロードして同じディレクトリに置いておくのが簡単でしょう。

手順の実例:クレー (Klee.ttc) の追加

例として,El Capitan から収録された クレー (Klee.ttc) のミディアム・デミボールドを (u)pTeX + dvipdfmx から使いたい場合を考えます。

前提

  • TeX Live のインストール・設定は済んでいる。
  • cjk-gs-integrate.pl を使うなどして,Klee.ttc へのシンボリックリンクが TEXMFLOCAL 内に作成済み。
  • otfinfo などによって,次の情報を得ているものとする。
    • Klee.ttc の ttc index 0番がデミボールド,1番がミディアム。
    • これらは Adobe-Japan1-4 の ROS (Registry, Ordering, Supplement) を持つフォントである。⇒ 通常の CMap ファイルが使用可能

準備:tfm/vf の複製

欧文フォントと異なり,和文フォントは基本的に正方形の仮想ボディを持っているため,既存のメトリック情報を流用できます。ここでは,jsarticle の既定のメトリックであるJISメトリック(pTeX では jis / jis-v,upTeX では upjisr-h / upjisr-v)を複製することにしましょう。(他にも,OTFパッケージに付属する nmlminr-h / upnmlminr-h のようなOTFメトリック,brsgnmlminr-h / upbrsgnmlminr-h のようなぶら下げ組OTFメトリックをベースとするという手もあります。)

では,pxcopyfont.pl を用いて pTeX および upTeX のJISメトリックを複製し,クレー用の tfm/vf を用意しましょう。ファミリー名 klee, シリーズ名はミディアム・デミボールドに応じて m/db で作成します。

## クレー ミディアム
# pTeX 横組用
$ perl pxcopyfont.pl -o jis klee-m-jy1 r-klee-m-jy1
# pTeX 縦組用 
$ perl pxcopyfont.pl -o jis-v klee-m-jt1 r-klee-m-jt1
# upTeX 横組用
$ perl pxcopyfont.pl -o upjisr-h klee-m-jy2 r-klee-m-jy2 r-klee-m-jy2x
# upTeX 縦組用
$ perl pxcopyfont.pl -o upjisr-v klee-m-jt2 r-klee-m-jt2

## クレー デミボールド
# pTeX 横組用
$ perl pxcopyfont.pl -o jis klee-db-jy1 r-klee-db-jy1
# pTeX 縦組用 
$ perl pxcopyfont.pl -o jis-v klee-db-jt1 r-klee-db-jt1
# upTeX 横組用
$ perl pxcopyfont.pl -o upjisr-h klee-db-jy2 r-klee-db-jy2 r-klee-db-jy2x
# upTeX 縦組用
$ perl pxcopyfont.pl -o upjisr-v klee-db-jt2 r-klee-db-jt2

これにより,次の tfm/vf が生成されます:

klee-m-jy1.vf
klee-m-jy1.tfm
r-klee-m-jy1.tfm

klee-m-jt1.vf
klee-m-jt1.tfm
r-klee-m-jt1.tfm

klee-m-jy2.vf
klee-m-jy2.tfm
r-klee-m-jy2.tfm
r-klee-m-jy2x.tfm

klee-m-jt2.vf
klee-m-jt2.tfm
r-klee-m-jt2.tfm

klee-db-jy1.vf
klee-db-jy1.tfm
r-klee-db-jy1.tfm

klee-db-jt1.vf
klee-db-jt1.tfm
r-klee-db-jt1.tfm

klee-db-jy2.vf
klee-db-jy2.tfm
r-klee-db-jy2.tfm
r-klee-db-jy2x.tfm

klee-db-jt2.vf
klee-db-jt2.tfm
r-klee-db-jt2.tfm

(u)pLaTeX + dvipdfmx で使用するサンプルコード

次に,これらの tfm/vf をとりあえず同一ディレクトリに置いたままで,そのディレクトリに次のソースファイルを作成します。

pLaTeX 用サンプルコード

%#!platex
\documentclass{jsarticle}
\usepackage{plext}% 縦組用

%%% klee ファミリーに m と db のシリーズを定義
\DeclareFontFamily{JY1}{klee}{}
\DeclareFontFamily{JT1}{klee}{}

\DeclareFontShape{JY1}{klee}{m}{n}{<->s*[0.961000]klee-m-jy1}{}
\DeclareFontShape{JY1}{klee}{m}{it}{<->ssub*klee/m/n}{}
\DeclareFontShape{JY1}{klee}{m}{sl}{<->ssub*klee/m/n}{}
\DeclareFontShape{JY1}{klee}{m}{sc}{<->ssub*klee/m/n}{}

\DeclareFontShape{JT1}{klee}{m}{n}{<->s*[0.961000]klee-m-jt1}{}
\DeclareFontShape{JT1}{klee}{m}{it}{<->ssub*klee/m/n}{}
\DeclareFontShape{JT1}{klee}{m}{sl}{<->ssub*klee/m/n}{}
\DeclareFontShape{JT1}{klee}{m}{sc}{<->ssub*klee/m/n}{}

\DeclareFontShape{JY1}{klee}{db}{n}{<->s*[0.961000]klee-db-jy1}{}
\DeclareFontShape{JY1}{klee}{db}{it}{<->ssub*klee/db/n}{}
\DeclareFontShape{JY1}{klee}{db}{sl}{<->ssub*klee/db/n}{}
\DeclareFontShape{JY1}{klee}{db}{sc}{<->ssub*klee/db/n}{}

\DeclareFontShape{JT1}{klee}{db}{n}{<->s*[0.961000]klee-db-jt1}{}
\DeclareFontShape{JT1}{klee}{db}{it}{<->ssub*klee/db/n}{}
\DeclareFontShape{JT1}{klee}{db}{sl}{<->ssub*klee/db/n}{}
\DeclareFontShape{JT1}{klee}{db}{sc}{<->ssub*klee/db/n}{}

% dvipdfmx special の発行
\AtBeginDvi{%
  \special{pdf:mapline r-klee-m-jy1  2004-H :1:Klee.ttc}%
  \special{pdf:mapline r-klee-m-jt1  2004-V :1:Klee.ttc}%
  \special{pdf:mapline r-klee-db-jy1 2004-H :0:Klee.ttc}%
  \special{pdf:mapline r-klee-db-jt1 2004-V :0:Klee.ttc}%
}

\begin{document}
{\usekanji{JY1}{klee}{m}{n}クレーミディアムの横組サンプル、「約物の“テスト”」。}\par
{\usekanji{JY1}{klee}{db}{n}クレーデミボールドの横組サンプル、「約物の“テスト”」。}

\vspace{1cm}

\parbox<t>{22zw}{%
{\usekanji{JT1}{klee}{m}{n}クレーミディアムの縦組サンプル、「約物の“テスト”」。}\par
{\usekanji{JT1}{klee}{db}{n}クレーデミボールドの縦組サンプル、「約物の“テスト”」。}}
\end{document}

upLaTeX 用サンプルコード

%#!uplatex
\documentclass[uplatex]{jsarticle}
\usepackage{plext}% 縦組用

%%% klee ファミリーに m と db のシリーズを定義
\DeclareFontFamily{JY2}{klee}{}
\DeclareFontFamily{JT2}{klee}{}

\DeclareFontShape{JY2}{klee}{m}{n}{<->s*[0.924690]klee-m-jy2}{}
\DeclareFontShape{JY2}{klee}{m}{it}{<->ssub*klee/m/n}{}
\DeclareFontShape{JY2}{klee}{m}{sl}{<->ssub*klee/m/n}{}
\DeclareFontShape{JY2}{klee}{m}{sc}{<->ssub*klee/m/n}{}

\DeclareFontShape{JT2}{klee}{m}{n}{<->s*[0.924690]klee-m-jt2}{}
\DeclareFontShape{JT2}{klee}{m}{it}{<->ssub*klee/m/n}{}
\DeclareFontShape{JT2}{klee}{m}{sl}{<->ssub*klee/m/n}{}
\DeclareFontShape{JT2}{klee}{m}{sc}{<->ssub*klee/m/n}{}

\DeclareFontShape{JY2}{klee}{db}{n}{<->s*[0.924690]klee-db-jy2}{}
\DeclareFontShape{JY2}{klee}{db}{it}{<->ssub*klee/db/n}{}
\DeclareFontShape{JY2}{klee}{db}{sl}{<->ssub*klee/db/n}{}
\DeclareFontShape{JY2}{klee}{db}{sc}{<->ssub*klee/db/n}{}

\DeclareFontShape{JT2}{klee}{db}{n}{<->s*[0.924690]klee-db-jt2}{}
\DeclareFontShape{JT2}{klee}{db}{it}{<->ssub*klee/db/n}{}
\DeclareFontShape{JT2}{klee}{db}{sl}{<->ssub*klee/db/n}{}
\DeclareFontShape{JT2}{klee}{db}{sc}{<->ssub*klee/db/n}{}

% dvipdfmx special の発行
\AtBeginDvi{%
  \special{pdf:mapline r-klee-m-jy2   UniJIS2004-UTF16-H :1:Klee.ttc}%
  \special{pdf:mapline r-klee-m-jy2x  UniJIS-UCS2-H      :1:Klee.ttc}%
  \special{pdf:mapline r-klee-m-jt2   UniJIS2004-UTF16-V :1:Klee.ttc}%
  \special{pdf:mapline r-klee-db-jy2  UniJIS2004-UTF16-H :0:Klee.ttc}%
  \special{pdf:mapline r-klee-db-jy2x UniJIS-UCS2-H      :0:Klee.ttc}%
  \special{pdf:mapline r-klee-db-jt2  UniJIS2004-UTF16-V :0:Klee.ttc}%
}

\begin{document}
{\usekanji{JY2}{klee}{m}{n}クレーミディアムの横組サンプル、「約物の“テスト”」。}\par
{\usekanji{JY2}{klee}{db}{n}クレーデミボールドの横組サンプル、「約物の“テスト”」。}

\vspace{1cm}

\parbox<t>{22zw}{%
{\usekanji{JT2}{klee}{m}{n}クレーミディアムの縦組サンプル、「約物の〝テスト〟」。}\par
{\usekanji{JT2}{klee}{db}{n}クレーデミボールドの縦組サンプル、「約物の〝テスト〟」。}}
\end{document}

これらのサンプルコードを (u)pLaTeX でコンパイルし,dvipdfmx でPDF化して,クレーフォントが埋め込まれた次のようなPDFが生成されれば成功です。

f:id:doraTeX:20161204093253p:plain

dvipdfmx special

サンプルコード中の

\special{pdf:mapline r-klee-m-jy2 UniJIS2004-UTF16-H :1:Klee.ttc}

のような部分は,dvipdfmx に対するフォントマッピングの設定の指示をDVIファイルに書きこんでいます。r-klee-m-jy2.tfm によって出力する文字は,CMap file UniJIS2004-UTF16-H によって Unicode から CID に変換し,Klee.ttc の index 1 のフォント中の該当CIDのグリフを呼び出してPDFに埋め込め,という意味です。:1: の部分は,複数のフォントを束ねたコレクションであるTTC形式の中の index 1 のフォント(ここでは「クレー ミディアム」)を意味しています(TTC index は 0 始まりである点に注意)。TTF形式やOTF形式のフォントの場合には :1: にあたる部分は不要です。

このように,ソース中に dvipdfmx special を書き込むと,「このファイルをコンパイルするときに使うフォント設定」を柔軟に指定することができます。別途フォントマップファイルを用意して dvipdfmx のオプションを変更したりする必要がなくてお手軽です。

和文フォント追加の自動化

追加したい各和文フォントに対して上記手順を繰り返すことで,(u)pLaTeX で使用可能な和文フォントをどんどん追加してゆくことができます。しかし,上記手順やソースには冗長性が多く,もっと自動化できる点が多くあるはずです。

そこで,これを自動化したパッケージを作成してみましょう。

tfm/vf 複製の自動化シェルスクリプト

次のようなシェル関数を用意しておきます。

#!/bin/sh

function generateTFM() {
    FAMILY=$1
    SERIES=$2
    perl pxcopyfont.pl -o jis ${FAMILY}-${SERIES}-jy1 r-${FAMILY}-${SERIES}-jy1
    perl pxcopyfont.pl -o jis-v ${FAMILY}-${SERIES}-jt1 r-${FAMILY}-${SERIES}-jt1
    perl pxcopyfont.pl -o upjisr-h ${FAMILY}-${SERIES}-jy2 r-${FAMILY}-${SERIES}-jy2 r-${FAMILY}-${SERIES}-jy2x
    perl pxcopyfont.pl -o upjisr-v ${FAMILY}-${SERIES}-jt2 r-${FAMILY}-${SERIES}-jt2
}

すると,

$ generateTFM klee m
$ generateTFM klee db

とするだけで,上記の tfm/vf ファイルを得られます。

和文フォント追加の自動化パッケージ:addJFont.sty

次の addJFont.sty を作成します。

\NeedsTeXFormat{pLaTeX2e}
\ProvidesPackage{addJFont}[2016/12/06 v0.1 doraTeX]

\newif\ifaddJFont@uplatex \addJFont@uplatexfalse

\DeclareOption{uplatex}{\addJFont@uplatextrue}
\ProcessOptions\relax

\ifaddJFont@uplatex
  \def\addJFont@scale{0.924690}%%% scale for upjisr-h.tfm
  \def\addJFontEnc{2}
\else
  \def\addJFont@scale{0.961000}%%% scale for jis.tfm
  \def\addJFontEnc{1}
\fi

\@onlypreamble\addJFont@special
\let\addJFont@special\@empty

\@onlypreamble\addJFont

%%% \addJFont{<family>}{<series>}{<pTeX用CMap>}{<upTeX用CMap1>}{<upTeX用CMap2>}{<dvipdfmx用フォント名>}
\def\addJFont#1#2#3#4#5#6{%
  \g@addto@macro\addJFont@special{%
    \ifaddJFont@uplatex
      \special{pdf:mapline r-#1-#2-jy2  #4H #6}%
      \special{pdf:mapline r-#1-#2-jy2x #5H #6}%
      \special{pdf:mapline r-#1-#2-jt2  #4V #6}%
    \else
      \special{pdf:mapline r-#1-#2-jy1  #3H #6}%
      \special{pdf:mapline r-#1-#2-jt1  #3V #6}%
    \fi
  }%
  %
  \expandafter\ifx\csname JY\addJFontEnc+#1\endcsname\relax
    \DeclareFontFamily{JY\addJFontEnc}{#1}{}%
    \DeclareFontFamily{JT\addJFontEnc}{#1}{}%
  \fi
  %
  \DeclareFontShape{JY\addJFontEnc}{#1}{#2}{n}{<->s*[\addJFont@scale]#1-#2-jy\addJFontEnc}{}%
  \DeclareFontShape{JY\addJFontEnc}{#1}{#2}{it}{<->ssub*#1/#2/n}{}%
  \DeclareFontShape{JY\addJFontEnc}{#1}{#2}{sl}{<->ssub*#1/#2/n}{}%
  \DeclareFontShape{JY\addJFontEnc}{#1}{#2}{sc}{<->ssub*#1/#2/n}{}%
  %
  \DeclareFontShape{JT\addJFontEnc}{#1}{#2}{n}{<->s*[\addJFont@scale]#1-#2-jt\addJFontEnc}{}%
  \DeclareFontShape{JT\addJFontEnc}{#1}{#2}{it}{<->ssub*#1/#2/n}{}%
  \DeclareFontShape{JT\addJFontEnc}{#1}{#2}{sl}{<->ssub*#1/#2/n}{}%
  \DeclareFontShape{JT\addJFontEnc}{#1}{#2}{sc}{<->ssub*#1/#2/n}{}%
}

\AtBeginDocument{\AtBeginDvi{\addJFont@special}}

\endinput

addJFont パッケージのサンプルコード

この addJFont パッケージを用いれば,先程のクレーを使用するサンプルは,次のように簡単に書けます。

% klee.sty
\NeedsTeXFormat{pLaTeX2e}
\ProvidesPackage{klee}[2016/12/06 v0.1 doraTeX]
\RequirePackage{addJFont}

\addJFont{klee}{m}{2004-}{UniJIS2004-UTF16-}{UniJIS-UCS2-}{:1:Klee.ttc}
\addJFont{klee}{db}{2004-}{UniJIS2004-UTF16-}{UniJIS-UCS2-}{:0:Klee.ttc}

% pLaTeX使用時は JY1/JT1 を,upLaTeX使用時は JY2/JT2 を使う
\DeclareRobustCommand*\klee[1]{\usekanji{J\iftdir T\else Y\fi\addJFontEnc}{klee}{#1}{n}}
% => \klee{m} で「クレー ミディアム」,\klee{db} で「クレー デミボールド」が使用可能となる!

\endinput
%#!platex
\documentclass{jsarticle}
\usepackage{klee}
\usepackage{plext}% 縦組用

\begin{document}
{\klee{m}クレーミディアムの横組サンプル、「約物の“テスト”」。}\par
{\klee{db}クレーデミボールドの横組サンプル、「約物の“テスト”」。}

\vspace{1cm}

\parbox<t>{22zw}{%
{\klee{m}クレーミディアムの縦組サンプル、「約物の“テスト”」。}\par
{\klee{db}クレーデミボールドの縦組サンプル、「約物の“テスト”」。}}
\end{document}
%#!uplatex
\documentclass[uplatex]{jsarticle}
\usepackage{klee}
\usepackage{plext}% 縦組用

\begin{document}
{\klee{m}クレーミディアムの横組サンプル、「約物の“テスト”」。}\par
{\klee{db}クレーデミボールドの横組サンプル、「約物の“テスト”」。}

\vspace{1cm}

\parbox<t>{22zw}{%
{\klee{m}クレーミディアムの縦組サンプル、「約物の〝テスト〟」。}\par
{\klee{db}クレーデミボールドの縦組サンプル、「約物の〝テスト〟」。}}
\end{document}

Sierra の全和文フォントの一斉同時使用パッケージ:sierraJFont.sty

ここで作成した addJFont パッケージを応用して,(u)pLaTeX + dvipdfmx で Sierra の全和文フォントを出力するパッケージも用意しておきました。先程の addJFont.sty に加え,生成した tfm/vf, 一部の Adobe-Identity-0 フォント用の CMap ファイルもまとめて,必要ファイル一式を次に置いておきます。

github.com

使用法

インストール

各ディレクトリを,各自の TEXMFLOCAL 内に次のようにコピーしてください:

  • styTEXMFLOCAL/tex/ptex/platex/SierraJFont
  • cmapTEXMFLOCAL/fonts/cmap/SierraJFont
  • tfmTEXMFLOCAL/fonts/tfm/SierraJFont
  • vfTEXMFLOCAL/fonts/vf/SierraJFont

src 内は tfm/vf を生成するために用いたスクリプトです。使用時には不要なので,インストールは必要ありません。

使い方

\usepackage{sierraJFont}

とすれば,次のコマンドで Sierra 搭載の全和文フォントが使用可能になります。pLaTeX, upLaTeX の双方に対応しています。

  • \sierraJFont{hiraginoSans}{w0}:ヒラギノ角ゴシック W0
  • \sierraJFont{hiraginoSans}{w1}:ヒラギノ角ゴシック W1
  • \sierraJFont{hiraginoSans}{w2}:ヒラギノ角ゴシック W2
  • \sierraJFont{hiraginoSans}{w3}:ヒラギノ角ゴシック W3
  • \sierraJFont{hiraginoSans}{w4}:ヒラギノ角ゴシック W4
  • \sierraJFont{hiraginoSans}{w5}:ヒラギノ角ゴシック W5
  • \sierraJFont{hiraginoSans}{w6}:ヒラギノ角ゴシック W6
  • \sierraJFont{hiraginoSans}{w7}:ヒラギノ角ゴシック W7
  • \sierraJFont{hiraginoSans}{w8}:ヒラギノ角ゴシック W8
  • \sierraJFont{hiraginoSans}{w9}:ヒラギノ角ゴシック W9
  • \sierraJFont{hiraginoSerif}{w3}:ヒラギノ明朝 ProN W3
  • \sierraJFont{hiraginoSerif}{w6}:ヒラギノ明朝 ProN W6
  • \sierraJFont{hiraginoSansR}{w4}:ヒラギノ丸ゴ ProN W4
  • \sierraJFont{yuMin}{m}:游明朝体 ミディアム
  • \sierraJFont{yuMin}{db}:游明朝体 デミボールド
  • \sierraJFont{yuMin}{eb}:游明朝体 エクストラボールド
  • \sierraJFont{yuMin36pKn}{m}:游明朝体+36ポかな ミディアム
  • \sierraJFont{yuMin36pKn}{db}:游明朝体+36ポかな デミボールド
  • \sierraJFont{yuMin36pKn}{eb}:游明朝体+36ポかな エクストラボールド
  • \sierraJFont{yuGo}{m}:游ゴシック体 ミディアム
  • \sierraJFont{yuGo}{b}:游ゴシック体 ボールド
  • \sierraJFont{yuKyokasho}{m}:游教科書体 ミディアム
  • \sierraJFont{yuKyokasho}{b}:游教科書体 ボールド
  • \sierraJFont{yuKyokashoYoko}{m}:游教科書体 横用 ミディアム
  • \sierraJFont{yuKyokashoYoko}{b}:游教科書体 横用 ボールド
  • \sierraJFont{toppanBunkyuMincho}{r}:凸版文久明朝 レギュラー
  • \sierraJFont{toppanBunkyuGothic}{r}:凸版文久ゴシック レギュラー
  • \sierraJFont{toppanBunkyuGothic}{db}:凸版文久ゴシック デミボールド
  • \sierraJFont{toppanBunkyuMidashiMincho}{eb}:凸版文久見出し明朝 エクストラボールド
  • \sierraJFont{toppanBunkyuMidashiGothic}{eb}:凸版文久見出しゴシック エクストラボールド
  • \sierraJFont{klee}{m}:クレー ミディアム
  • \sierraJFont{klee}{db}:クレー デミボールド
  • \sierraJFont{tsukuARdGothic}{r}:筑紫A丸ゴシック レギュラー
  • \sierraJFont{tsukuARdGothic}{b}:筑紫A丸ゴシック ボールド
  • \sierraJFont{tsukuBRdGothic}{r}:筑紫B丸ゴシック レギュラー
  • \sierraJFont{tsukuBRdGothic}{b}:筑紫B丸ゴシック ボールド

使用例

sierraJFont パッケージのサンプルコード

出力結果

f:id:doraTeX:20161206090945p:plain

f:id:doraTeX:20161206090951p:plain

補足

上記手順に従った場合,独自 CMap を使用した Adobe-Identity-0 のフォント(游明朝体,游明朝体+36ポかな,游教科書体,游教科書体横用)で全角シングルクォーテーション ‘ ’ や全角ダブルクォーテーション “ ” を用いたときの組版が狂います。 sierraJFonts パッケージに添付した upTeX 用の vf には,その個別対応修正を入れてあります。