マクロツイーター

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

出力 PDF のバージョン(とか)を指定する

以前の記事で mediabb パッケージがアレであるという話をした。この話において、アレなことになるのは PDF のバージョンの違いが原因であった。特にバージョン 1.4 と 1.5 の間では、PDF ファイルの「書式」そのものに大きな変更が加えられているため、PDF 1.4 以前の時代に作製された古いソフトウェアは 1.5 以降の PDF を全く処理できないことが多い。

そういう「古い」ソフトウェアの使用がどうしても避けられなかったら、扱う PDF 文書(画像)の方のバージョンを古いものにするより他に仕方がない。そういう場合、既存の PDF 文書に何か「バージョンを下げる」変換を加えるという方法*1も考えらえるが、「PDF を作成したソフト」自身が「古いバージョンを指定する機能」を有するならば、そちらを利用する方がデータの劣化やトラブルが起こりにくいであろう。(「バージョンを下げる」事は、それ自体が不可避な劣化を引き起こす場合もあるので、可能な限り避けたいのは勿論である。)ここでは、LaTeX を用いて PDF 文書を作成する場合に、出力する PDF のバージョンを指定する方法について解説する。

dvipdfmx のコマンドオプションでの指定

dvipdfmx で PDF を作成する場合は、dvipdfmx の起動時オプション -V で PDF のバージョンを指定できる。ここで、-V の引数の値は「マイナーバージョン」、つまりバージョン 1.x の‘x’の部分である。*2例えば、test.dvi をバージョン 1.4 の PDF に変換したい場合は以下のようにする。

dvipdfmx -V 4 test.dvi

ところで、mediabb が使えない(/MediaBox の文字列が検索できない)事の直接的な原因は、PDF のバージョンが 1.5 であること自体というより、「オブジェクト((「PDF のオブジェクト」とは何かという話はここでは措いておく。とにかく、PDF の書式中で、「/MediaBox」等の文字列が書かれている部分のことである。))の記述が圧縮対象に含まれた」(バージョン 1.5 でそれが可能になった)ことにある。すなわち、「mediabb で読める PDF」を作るのが目的であれば、PDF のバージョンを下げる他に、「圧縮を解除する」という方法がある。*3圧縮の有無の指定するには -z オプションを使う。-z 0 で圧縮無し、-z 9 で圧縮有り*4になる。

dvipdfmx -z 0 test.dvi

-z オプションの既定値は 9(圧縮有り)である。-V オプションの既定値は環境によって異なる*5が、2010 年版以降の TeX Live では 5(バージョン 1.5)である。*6

XeTeX でのコマンドオプションでの指定

XeTeX エンジンが TeX 文書をコンパイルする時、内部では、一旦 TeX 文書を DVI 形式(の独自拡張形式((XeTeX のコマンドに -no-pdf オプションを付けて起動すると実際にこの形式のファイルが出力され、その拡張子は .xdv となっている。そのため、この独自拡張形式が「XDV 形式」と呼ばれることもある。)))に変換して、それを xdvipdfmx(dvipdfmx の拡張版)を用いて PDF に変換する、という動作を行う。ここで、後段の DVI→PDF 変換に使うコマンドは XeTeX の -output-driver オプションで指定できるので、ここで前節で紹介したオプションを入れることで、バージョン指定や圧縮指定が実現できる。(((x)dvipdfmx の -q オプションは出力メッセージを抑止するためのもので、XeTeX は普通はこれを付けて xdvipdfmx を呼んでいる。-q を外すと、いつもの dvipdfmx のメッセージが出力されるようになる。))

xelatex -output-driver="xdvipdfmx -q -V 5 -z 0" test.tex
pdfTeX の場合:pdf14 パッケージ

pdfTeX の場合、PDF 出力に関する全ての設定は、(pdfTeX 拡張の)TeX プリミティブで行うことになる。例の記事で登場している「\pdfminorversion」もその一種である。その使用は特に難しいという訳でもないのだが、必然的に「TeX の変数の設定」の文法が絡むため、どうしても「TeX レベル」の操作と見做さざるを得ない。LaTeX レベルで PDF バージョンを設定するためのパッケージとしては、pdf14 パッケージというものがある。名前の通り、「出力 PDF バージョンを 1.4 にする」機能を提供する。(pdfLaTeX/LuaLaTeX 専用である。)LaTeX 文書において、

\usepackage{pdf14}

でパッケージを読み込むと PDF 出力について以下の設定が行われる。

  • バージョンが 1.4 になる。
  • オブジェクトストリームはバージョン 1.4 で非対応なので、その使用が抑止される。従って、「オブジェクトの記述」に対し圧縮が施されることがなくなる。
出力 PDF バージョンの既定値

出力 PDF のバージョンについて、TeX Live では長らく 1.4(pdfTeX 系・dvipdfmx 系ともに)を既定値としていた。先述の通り、 1.4 と 1.5 の間に大きな(前方)非互換がある(かつ普通の TeX の出力で 1.5 にする“必要性”が無い)からである。しかし、2010 年版において出力バージョンの既定値が 1.5 に変更された。その理由は以下のようなものであろう。*7

  • PDF 用のソフトウェアの多くがバージョン 1.5 対応の版に更新されている、または 1.5 対応の別のソフトウェアにより代替されている。
  • 既にバージョン 1.5 の PDF ファイルが多く流通していて、それを画像として TeX 文書に挿入するには TeX 側の出力 PDF バージョンも 1.5 にする必要がある。
  • 相変わらず普通の TeX の出力で 1.5 にする“必要性”はない((LaTeX のパッケージの実装において、PDF の新しいバージョンの機能を利用する場合には、適切な出力バージョンを指定する(\pdfminorversion の値を設定する)責任はパッケージの実装者にある(つまりエンジンが勝手に判断してはくれない)のであるが、現状では、必要なバージョン設定を行っていない場合が結構存在するらしい。))が、1.5 にするとオブジェクトの記述の圧縮が有効になるため、出力 PDF のサイズが小さくなるという“有益性”がある。

2 番目の項目について補足すると、pdfTeX と dvipdfmx のどちらも「古いバージョンに対応するように文書データを(書式変換以外の意味で)加工する」という機能は持たない(と思われる)ので、バージョン 1.4 の PDf を出力する時にバージョン 1.5 の PDF を挿入することはできない。dvipdfmx でそれを試みるとエラーメッセージが出て失敗する。pdfTeX では警告が出て処理そのものは続行されるが、「1.5 の機能を含んでいるのに 1.4 であると詐称している」PDF 文書が生成される可能性があるので、少なくとも PDF 規格に詳しくない素人はそういう警告が出る行為はしてはいけない。

このように過去においてバージョンの既定値が 1.4 から 1.5 に変更された事が、pdf14 という「バージョンを 1.4 にする」ことに特化したパッケージが用意されている理由である。

でも LaTeX 文書中でバージョンとか設定したいよね

そういう訳で、現状では pdfLaTeX において出力 PDF のバージョンや圧縮を自由に設定する(例えば「バージョン 1.5 のままで圧縮だけ無効にする」など)ための方法は用意されていない。また、実は dvipdfmx を利用する場合でも PDF バージョン設定を TeX 文書内で行う方法はある((pdf:minorversion という PDF special 命令がある。残念ながら圧縮の設定(-z オプションに相当するもの)の命令は存在しないようだ。))のだが、それを利用する LaTeX パッケージも現状では存在しない。

で、作ってみた。

次のように、所望の設定をパッケージオプションで指定してパッケージを読み込むだけである。

\usepackage[1.5,noobjcompress]{bxpdfver}

次のようなオプションが指定できる。(詳細は説明書を参照。)

  • dvipdfmx: dvipdfmx を使う場合に指定するドライバオプション。pdfTeX・LuaTeX・XeTeX を使う場合はドライバオプションは指定しない。
  • 1.5: バージョン指定。1.41.51.61.7 の何れかを指定する。省略した場合はシステムの既定値を引き継ぐ。
  • nocompress: 全てのストリームの圧縮を抑止する。pdfTeX・LuaTeX でのみ使用可能。
  • noobjcompress: オブジェクトストリームの使用を抑止する。この場合、「オブジェクトの記述」に対する圧縮が行われなくなる。pdfTeX・LuaTeX でのみ使用可能。((詳細は省略するが、nocompressnoobjcompress は絹としては全く独立である。後者は実際には何らかの圧縮を抑止するものではない。))

また、プレアンブルで \setpdfversion 命令を実行することでもバージョンを指定できる。*8

\setpdfversion{1.4}% バージョンを 1.4 にする
\setpdfversion{image.pdf}% image.pdf のバージョンに合わせる

*1:例えば一度 Acrobat で開いた後、古いバージョンを指定して保存する、等。

*2:現状で指定されうる PDF バージョンは 1.4、1.5、1.6、1.7 の何れかに限られる。つまり、マイナーバージョンは 4〜7 の範囲の整数。

*3:ただ、「バージョン 1.4 を指定する」場合はストリームの圧縮は行われるのに対して、「圧縮を解除する」場合は全ての圧縮が抑止されるので、ファイルサイズが大きくなる。といっても、その PDF を画像として他の PDF 文書に埋め込んだ場合、埋込先の PDF 出力の設定で圧縮を許可していれば、埋め込んだ PDF に由来すデータにもその効力が及ぶはずである。つまり、「その画像を埋め込んだ PDF 文書」にはサイズ膨張の影響は及ばない。

*4:詳しく言うと、1〜9 が圧縮有りで、値が大きい方が圧縮率が良くなり、小さい方が処理が軽くなる。ただし、dvipdfmx や pdfTeX が用いている圧縮アルゴリズム(Deflate 圧縮)は元々非常に処理が軽いので、最も圧縮率の良い「9」を選んでも現在の機器の性能では十分に速い。なので恐らくは実用上は「0(圧縮無)」が「9(圧縮有)」しか用いられない。

*5:設定ファイル dvipdfmx.cfg に記載されている。

*6:この後に述べる「バージョンの既定値」に関する話も参照されたい。

*7:TeX Live のドキュメントおよび pdf14 のマニュアルの記述から推察した。

*8:圧縮設定のための命令も存在する。詳細は説明書を参照されたい。