マクロツイーター

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

mediabb パッケージが(あまり)役に立たない話

言葉だけでは実感として把握し難いので、実際に簡単な文書を pdfLaTeX で変換する際に PDF のバージョン指定を変えて中身をみてみよう。

[sample.tex]
% pdfLaTeX document
\documentclass{standalone}
\pdfminorversion=4
\usepackage[pdftex]{pict2e}
\pagestyle{empty}
\begin{document}
\begin{picture}(30,20)\roundcap
\thicklines\put(4,16){\line(1,0){8}}\multiput(8,6)(3.5,-3){2}{\line(0,1){10}}
\multiput(11.5,3)(0,10){2}{\line(1,0){7}}\put(11.5,8.5){\line(1,0){6}}
\put(18,6){\line(4,5){8}}\put(18,16){\line(4,-5){8}}
\end{picture}
\end{document}

上の文書は picture 環境で作成した単純な「画像の LaTeX ソース」である*1。standalone クラスを使っているので、これをコンパイルすると、picture 部分だけを含むタイトな PDF 画像ファイルが得られる。

ここで、3 行目に \pdfminorversion=4 とあるが、これは出力する PDF のバージョンを 1.4(つまり「マイナーバージョンが 4」)にするという指定である。この状態で実際にコンパイルした PDF の中身(テキストエディタで開いたもの)を以下に掲載する。

このように PDF ファイルはバイナリとテキストが混在した形式になっている。テキストの部分をよく見ると、17 行目に

/MediaBox [0 0 29.888 19.925]

という記述が見つかる。これが PDF におけるページのバウンディングボックスを表しているのである。そして実のところ、mediabb パッケージは PDF を(テキストファイルとして取扱い)直接読み込んでこの「/MediaBox」という文字列を検索することで、バウンディングボックスの値を取得しているのである。

次に、sample.tex の 3 行目を

\pdfminorversion=5

に書き換えた上で再度 pdfLaTeX でコンパイルする。これで、出力の PDF のバージョンが 1.5 になる。この中身を見比べてみよう。

先のバージョン 1.4 のものと比べると、バイナリの分量が少し増えていることが判る。(今の場合は全体のサイズが極めて小さいのでまだテキストが多いように見えるが、普通の TeX 文書の場合、バージョン 1.5 の PDF にすると大部分がバイナリになることが多い。)そして、重要なこととして、1.4 の方にあった「/MediaBox」の行がこちらでは見当たらない。それではこのファイルにはバウンディングボックスの指定が欠けているのかというと、そんなことはない。実は、1.4 の方にあった「/MediaBox」を含む一連のテキストの記述は、1.5 の方では Deflate 圧縮がかかった状態で(バイナリ部分のどこかに)格納されているのである。

これを見ると、mediabb パッケージをバージョン 1.5 の PDF に対応させることは絶望的であることが解るだろう。そもそもバイナリを完全に読む事自体が非常に困難なのである*2が、たとえそれができたとしても、TeX 言語のコードで Deflate の展開アルゴリズムを実装しなければいけないわけである。((もう一つ指摘しておく。今の mediabb は「/MediaBox」の文字列を単純に検索しているだけで、PDF の構造を一切関知していない(だから、例えば複数ページの PDF で各ページのバウンディングボックスが異なる場合などは全く正しく処理できない)。しかし、圧縮されたバイナリのチャンクを読むとなると、厳密に PDF の構造に沿ってパーズする必要が出てくるであろう。))

*1:出力サイズを小さくするため「文字」(つまりフォント)を一切含まないものにした。

*2:欧文 LaTeX ならば可能である。しかし、pLaTeX でなく欧文 LaTeX でよいのなら pdfLaTeX を使えばよいのであって、そもそも mediabb パッケージは無用である。