XeTeX

XeTeX とは

The XeTeX typesetting system は UTF-8 ベースの TeX。 「ズィーTeX」と読む。 Mac OS X 上で開発され,システムが認識する OpenType フォントをそのまま使える。 Linux 版もある。W32 版は Linux 版を移植したものである。 Linux と W32 では, 使えるフォントは OS が認識しているものと言うより,FontConfig が認識して いるものと言ったほうが正確である。 なお,バージョン 0.995 以降では(ただし 0.995 でも xetex は svn revision 344 以降,xdvipdfmx は svn revision 74 以降),

[FontFileName:FaceIndex]:features

なるフォントの指定法も可能になり,FontConfig とは無関係に, Kpathsearch が見つけることができるところにある “Uninstalled fonts” を native fonts として使用することもできるようになっている。例えば

\font\x="[msmincho.ttc:1]:mapping=tex-text,color=0000FF" at 12pt

\font\x="MS PMincho:mapping=tex-text,color=0000FF" at 12pt

と同じように振舞う。FaceIndex は不要の場合は省略できる。 前者の方が FontConfig に関係しないので, 早く処理できるかもしれない。簡単な比較をしてみよう:

%
% test-a
%
\font\x="[msmincho.ttc:1]:mapping=tex-text,color=0000FF" at 12pt
\x This is a test of -, -- and ---.
\bye
%
% test-b
%
\font\x="MS PMincho:mapping=tex-text,color=0000FF" at 12pt
\x This is a test of -, -- and ---.
\bye

の場合,test-a の方が test-b よりも約 2.3 倍ほど処理が速い。 なお,この数値はファイルの置き方その他の環境に依存するはずで, どのシステムにも当てはまるわけではない。また測定時間はプロセスが 要した時間であって,xetex 自身のロード時間その他は含まれていない。 これを含めると,比はより 1 に近付くと思われる。しかし test-a の方が かなり速いということはどの場合にも当てはまるだろう。 (Unix の場合は time xetex foo のようにすると時間がわかるが, W32TeX の場合は独自の “--proctimes” なるオプションを使うと, 可能なら要したプロセス時間を表示するようになっている。)

デフォルトではタイプセット時に,パイプによって出力がドライバに送られ, 最終出力は PDF となる。 オプション “--no-pdf” によってこれを 2 段階に分けることもできる。 この場合は .xdv ファイル (.dvi ファイルを拡張したもの)を出力する。.xdv ファイルをドライバによって PDF に変換する。 xdv2pdf は Mac 専用のドライバであって,他では利用できない。 Linux と W32 では,汎用の xdvipdfmx というドライバを用いる。これは dvipdfmx を XeTeX 用に拡張したものである。 xdv2pdf は Mac OS X を有効利用するドライバだが,仮想フォントを読むことが できないので,通常の tfm, vf 形式の TeX, LaTeX 用フォントも利用する場合には Mac OS X であっても xdvipdfmx を使うことになる。 また、上記の “Uninstalled fonts” を使う機能も,ドライバに xdvipdfmx を使う 場合だけ有効である。直接 PDF を出力する場合には

xelatex --output-driver='xdvipdfmx -q -E' foo

のようにすると,デフォルトのドライバを変更して xdvipdfmx を使うようにできる。なお Mac OS X 用の XeTeX には最新の 0.995 以降の ものにしか xdvipdfmx は含まれていない。 svn revision 506 以降では、 Mac OS X 用のデフォルトのドライバも xdvipdfmx になった。 パッケージに同梱されている graphics.cfg と color.cfg は xdv2pdf 用の設定が なされている。従って Linux と W32 では, graphics パッケージや color パッケージなどを使用するとき,必ず [dvipdfm] オプションを付加しておくのを忘れてはいけない。ただし,Jonathan Kew さんに より,Mac と Linux-W32 とでインターフェイスを統一する仕事がなされており, 最新版の xdvipdfmx と XeTeX を W32 版でテストしてみると, デフォルトのままで xetex.def を使えるようになっている。

しおり等の PDF 文字列に関しては,オリジナルの dvipdfmx では 適切な CMap を指定することで Big Endian UTF-16 with BOM に変換するようになっていた。 xdvipdfmx でもこの機能はそのまま使えるが,UTF-8 で入力する XeTeX においては 単に UTF-8 を Big Endian UTF-16 with BOM に変換するだけでよいので, より簡単な実装が可能である。 実際にこの機能が実装されていて,特別に何もしなくても日本語しおり等を作ることができる。

Mac でのインストール

ptetex をインストールした Mac OS X 10.4.x でインストールしてみた。 本家から XeTeX_0995.dmg をダウンロードし,ダブルクリックして現れる XeTeX.pkg をダブルクリックして先に進んでいくとエラーになる。 インチキだが

cd /usr/local/teTeX/bin
ln -s . powerpc-apple-darwin-current

とするとインストーラが動く。

cd /usr/local/teTeX/share
mv texmf.local texmf-local
cd texmf-local
ln -s ../texmf-var/fonts/map/dvips/updmap dvips

/usr/local/teTeX/share/texmf/tex/generic/config/language.dat の “The following languages are disabled by default.” と 書いてあるところ以降にある magyar huhyphn.tex という行を “%! ” でコメントアウトし

fmtutil --byfmt xetex
fmtutil --byfmt xelatex

Windows でのインストール

cf. qa:43295

最新の web2c-2010-w32.tar.bz2 を入手して,TeX のインストール トップディレクトリで展開して下さい。この中に xetex をサポートする fmtutil.cnf と texmf.cnf が入っています。

xetex-w32.tar.bz2 を TeX のインストールトップディレクトリで展開して下さい。

TopDir/share/texmf/fonts/conf に移動し,(つまりカレントディレクトリとし) そこにある fonts.conf というファイルを編集します。 編集するのは “Find fonts in these directories” というセクションだけです。 そこにはデフォルトで, Windows のシステムフォントディレクトリだけが

    <dir>c:/windows/fonts</dir>

として入れてありますから,このままで良い場合は編集する必要はありません。 ディレクトリの名前が違う場合には変更する必要があります。 Windows のシステムフォントディレクトリの他に,購入したフォントのディレクトリがあれば, 以下の例のように追加することができます:

    <dir>c:/windows/fonts</dir>
    <dir>c:/usr/local/share/texmf/fonts/opentype/dnscreen/hiragino</dir>
    <dir>c:/usr/local/share/texmf/fonts/opentype/adobe/kozuka</dir>
    <dir>c:/usr/local/share/texmf/fonts/opentype/adobe/others</dir>

コンソール上で

    fc-cache -v -f

なるコマンドを実行して下さい。これはフォントディレクトリにある各ファイルを スキャンして,キャッシュファイルを作成するコマンドです。 キャッシュファイルは,TopDir/share/texmf/fonts/cache に作成されます。 大きいフォントファイルが大量にあると,このコマンドは終了までに数分かかる ことがありますから,気長に他の仕事をしていて下さい。

以上でインストールが終了します。使用可能フォント名は,通常のものが使えます。 名前を見たい場合は,

   fc-list >namelist.txt

とすると, namelist.txt に記録されます。 ただし UTF-8 で記録されますから,もし Shift_JIS で見たかったら

   nkf -s namelist.txt >namelist.sj

とすれば良いでしょう。あるいは最初に

   fc-list | nkf -s >namelist.sj

とすると,直接 Shift_JIS のファイルになります。 ただし,nkf でコード変換した結果のフォント名をそのまま使うと, エラーになることがあります。その理由は例えば 1 バイト仮名が nkf によって 2 バイト仮名に変換されたりするからです。漢字フォント名を 使うときは,UTF-8 が読めるエディタで fc-list の生の出力を見る必要があります。 通常はアルファベットの名前のほうが入力も簡単でしょう。

入力用エンコーディング

XeTeX はデフォルトではファイルを UTF8 として読み込みますが、

\XeTeXinputencoding (エンコーディング名)

の指定により、ファイルのそれ以降の部分をそのエンコーディングで読み込みます。グルーピングの影響は受けません。特に重要なのは

\XeTeXinputencoding "bytes"

で、これにより、 XeTeX はファイルを 1 バイトずつ、文字コードの解釈を行わずに読み込むようになるので、 8 ビットのハイフネーションパターンや、 inputenc, CJK 等の 8 ビットの TeX を前提としたマクロも (原理的には) 使用できるようになります。

エンコーディングの解釈には、 ICU ライブラリが使われるので、 iconv の規則とは異なり、

\XeTeXinputencoding "SJIS"

\XeTeXinputencoding "CP932"

はどちらも 0x5c を円記号では無くバックスラッシュとして、解釈してくれるようです。

TECKit

XeTeX には単純だけれども結構強力な入力フィルタ TECKit が内蔵されており、ソースコード中のある文字列を別の文字列に変換してから、 TeX に処理させることができます。 使用するフィルタはフォント毎に指定します。

xu-hyphen

XeTeX は一部の言語 (ギリシャ語、コプト語など) のハイフネーション処理には始めから、ユニコードのフォントエンコーディングを用いたパターンファイルを使用しますが、他の多くの言語用には、古典的な 8 ビットの TeX を前提としたハイフネーションパターンをそのまま利用します。 xu-hyphen はそのために必要なラッパーのコレクションです。

スマート・フォント

和文や欧文などの『単純』な表記システムのタイプセットでは、グリフを組方向のメトリックに従い平行移動しながら配置することで、ほぼ、事が足ります。 しかし、もちろん、これだけでは、和文の縦組での約物、囲み文字や字間空き、欧文の詰め、合字やアクセント記号の位置調整など、処理しきれない事項もあります。 伝統的な TeX では、これらの処理の多くは tfm に実装されてきました。 しかしながら、世界には、それほど『単純』ではない表記システムもあります。

TeX 以外のシステムでも、このような『単純』な平行移動しながらの配置では済まない文字組を行う必要は当然あります。それには処理に必要な情報をフォントに実装した、スマート・フォント技術が使われることが多くなってきています。

XeTeX は tfm には依らずにタイプセットを行うために、様々なスマート・フォント技術をサポートしています。スマート・フォント技術では、同じ文字でも使用されるコンテクストによって、異なる扱いが必要になるため、 XeTeX では従来の TeX とは異なり、一つ一つの文字を個別に処理するのでは無く、文字列ブロック毎にまとめて処理するアプローチがとられています。次のソースを XeLaTeX でコンパイルして見てください。

\documentclass{article}
\usepackage[cm-default]{fontspec}
\TeXXeTstate=1
\begin{document}
\beginR
A quick brown fox jumps over the lazy dog.
\end{document}

\beginR は e-TeX のプリミティブで文字を右から左方向に組んでいきます。結果は

.god yzal eht revo spmuj xof nworb kciuq A

となるはずです。この文書では tfm ベースの Computer Modern フォントが使用されています。ここで、

\usepackage[cm-default]{fontspec}

の行を

\usepackage{fontspec}

にすると、デフォルトのフォントが Latin Modern OpenType になります。それをコンパイルすると、結果は

dog. lazy the over jumps fox brown quick A

となるはずです。つまり、 XeTeX は空白文字で区切られた単語を一塊のブロックとしてタイプセットしているわけです。

AAT (Apple Advanced Typography) フォント

わしゃ知らん

OpenType フォント

OpenType フォントはフォントファイルの以下のテーブルにスマート・フォント機能を実装しています。

BASEベースラインの設定用データ。現在 XeTeX ではアクセスできない。
GDEF以下のテーブルのスマート・フォント機能の実装を簡単にするためのグリフ分類用データ。ユーザーが明示的にアクセスする必要はない。
GPOS組み版方向への単純なグリフメトリックだけでは実現できない、状況に応じた。位置調整用のデータ。
GSUB状況に応じた。グリフ置換用のデータ。
JSTF行頭、行末をそろえる際の(フォントのデザインに応じた)微調整用のデータ。現在 XeTeX ではアクセスできない。

OpenType フォントの各テーブルは文字種と言語ごとにアクセスできます。

スマート・フォント技術としての OpenType の特徴はユニコード規格で定められている、文字種に共通の表記上の規則、例えば、アラビア文字やシリア文字のコンテキストによる字形、インド・東南アジア系文字の並べ変え等は、レンダラが知識として持っていることを仮定し、フォントには、そのフォントのデザイン固有のデータのみを格納するとの立場がとられていることです。

いろいろ実験してみましょう。

\documentclass{article}
\usepackage{graphicx,geometry,fontspec}
\geometry{margin=1in}
\def\showfeature#1#2{\mbox{\XeTeXinterchartokenstate=0#2\hspace{0.5em}\rotatebox[origin=tl]{-90}{\addfontfeature{RawFeature=vertical:}#2}\hspace{0.5em}{\addfontfeature{RawFeature={#1}}\rotatebox[origin=br]{-90}{\addfontfeature{RawFeature=vertical:}#2}#2}}}
\parindent=0pt
\begin{document}
\fontspec[Script=Kana]{Kozuka Mincho Pro-VI}
\showfeature{+dlig,+afrc}{1dl=1/10リットル}\hfill
\showfeature{+afrc}{1/2=1/3+1/6}\hfill
\showfeature{+frac}{1/2=1/3+1/6}\hfill
\showfeature{+trad=0}{闘鶏}\hfill
\showfeature{+trad=1}{闘鶏}\hfill
%%横書/縦書用のフィーチャーを組み版方向と一致させずに適用するとおかしな事になる。
\showfeature{+palt}{一月一日}\hfill
\showfeature{+vpal}{一月一日}\\[20pt]
{\obeylines\XeTeXinterchartokenstate=0\addfontfeature{RawFeature=+ccmp}%
ピㇼカ チカㇷ゚ポ!  カムイ チカㇷ゚ポ!
ケケ ヘタㇰ, アタㇱ ワ トアン チカㇷ゚ポ
カムイ チカㇷ゚ポ ツ゚カン ワ アンクㇽ, ホㇱキウㇰクㇽ
ソンノ ラメトㇰ シノ チパパ ネ ルヱ タパン}\\[20pt]
\count255=0
\loop\ifnum\count255<23{\addfontfeature{RawFeature={+aalt=\the\count255}}辺}\advance\count255by1\repeat\\[20pt]
\count255=0
\loop\ifnum\count255<7{\addfontfeature{RawFeature={+nalt=\the\count255}}イロハ }\advance\count255by1\repeat
\end{document}

Graphite フォント

Graphite は SIL で開発された、極めて強力なスマート・フォント技術で、レンダラにユニコード規格などの事前の知識を要求すること無く、すべてをフォントに実装されたデータに基づき、処理されます。このような、スマート・フォント技術が新たに開発されたのは、ユニコードには収録されていない文字や、縦令収録されていても、少数言語のタイプセットにはユニコードの規格に採用されている公式言語の規則とは異なる処理を必要とする文字があるからです。

\font\d="Doulos SIL/GR:1041=0:" at 40pt
\d
Ştiaţi că…?
\hfill
\font\d="Doulos SIL/GR:1041=1:" at 40pt
\d
Ştiaţi că…?

%%同じ事を OpenType でやってみる
\vskip40pt
\font\d="Doulos SIL/ICU:script=latn:language=dflt:" at 40pt
\d
Ştiaţi că…?
\hfill
\font\d="Doulos SIL/ICU:script=latn:language=ROM :" at 40pt
\d
Ştiaţi că…?

%%次は OpenType では実装されていない例。
\vskip40pt
\font\d="Doulos SIL/GR:1027=0:" at 40pt
\d
Монгол хэл
\hfill
\font\d="Doulos SIL/GR:1027=1:" at 40pt
\d
Монгол хэл
\bye

Graphite フォントの中にはビルマ文字のPadauk Fontのように、ビルマ語、カレン語、モン語の文字の並べ変えや位置調整のみならず、改行規則まで実装したフォントもあります。

改行アルゴリズムの比較

そもそも TeX で改行が可能な位置は、(数式と kern を無視して)単純化すると、 glue, penalty, discretionary break です。ハイフンは日本語に関係しないので、無視します。 文章中のどのような箇所に glue と penalty が現れるかというと、

  1. ユーザーが直に書き込んだ場所、
  2. マクロの展開の結果書き込まれる場所、
  3. それ以外、

    がありますが、ここでは、3. が問題となります。

このようにして、各言語毎の規則で設定された改行可能箇所から、その段落の最も適切な改行箇所を見つけ出すのは、 TeX の役割です。 0.997 以降では、更に、 \XeTeXinterchartokenstate が正の値になっていれば、 \XeTeXcharclass の概念が有効になり、 \XeTeXcharclass が A の文字と \XeTeXcharclass が B の文字との間にはトークンレジスタ

\XeTeXinterchartoks A B

が自動的に挿入されます。このトークンレジスタに改行を可能にする glue や penalty に展開される内容が入っていれば、ここも改行可能箇所になります。 このグルーの挿入はマクロ展開前に行われます。 \XeTeXcharclass は 0 -- 255 の任意の整数ですが、 255 だけは特別な意味を持ち、文字列の境界を表します。例えば、行末。行頭、インラインの数式、 hbox などです。 FMT ファイルで、\XeTeXcharclass の値は

一例として、行末禁則文字の \XeTeXcharclass を 4 に設定するには、

\@for\Kinsoku:={`#,`¥,`$,`&}\do{\XeTeXcharclass\Kinsoku=4}

とします。 \XeTeXinterchartoks 4 1 等を適切に定めれば、これらの文字の直後での改行を抑制できます。 \XeTeXinterchartoks にはフォントの切替え命令を設定することもできます。これにより、 dvi ドライバではなく、 TeX 側に於ける、バーチャルフォントが実現できます。 なお、このメカニズムにより、文字間にトークンを挿入すると、内蔵の ICU ライブラリによる解析の対象は個別の文字になってしまうので、 \XeTeXlinebreaklocale の設定は無意味になります。 同様に、 OpenType フォントの持つ、コンテクスト依存の文字置換や、リガチャーを使用する際にも、 \XeTeXinterchartokenstate=0 としなければなりません。

{\XeTeXinterchartokenstate=0\fontspec[Script=Kana,RawFeature=+dlig]{Kozuka Mincho Pro-VI}ミリバール}

fontspec パッケージ

fontspec は NFSS のフォントファミリーの定義を容易に行うためのマクロパッケージです。

\fontspec[オプション]{フォント名}

は現在使用中のフォントファミリーを変更します。

\setmainfont[オプション]{フォント名}

は \rmdefault を変更します。

\newfontfamily\myfontfamily[オプション]{フォント名}

は新しいフォントファミリー \myfontfamily を定義します。

\documentclass{article}
\usepackage{graphicx,geometry,fontspec}
\geometry{margin=1in}
\parindent=0pt
\pagestyle{empty}
\begin{document}
\fontspec{Lido STF}
\textit{\textbf{A}} quick brown \textbf{fox} jumps over the lazy \textit{dog.}
\end{document}

をコンパイルして、埋め込まれたフォントを見てみると、

>pdffonts test.pdf
name                                 type         emb sub uni object ID
------------------------------------ ------------ --- --- --- ---------
ABHBIS+LidoSTF-BoldItalic-Identity-H CID Type 0C  yes yes yes      5  0
WGMDOS+LidoSTF-Identity-H            CID Type 0C  yes yes yes      7  0
XSCVIF+LidoSTF-Bold-Identity-H       CID Type 0C  yes yes yes      9  0
ZUDXAP+LidoSTF-Italic-Identity-H     CID Type 0C  yes yes yes     11  0

とファミリー内での、シリーズやシェイプの変更も正しく処理されていることが分かります。しかし、もし、

\fontspec{[LidoSTF.otf]}

とファイル名でフォントを指定したのでは、ファミリー内のすべてのフォントは LidoSTF.otf になってしまいます。このような場合はオプションで、

\fontspec[BoldFont={[LidoSTFBold.otf]},ItalicFont={[LidoSTFItalic.otf]},BoldItalicFont={[LidoSTFBoldItalic.otf]}]{[LidoSTF.otf]}

と自分でフォントを指定しなければなりません。

非欧文フォントでは、残念ながら、縦令フォント名を使用して font-config にフォントを探させても、誤ったフォントを選んでしまうことが多いので、自分でファミリーを構成するフォントを指定した方が安全です。

実行例

簡単なサンプル test.tex を UTF-8 で書く:

\documentclass{article}
\begin{document}
Hello, \TeX !
\font\foo="ヒラギノ丸ゴ Pro W4"
\foo 日本語
\end{document}

これで xelatex test とすると,test.pdf ができる。 ただしこれでは

,「

のような約物の連続で間延びして,逆に使い物にならない。

日本語のルールに則って行分割をするには次のようにする。

\XeTeXlinebreaklocale "ja_JP"
\XeTeXlinebreakskip=0em plus 0.1em minus 0.01em
\XeTeXlinebreakpenalty=0

元に戻すには次のようにする。

\XeTeXlinebreaklocale ""

ただし XeTeX は日本語の組版ルールをよく知っているわけではないので, 現状ではまともではない。 しかし筋が良いソフトだけに日本人が開発に協力すれば pTeX 相当の処理が加えられるのではないかと期待する。

参考サイト

コメント



Last-modified: 2010-04-16 (金) 06:14:38 (105d)