マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

LaTeX に新しいフォントを持ち込む話

前の記事であげた文書「欧文フォントのインストール」TeX レベルにおけるフォントの取扱を専ら扱っている。実際に LaTeX 上で新しいフォントを使いたいという人にとっては、LaTeX レベルでの設定――すなわち、新しいフォントを LaTeX のフォント命令で扱えるようにするための方法――の知識も必要である。幸い、例の文書の内容を習得した(つまり、TeX\font プリミティブでの定義ができる)人((当然ながら、「LaTeX のフォント関連コマンド(\fontshape 等)について知っていることも前提となる」))にとっては、LaTeX レベルの設定はそれほど難しくない。以下では、そういう人のために、必要最低限の知識を説明しようと思う。

LaTeX でのフォントの管理方法

まず、既存の(つまり「既に設定されている」)フォントを使う場合を例にとって、LaTeXTeX のフォント管理方法の違いについて見ることにする。*1

例えば、T1 エンコーディングの「Times Bold Italic」を 12pt で使いたいとする。*2LaTeX の場合、まずその『フォント』の属するファミリ、シリーズ、シェープを考える: 「Times Bold Italic」はファミリ ptm のシリーズ b のシェープ it である。従って、エンコーディングとサイズを加えて、5 つの「属性」を指定することになる。((\fontsize の第 2 引数は行送り(この場合 14pt)を表す。これはフォントの属性ではないが、LaTeX ではフォントサイズは行送りと共に指定することになっている。ちなみに、article クラスの \large はこの \fontsize{12}{14} と同じである。))

\fontencoding{T1}\fontfamily{ptm}\fontseries{b}\fontshape{it}%
\fontsize{12}{14}\selectfont Hello!

あるいは、サイズ以外の属性は \usefont 命令で一度に指定できるので、それを用いてもよい。((\usefont は中で自動的に \selectfont を行うので、それのみ使うのなら \selectfont は不要。))

\usefont{T1}{ptm}{b}{it}\fontsize{12}{14}\selectfont Hello!

さらに「文書の既定のフォントを T1 の Times にする」という前提であれば、以下のようにするのが一般的であろう。((\large = \fontsize{12}{14} とする。なお、\bfseries は本当は \fontseries{bx} であるが、ptm ファミリで bx シリーズが指定された場合は黙って b シリーズに代替される。))

% プレアンブルで
\usepackage[T1]{fontenc}
\renewcommand{\rmdefault}{ptm} % \rmfamily を ptm にする
% 当該の箇所で
\rmfamily\bfseries\itshape\large Hello!

使う側の書き方は色々あるが、いずれにしても、LaTeX ではこのように複数の属性を用いてフォントを管理している(このフォント管理の仕組みを NFSS(Nww Font Selection Scheme)と呼ぶ)。

TeX でのフォントの管理方法

それでは、TeX のプリミティブでのレベルで「T1 エンコーディングの Times Bold Italic の 12pt」を指定するにはどうすればよいか。まず当該フォントの TFM 名を求める。「T1 エンコーディングの Times Bold Italic」の TFM 名は ptmbi8t である。*3従って、以下のような指定方法になる。

% 予め定義しておく
\font\TITimesBoldItalicXII=ptmbi8t at 12pt
% 当該の箇所で
\TITimesBoldItalicXII Hello!

つまり、上のようにして \font で定義された \TITimesBoldItalicXII という制御綴が TeX でのフォントの表現(「fontdef トークン」と呼ばれる)となっている。これで判るように、TeX では、「属性」がどれか違うものは全て「全く違うフォント(=fontdef トークン)」として取り扱われる。

\font\TITimesBoldItalicXII=ptmbi8t at 12pt    % T1, Times Bold Italic 12pt
\font\LYITimesBoldItalicXII=ptmbi7y at 12pt   % LY1, Times Bold Italic 12pt
\font\TIPalatinoBoldItalicXII=pplbi8t at 12pt % T1, Palatino Bold Italic 12pt
\font\TITimesItalicXII=ptmri8t at 12pt        % T1, Times Italic 12pt
\font\TITimesBoldXII=ptmb8t at 12pt           % T1, Times Bold 12pt
\font\TITimesBoldItalicX=ptmbi8t at 10pt      % T1, Times Bold Italic 10pt

この扱いは、「TFM レベル」での扱いとも異なっていることが、上掲の最初と最後の定義を比べると解る。TFM では「フォントサイズのみが異なる」ものは同じフォント(ptmbi8t)として扱える。*4TeX では「TFM とサイズ」を組にしたものを「1 つのフォント」(つまり、\TITimesBoldItalicXII\TITimesBoldItalicX)としているのである。

NFSS は何をしているのか

以上のことを考え合わせると、「LaTeX のフォント管理システム(NFSS)が何をしているのか」が判る。つまり、要件としては、LaTeX の「エンコーディング T1、ファミリ ptm、シリーズ b、シェープ it、サイズ 12pt」*5という指定から「fontdef トークン」を作り出す必要がある。一方、TeX\font 命令で fontdef トークンを定義するには TFM とサイズが必要である。サイズは指定されたものをそのまま使えばよい。従って、NFSS が行うべきことは

T1/ptm/b/it ―→ ptmbi8t

のように、「サイズ以外の 4 つの属性値」から「TFM 名」への写像ということになる。

実際に新しいフォントを導入してみよう

原理の概要が判ったところで、実際に新しいフォント(つまり、TFM として定義されたもの)を LaTeX に導入する設定例を述べる。ただし、ここでは最も単純な場合として、「単一のフォントからなるファミリ」を扱うことにする。例としては、件の文書の 5.3 節においてインストール例として挙げられている「Plasma Drip BRK」(TFM 名 plasma)を用いる――つまり、その節の手順に従って、TeX レベルのインストール作業は既に済んでいる状態を前提とする。*6

TFM は既に与えられいる(plasma.tfm)ので、それの対応元となる 4 つの属性値(サイズ以外)を決める必要がある。

?/?/?/? ―→ plasma

このうち、エンコーディングは既に決まっていて、例の文書の通りに作業したのであれば、それは LY1 のはずである(texnansi.enc を使っているので)。ファミリ名については、これから新たに導入するのだから好きなように命名すればよい。ここでは単純に plasma としよう。「フォント」が 1 つしかないので、この plasma ファミリには plasma.tfm のみで構成される。実は、シリーズとシェープの値も何でも良い(実際に使うときに \fontseries 等に「設定した名前」を指定すれば通用する)のであるが、ここではメンバーが 1 つしかないので、「最も普通」を意味するシリーズ m (= medium)とシェープ n (= normal)を当てることにしよう。これで「設定すべき内容」が確定した。

LY1/plasma/m/n ―→ plasma

それでは、実際に設定作業に取り掛かる。上のような属性値から TFM への対応は「フォント定義ファイル」に記述するのが標準的な方法である。((このようにしておくと、\usepackage 等で設定ファイルを明示的に読み込まなくとも、該当のファミリが呼び出された時点でそのファイルが自動的に読み込まれる。))フォント定義ファイルはファミリ毎に用意し、ファイル名は「(エンコーディング名の小文字)(ファミリ名).fd」とする。このファイルにまず「新しいファミリを定義する命令」である \DeclareFontFamily 命令を記述する。今の場合、次のようになる。

[ly1plasma.fd]
% LY1/plasma のフォント定義ファイル
  % \DeclareFontFamily{エンコーディング}{ファミリ}{}
  % 第 3 引数は普通は空で構わない
\DeclareFontFamily{LY1}{plasma}{}

この後に、「属性値から TFM への対応」を \DeclareFontShape 命令を用いて記述する。今の場合、対応(TFM)が 1 つしかないので、この命令の記述も 1 つになる。

  % \DeclareFontShape{エンコーディング}{ファミリ}{シリーズ}{シェープ}
  %   {<->TFM名}{} : 最後の引数は普通は空で構わない
\DeclareFontShape{LY1}{plasma}{m}{n}{<->plasma}{}

TFM 名の前にある「<->」については、「オプティカルサイズ」でない場合は常にこれを付けると思って構わない。*7これでフォント定義ファイルは完成である。この ly1plasma.fd ファイルを次の場所に配置する。*8

  • $LOCAL/tex/latex/plasma/ly1plasma.fd
    (「パッケージ名」を plasma とした。)

これで設定は全て完了である。この後で、任意の LaTeX 文書中で「LY1/plasma/m/n」の指定を行う(例えば \usefont{LY1}{plasma}{m}{n} を実行する)と、先の定義ファイルが読み込まれて、現在のフォントサイズの plasma.tfm にフォントが変更される。ここで、「1 つのシェープしかないのだから、もっと単純に、例えば \plasmafont とかで使えるようにしたい」というのであれば、それは単なる「LaTeX のマクロ定義」*9の問題である。

実際に LaTeX 文書でフォントを使ってみる

[test-plasma.tex]
\documentclass{article}
  % LY1 エンコーディングを使用可能にするが、既定は OT1 のまま
\usepackage[LY1,OT1]{fontenc}
  % 素敵な色をつけましょう
\usepackage{color}
\definecolor{dred}{rgb}{0.8,0,0}
\definecolor{dgray}{rgb}{0.1,0.1,0}
\pagecolor{dgray} % ページ背景色の設定
\begin{document}
\begin{center}
  % LY1/plasma/m/n(つまり plasma.tfm)の 50pt を指定
  \usefont{LY1}{plasma}{m}{n}\fontsize{50}{50}\selectfont
  \color{dred}Happy {\TeX}ing!
\end{center}
\end{document}

*1:なお、この記事では、「オプティカルサイズ」(サイズによりデザインの異なる)の取扱については、実際にそのようなフォントを導入することが稀であるという理由で割愛することにする。

*2:Times などの「Adobe 基本書体」は LaTeX で最初から適切な設定が行われているので、それを用いることを前提とする。

*3:なお、この名前は一定の規則(Berry 命名規則)に基づいて決められたものだが、この規則は単なる習慣であって、TeX 自体はこの規則とは無関係であることに注意されたい。Berry 命名規則についてはいつか話をしたい。

*4:Computer Modern はサイズにより TFM が異なる(例えば、cmt10、cmr9、cmr17、等)が、これの理由は「オプティカルサイズ」だからである。(つまり「サイズだけが異なる」のではない。)

*5:便宜的に、この属性値の組をまとめて「T1/ptm/b/it/12」のように表記することが多い。

*6:私は DailyFreeFonts.com からこのフォントファイルを入手した。

*7:オプティカルサイズ」である場合にこの部分がどうなるかは、OT1/cmr のフォント定義ファイル、すなわち ot1cmr.fd を見れば判るだろう。

*8:例の文書の表記方法に従う。勿論、この後に「必要ならば mktexlsr を実行する」の但し書きがつく。

*9:TeX のマクロ」ではないですよ(念のため)。