マクロツイーター

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

「dvipdfmxと3つのバッド・ノウハウ」に関するアレ(1)

「TeX ユーザの集い 2014」の、某ZR氏の LT に関する補足的な何か。

各バッド・ノウハウのサンプル

① ドライバ詐称

% upLaTeX 文書
\documentclass[a6paper,papersize,uplatex]{jsarticle}
\usepackage[dvips]{graphicx}
\setlength{\fboxrule}{8pt}
\setlength{\fboxsep}{0pt}
\begin{document}

\begin{center}\LARGE
{\TeX} ユーザの集い2014
\par\smallskip
\fbox{\includegraphics[width=3cm]{image.eps}}
\par\smallskip\\{\gtfamily アレ。}
\end{center}

\end{document}
  • ポイントは:
    • ドライバ指定が間違って “dvips” になっている。
    • 挿入した EPS 画像のバウンディングボックス(bbox)の左下座標が正の値である。(実際の bbox 値は [540 315 900 675]。)
  • これを TeX Live 2013 以降でコンパイルすると、画像が“ふっ飛んで”(大きくずれて)しまう。
    参照: dvipdfmx での EPS 画像挿入が最近アレな話
  • 紙面サイズを a6paper にしているのは、ふっ飛んだ画像を敢えて紙面の外にはみ出させるため ;-)
  • upLaTeX を使ってるのは「最近はそれがアタリマエ」だからで特に意味はない。

バウンディングボックス詐称

% upLaTeX 文書
\documentclass[a6paper,papersize,uplatex]{jsarticle}
\usepackage[dvipdfmx]{graphicx}
\setlength{\fboxrule}{4pt}
\setlength{\fboxsep}{0pt}
\begin{document}

\begin{center}\LARGE
\fbox{\includegraphics[clip,width=5.4cm,height=3cm,
    bb=18 162 342 342]{image.png}}
\par\smallskip\\{\gtfamily アレ。}
\end{center}

\end{document}
  • ポイントは:
    • ビットマップ画像を挿入している。
    • bb オプションに、画像本来のもつ bbox とは異なる値を指定している。
  • TeX Live 2013 以降でかつ、ドライバ(dvipdfmx.def)が v3.6 以降である」環境でコンパイルすると、bb オプションの指定が無視されたような挙動になる。
    参照: 実験レポート:LaTeX + dvipdfmx による画像ファイル挿入
  • この例では width と height を両方指定しているので、「縦方向に潰れた」ような出力になるが、もし width だけ指定したとすると、枠からはみ出して(画像全体が)入ることになる。
  • 「画像の一部だけを切り出して挿入したい」場合は、viewport オプションを使うのが正解。(後日改めて説明する。)

③ 面倒だからピクセル単位

% upLaTeX 文書
\documentclass[b4paper,papersize,uplatex]{jsarticle}
\usepackage[dvipdfmx]{graphicx}
\setlength{\fboxrule}{8pt}
\setlength{\fboxsep}{0pt}
\begin{document}

\begin{center}
\fbox{\includegraphics[bb=0 0 480 480]{image.png}}
\par\bigskip
{\fontsize{96}{96}\gtfamily アレ。}
\end{center}

\end{document}
\end{center}

\end{document}

実は、この話に関しては少し勘違いを起こしていて、発表では「画像を実寸で(width/height 非指定で)装入する」という条件を入れていた*1が実はこの条件は不要であった。*2寧ろ、width/height がある場合の方が実際のバッド・ノウハウの使用状況に近いと思うので、その場合のサンプルを示しておく。

% upLaTeX 文書
\documentclass[a4paper,papersize,uplatex]{jsarticle}
\usepackage[dvipdfmx]{graphicx}
\setlength{\fboxrule}{4pt}
\setlength{\fboxsep}{0pt}
\begin{document}

\begin{center}
\fbox{\includegraphics[width=10cm,bb=0 0 480 480]{image.png}}
\par\bigskip
{\fontsize{96}{96}\gtfamily アレ。}
\end{center}

\end{document}
  • ポイントは:
    • ビットマップ画像を挿入している。
    • 画像ファイルが解像度の情報を持っていて、それが 72 dpi ではない。(今の場合は 96 dpi。)
    • bb オプションの単位を(bp 単位ではなく)ピクセル数で指定している。
  • 2007 年 5 月以前の dvipdfmx では「ビットマップ画像の一部を切り出して挿入する」機能がサポートされていなかった。つまり、(special 命令で)bbox を指定しても、それは無視されていた。
    • このため、bb オプションの指定は、TeX エンジン側で画像の(元の)寸法を得るため目的のみで使われていた。
    • 従って、width/height の両方が指定される場合は、bb の値は全くされず、また、width/height の一方のみが指定される場合は、bb の値はその縦横の比率のみが意味をもっていた。*3
    • だから、bb の値の単位は何でもよくて、このため「ピクセル単位で指定する」という解説がしばしば行われていた。
  • ところが、2007 年 5 月以降の dvipdfmx では、ビットマップ画像の切り出し挿入がサポートされ、このため bbox 指定が有効になる。
    • 従って、bb オプションの値をピクセル単位で与えると、結果的に正しい bbox とは食い違う値を指定して「bbox 詐称」をしていることになってしまう。
    • つまり、“実際の画像部分”は [0 0 360 360] の範囲にしかないのに、それより大きい [0 0 480 480] の領域を挿入しようとしてしまう。だから、画像が意図したものより小さく出力され、右上部分に空白が生じる。
    • ちなみに、“実寸で”装入した場合は、480 bp 四方の領域が取られてその左下の 360 bp 四方(これが本来の“実寸”)に画像が入ることになる。
    • TeX Live 2013 以降でかつ、ドライバが v3.6 以降である」環境では(見かけ上は)正常な出力になる。その理由は、「bbox 詐称が封印されたから」*4に他ならない。バッド・ノウハウであることは変わらない。
* * *

スライドのソース一式を公開しておく。ただし、これを見たときに受ける精神的ダメージについて作者は責任を負わないものとする。

*1:実寸(つまり 480 bp 四方)で入る余裕を持たせるため用紙サイズを b4paper にしている。

*2:一時期の dvipdfmx では、special 命令で「bbox を明示指定して実寸でビットマップ画像を読む」という指定をした時に理屈に合わない挙動をしていた。(これは完全に dvipdfmx 側の不具合である。)このことと混同して「実寸」の条件を入れてしまった。

*3:つまり、TeX エンジンが、width/height の一方から他方の値を算出するのに用いている。

*4:要するに、ドライバが bb オプションの値を dvipdfmx に渡していないのである。