マクロツイーター

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

TikZ は dvipdfmx をどこまでサポートするか? (1)

TeX Wiki「TikZ」の記事に述べられているように、TikZ の描画処理は間に PGF という「中間処理層」(「描画エンジン」と呼ばれている)を挟んで行われている。グラフィクスの描画には DVI ウェアの「拡張機能」を必要とするのであるが、DVI ウェア毎の仕様の差は全て PGF のドライバのレベルで吸収されている。つまり TIkZ 自体は「直接は DVI ウェア依存の動作」をせず(つまりドライバを持たず)、常に同じ「PGF の命令」を利用しているのである。すなわち、「TikZ は dvipdfmx をサポートするか」という問題は結局「PGF は dvipdfmx をサポートするか」という問題に帰着される。(なお、PGF は Beamer の描画処理でも用いられていて(TikZ を使っているのではない)、やはり Beamer も「直接は」DVI ウェア依存の処理を(原則的には)行っていないことは以前の記事で述べた。)

「dvipdfm」はどこまでサポートされるか?

現状の PGF/TikZ のマニュアルを見ると、そこには「dvipdfmx」のドライバに関する記述はないが、「dvipdfm」のドライバ(pgfsys-dvipdfm.def)に関する記述が載っている。(「Input and Output Formats」の節。)要点としては、次のような制限事項があると書かれている:

  1. LaTeX 上で動作する場合、画像挿入は graphicx の機能を利用する。透明マスク((ビットマップ画像の一部のピクセルを透過させる機能。PGF の \pdfdeclaremask 命令。))は非サポート。
  2. plain 上の動作では、画像挿入は非サポート。
  3. 図画間結合(inter-picture connections)は pdfTeX の最近の版でのみサポートされる。
  4. パターン*1は非サポート。
  5. 関数シェーディング*2は非サポート。

しかし、この記述は飽くまで dvipdfm についてのものである。dvipdfmx については状況は異なる。

前提知識: dvipdfm と dvipdfmx

LaTeX で dvipdfmx の使用を前提とする解説文書をみると、ものによって(同じパッケージであっても)ドライバ指定を「dvipdfm」としているものと「dvipdfmx」としているものがある。学習者の混乱の原因となっていると思うので詳しく説明しておく。

元々 dvipdfm というソフトウェアがあって、それを機能拡張したものが dvipdfmx である。ただし完全な上位互換ではないので、少し昔の TeX システムでは両方のソフトウェアが並存していた。基本的に別のものと考えるなら、ドライバ指定については「dvipdfm を使うなら dvipdfm、dvipdfmx を使うなら dvipdfmx」という自明な規則に従えばよい。

しかし、パッケージによっては、「dvipdfmx のドライバは提供されていないが、dvipdfm のものは提供されている」場合が存在する。そういうパッケージを dvipdfmx で使いたい場合には、応急処置として「dvipdfm」ドライバを使うことが考えられる。それで取りあえず dvipdfm の範囲の機能は使えることが期待できる。すなわち、ドライバ依存のパッケージを dvipdfmx で使う場合は、「dvipdfmx のドライバがあればそれを指定し、無ければ dvipdfm を指定する」という規則に従えばよい。(なお、dvipdfmx 用のドライバが提供されているかは当該パッケージのマニュアルを参照して確認するのが確実である。もちろん、dvipdfmx と dvipdfm のどちらのドライバも無い場合は、dvipdfmx での使用は諦めるしかない。)

少し昔の時点では、dvipdfmx のサポート状況は余り良くなかった。dvipdfmx を主に使っているのは CJK 言語の国であるという事情があり、欧米では少し前まで dvipdfmx はほとんど知られていなかったためである。(dvipdfm も余り使われず、専ら dvips か pdftex が使われている。)しかし、XeTeX がその PDF 生成のために「dvipdfmx の更なる拡張版」(xdvipdfmx)を使っていることが契機となり、dvipdfmx の存在が広く知られるようになり、それに伴って、ドライバ依存のパッケージで dvipdfmx 用のドライバをもつものが増えていった。そして現在は、(ソフトウェアの)dvipdfm は obsolete となり代わりに dvipdfmx を使うことが推奨されるようになっている。実際、TeX Live でも W32TeX でも本物の dvipdfm の実行ファイルはもはや存在せず、dvipdfm というコマンドを実行すると、代わりに dvipdfmx が「互換モード」で起動するようになっている。*3

「dvipdfmx」はどこまでサポートされるか?

さて、話を PGF に戻す。マニュアルには記載されていないが、現在の PGF では dvipdfmx 用のドライバ(ファイル名は pgfsys-dvipdfmx.def)が用意されている。*4先に述べた dvipdfm ドライバの制限事項と対照させると以下のようになる」。

  1. graphicx の機能を用いている点は変わらない。*5透明マスクはサポートされている。
  2. これについては後述。
  3. これは同じ。ただこれは本当は DVI ドライバではなく TeX エンジンに関する依存事項であることに注意。*6この機能については跡で詳しく扱う。
  4. パターンはサポートされている。
  5. 関数シェーディングはサポートされている。
TikZ のドライバを指定する「まともな」方法

「ドライバ依存」のパッケージで「ドライバを指定する」ための方法について、大抵は「パッケージオプション(\usepackage 命令のオプション)に書く」という方式が採られている。

\usepackage[dvipdfmx]{graphicx,color} % ドライバを dvipdfmx にする

ところが、理由は不明であるが、TikZ(および PGF)はこの「伝統的な」方式を使っていない。そして、マニュアルには次のような「よく解らない」説明のみが書いてある。((「LaTeX 以外」ではドライバのファイル名(pgfsys-〈ドライバ名〉.def という名前)を著す \pgfsysdriver というマクロを直接再定義することが指示されている。))

For the LaTeX format a sophisticated mechanism exists inside the graphics package and PGF plugs into this mechanism.

よく解らないわけだが、実装としては、PGF では(設定ファイル(pgf.cfg)で指定されない場合)graphics パッケージ(または graphicx パッケージ*7)のドライバ指定に従うということである。これに単純に従うと、例えば dvipdfmx ドライバを指定する場合は、「前もって graphicx をそのオプションで読み込んでおく」べき、ということになる。

\documentclass[a4paper]{article}
\usepackage[dvipdfmx]{graphicx}
\usepackage{tikz}
[追記] 上記の読込の方法では、color パッケージのドライバ指定が不正になることがあるので、よい子の皆さんは、マネをしないように。

しかし、この方式は如何にも奇妙である。恐らく、作者は「ドライバ指定は通常はグローバルオプション((文書クラスに指定されたオプション(\documentclass 命令のオプション)は、全てのパッケージについて「それが適用可能であれば」適用される。これを「グローバルオプション」と呼ぶことがある。))で指定する」という習慣を念頭においているのだと私は推測している。*8

\documentclass[a4paper,dvipdfmx]{article} % ドライバをグローバルオプションで指定
\usepackage{pict2e}   % 'dvipdfmx' オプションをもつ全てのパッケージで
\usepackage{animate}  % それが有効になる。
\usepackgage[bookmarks=true]{hyperref}

PGF は内部で(常に)graphicx を読み込んでいて、そのドライバを識別して既定のドライバ設定を決定している。従って、グローバルオプションでドライバを指定するという習慣に従っていれば、PGF(および TikZ)のドライバ指定も自動的に所望のものになる。以下では、dvipdfmx のドライバを指定してパターンと関数シェーディングを実際に利用する例を挙げる。

\documentclass[a4paper,dvipdfmx]{article} % ドライバをグローバルオプションで指定
\usepackage{tikz}
\usetikzlibrary{patterns,shadings}
\begin{document}
% パターンの例
\tikz \draw[pattern=crosshatch,pattern color=blue] (0,0) rectangle (2,2);
% 関数シェーディングの例
\tikz \shade[shading=Mandelbrot set] (0,0) rectangle (2,2);
\end{document}
補足:XeTeX について

XeTeX の現状のドライバ(pdfsys-xetex.def)は(古い)dvipdfm のドライバと同程度の機能しか提供していない。しかし、XeTeX は「dvipdfmx の拡張版」を用いて PDF 生成を行っているので、dvipdfmx 用のドライバとほぼ同じ実装で同等の機能が実現できるはずである。PGF 開発のサイトSourceForge)を見ると、ごく最近(2012 年 11 月)に XeTeX 用ドライバの更新が行われていることが解る。(参照:レポジトリML)これがリリースされれば、XeTeX でも PGF/TikZ のほぼ完全な機能が使えることになるだろう。

(続く)

*1:領域を「模様で」塗りつぶす機能。TikZ の patterns ライブラリ。

*2:例えば領域をマンデルブロ集合で塗りつぶすための機能(謎)。TikZ の shadings ライブラリ。

*3:かつて「dvipdfmx のバグを回避するために代わりに dvipdfm を使う」というバッドノウハウが用いられていたが、それは現在ではもう通用しないだろう。

*4:dvipdfmx のドライバが作られたのは 2008 年頃だと思う。

*5:これは graphicx 用の xbb 自動生成などがそのまま適用されていることから判断できる。

*6:pdfTeX は「DVI ドライバ」相当部分と「TeX エンジン」相当部分の両方を兼ねているので話が解りにくくなっている。

*7:graphicx は内部で graphics を「同じドライバ指定で」読み込んでいる。

*8:先に述べた事情のため、昔は dvipdfmx を使うときにパッケージによって「dvipdfmx」と「dvipdfm」の指定を使い分ける必要があって、この方法が使えなった。そのため日本ではあまりこの方式は使われていないようである。