マクロツイーター

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

bxcoloremojiがもっとdvisvgmできるようになった話

最近、自作のパッケージのdvisvgmへの対応を進めている。既にpxchfonパッケージとbxtexlogoパッケージについて記事を書いた。本記事ではbxcoloremojiパッケージの最近(v1.2)の改修におけるdvisvgm対応の内容について説明する。

前提知識

  • dvisvgmのフツーの使い方。
  • bxcoloremojiパッケージのフツー(dvisvgm以外)の使い方。

dvisvgmでフツーに使えるようになった話

メジャーなワークフローにおいてはbxcoloremojiパッケージは「フツーに読み込むだけで取りあえず1使える」状態になっている。1.0版以降のbxcoloremojiは絵文字画像出力のためにtwemojisパッケージを利用しているが、twemojisの読込は自動で行われるので特にそれを気にする必要はない。LuaLaTeXなどのPDF出力のエンジンにおいては本当に何も気にせずただ読み込むだけでよい。

[example1.tex]
% LuaLaTeX
\documentclass[a4paper]{ltjsarticle}
\usepackage{bxcoloremoji}% 読み込むだけ!
\begin{document}
素敵\coloremoji{⛄}
\end{document}

「DVI出力エンジン+dvipdfmx」のワークフローの場合も、「常にドライバオプションをグローバルに指定する」というイマドキのLaTeXの常識に従っていれば、bxcoloremojiを使うにあたって特に気にする点はない。

[example2.tex]
% upLaTeX+dvipdfmx
% イマドキのLaTeXではドライバオプションは無条件で付ける
\documentclass[uplatex,dvipdfmx,a4paper]{jsarticle}
\usepackage{bxcoloremoji}% 読み込むだけ!
\begin{document}
やっぱり素敵\coloremoji{⛄}
\end{document}

同様に考えると「DVI出力エンジン+dvisvgm」の場合も「ドライバオプションさえ忘れなければあとは何も気にしなくてよい」となってほしい。

pxchfonパッケージの記事でも述べた通り、日本語LaTeXとdvisvgmの併用においては(pxchfonを使わない限りは)pLaTeXの使用が「無難」なので、本記事ではdvisvgm併用の例ではpLaTeXを使用する。この場合、dvisvgm実行時に--fontmap=kanjix.mapのオプション指定が必要である。

[example3.tex]
% pLaTeX+dvisvgm
\documentclass[platex,dvisvgm,a4paper]{jsarticle}% ドライバ指定したよ
\usepackage{bxcoloremoji}% 読み込むだけ!
\pagestyle{empty}% 画像なのでページ番号は不要
\begin{document}
例によって素敵\coloremoji{⛄}
\end{document}

しかし旧版のbxcoloremojiではdvisvgmは「その他大勢のDVIドライバの一つ」という扱いで、パッケージの動作の前提となる設定を自分で行う必要があった。このため先の単純な設定では次のようなエラーが発生する。

! Package bxcoloremoji Error: Package 'graphicx' is not loaded.

エラーに対処するには(ドライバ指定はできているので)単純にgraphicxパッケージを前もって読み込めばよいのだが、すると今度はtwemojisパッケージの読込が要求される。twemojisも追加すると正常に動作するが、実はこれでも最適ではない。bxcoloremojiはdvipdfmxドライバの場合に画像の挿入を高速化するため「bbオプション設定2」という手法を利用している。この手法はdvisvgmでも適用可能であるが、既定では無効になっているので、画像挿入に余計な時間がかかっている3のである。最適にするにはbbparam=trueというオプションを指定する必要がある。

つまり旧版のbxcoloremojiをdvisvgmで使おうとすると以下のように書く必要があった。これは単純に面倒なだけでなくこの「正解」に行き着くのが難しいという問題もあった。

[example4.tex]
% pLaTeX+dvisvgm
\documentclass[platex,dvisvgm,a4paper]{jsarticle}
\usepackage{graphicx,twemojis}% 別のパッケージ読込が必要でした
\usepackage[bbparam=true]{bxcoloremoji}% 'bbparam'指定も必要でした
\pagestyle{empty}
\begin{document}
例によって素敵\coloremoji{⛄}
\end{document}

新版のbxcoloremojiではこの点を改善して、dvisvgmのグローバルオプションが指定されている場合に自動的に「dvisvgm用の最適な設定」を行うようにした(dvipdfmxと同じ処置)。従って、先ほどの単純な設定のexample3.texが正常に動作するようになる。

カスタムファミリの使用を指定した場合はtwemojisを使わずに直接graphicxパッケージの\includegraphics命令で画像を挿入する形になるが、この場合も「何も気にせずに」dvisvgm上で使える。以下に示すのはbxcoloremoji-oldstdバンドル​4で提供されるカスタムファミリのtwemoji-pdfを利用した例である。

[example5.tex]
% pLaTeX+dvisvgm
\documentclass[platex,dvisvgm,a4paper]{jsarticle}
\usepackage[family=twemoji-pdf]{bxcoloremoji}% カスタムファミリ指定
\pagestyle{empty}
\begin{document}
相変わらず素敵\coloremoji{⛄}
\end{document}

相変わらず⛄️は素敵😊

dvisvgmでPNGできるようになった話

bxcoloremojiではPNG形式の画像もカスタムファミリとして使用できるが、dvisvgm上で使う場合では少し注意が必要である。

dvisvgm上でPDF形式の画像を\includegraphics命令で挿入5した場合、その画像データはSVGのコードに変換された上で出力のSVGファイル中に埋め込まれる。例えば先ほどの出力のexample5.svgの中を見ると以下のように絵文字の描画データが埋め込まれている。

<text class='f1' x='9.148144' y='53.004663'>相変わらず素敵 </text>
<g transform='matrix(.340741 0 0 .340741 73.63453 44.910091)'>
<path d='M21 19.5C21 23.641 17.641 27 13.5 27S6 23.641 6 19.5S9.359 12 13.5 12S21 15.359 21 19.5Z' fill='#e1e8ed'/>
<path d='M9 8.25C9 5.766 11.016 3.75 13.5 3.75S18 5.766 18 8.25S15.984 12.75 13.5 12.75S9 10.734 9 8.25Z' fill='#e1e8ed'/>
<path d='M17.25 4.5C17.25 5.328 16.578 6 15.75 6H11.25C10.422 6 9.75 5.328 9.75 4.5V1.5C9.75 .672 10.422 0 11.25 0H15.75C16.578 0 17.25 .672 17.25 1.5Z' fill='#414042'/>
<path d='M18.75 5.25C18.75 5.664 18.414 6 18 6H9C8.586 6 8.25 5.664 8.25 5.25S8.586 4.5 9 4.5H18C18.414 4.5 18.75 4.836 18.75 5.25Z' fill='#231f20'/>
<path d='M16.875 11.25H10.125C9.504 11.25 9 11.754 9 12.375C9 12.863 9.312 13.277 9.75 13.43V18.75C9.75 19.164 10.086 19.5 10.5 19.5H11.25C11.664 19.5 12 19.164 12 18.75V13.5H16.875C17.496 13.5 18 12.996 18 12.375S17.496 11.25 16.875 11.25Z' fill='#dd2e44'/>

これに対して、PNGなどのビットマップ画像を\includegraphicsで挿入した場合は、出力のSVGファイルには当該の画像ファイルへの参照(HTMLのimg要素のようなもの)が記される。画像を挿入したい場合、通常はそのファイルは「手許」(文書ファイル群があるディレクトリ)に置かれていて、この場合は参照は機能するだろう。例えば「絵文字『🙃』のPNG画像がカレントディレクトリにzannen.pngとして存在する」という前提で以下のLaTeX文書をSVGに変換してみる。

[example6.tex]
% pLaTeX+dvisvgm
\documentclass[platex,dvisvgm,a4paper]{jsarticle}
\usepackage{graphicx}% bxcolormoejiしない
\pagestyle{empty}
\begin{document}
ざんねん
% 普通に手許の画像ファイルを挿入した
\includegraphics[width=1zw]{zannen.png}
\end{document}

出力のSVGファイルに記されているのは描画データそのものでなくzannen.pngというファイルへの参照である。

<text class='f1' x='9.148144' y='53.004663'>ざんねん</text>
<g transform='translate(45.9975,43.792687)'>
<svg height='9.21199' overflow='visible' viewBox='0 0 72 72' width='9.2123'>
<image height='72' width='72' xlink:href='zannen.png'/>
</svg>
</g>

今のような通常のケースでは、少なくとも「出力のSVGファイルと画像ファイルを一緒に取り扱う」ことに留意していれば問題ない。しかしbxcoloremojiでPNG画像を扱う場合は、画像ファイルが「手許」にないので、画像が参照になるのは甚だ都合が悪い。実際に旧版のbxcoloremojiでPNG形式のカスタムファミリ(twemoji-png)を使おうとすると問題が起こる。

[example7.tex]
% pLaTeX+dvisvgm
\documentclass[platex,dvisvgm,a4paper]{jsarticle}
\usepackage{graphicx,twemojis}% bxcoloremojiが古いのでコレが必要
\usepackage[family=twemoji-png]{bxcoloremoji}% PNGのカスタムファミリ
\pagestyle{empty}
\begin{document}
結局のところ素敵\coloremoji{⛄}
\end{document}

この場合も先と同じ理屈に従って、絵文字の画像ファイルへの参照が記録される。

<image height='72' width='72' xlink:href='twemoji-png/twemoji-26C4.png'/>

しかしSVGファイルを扱うソフトウェアはTeXと無関係なものであるため、このパスを基にして「TeX一式のインストールの中にある画像ファイル」を見つけることが当然できない。結局、絵文字の表示は失敗してしまう。

実は、dvisvgmには「ビットマップ画像を参照ではなくデータ埋込6として扱う」ためのオプション--embed-bitmapsが用意されている。ところが残念なことに、今のgraphicxパッケージを前提にする限りはこのオプションは効果をもたない。何故かというと、graphicxパッケージのdvisvgm用ドライバの現在の実装では、ビットマップ画像を挿入するのに「dvisvgmのビットマップ画像挿入用命令7」を利用していないからである。画像挿入の処理はXMLコードを直接吐き出す実装であるため、--embed-bitmapsの影響を受けないのである。

この問題に対処するため、新版のbxcoloremojiでは「dvisvgmドライバでビットマップ画像を挿入する」場合に\includegraphicsの処理を一部修正8して「dvisvgmのビットマップ画像挿入用命令」を使うようにした。これによりdvisvgmの--embed-bitmapsオプションと併用することで「絵文字画像を埋め込んだSVGファイル」が得られるようになる。

新版のbxcoloremojiでtwemoji-pngカスタムファミリを使う例を示す。

[example8.tex]
% pLaTeX+dvisvgm
\documentclass[platex,dvisvgm,a4paper]{jsarticle}
\usepackage[family=twemoji-png]{bxcoloremoji}% PNGのカスタムファミリ
\pagestyle{empty}
\begin{document}
結局のところ素敵\coloremoji{⛄}
\end{document}

これを次の手順で変換すると「絵文字画像を埋め込んだSVGファイル」が得られる。

platex example8.tex
dvisvgm --embed-bitmaps --fontmap=kanjix.map --font-format=woff2 example8.dvi

結局のところ⛄️は素敵😊

まとめ

新版のbxcoloremojiパッケージをdvisvgmで使う方法は以下の通り。

  • 基本的に何も気にせずにフツーに読み込めばOK。
  • PNG形式のカスタムファミリを使う場合はdvisvgmに--embed-bitmapsオプションを付ける。

  1. もちろん「好みに応じてオプションを調整する」余地はあるが、既定の設定でも目的は達成できる程度には機能する。↩
  2. 現在のgraphicxパッケージのdvipdfmx上の動作では画像の外見の大きさの情報(バウンディングボックスの値)を「自動で外部コマンド(extractbb)を実行する」ことで取得しているが、この処理は外部コマンド起動のせいでかなり時間を要する。バウンディングボックスの値を\includegraphicsのbbオプションに指定するとこの処理が省略されるので、所要時間を削減できる。↩
  3. つまり高速化されていないので「ユーザが用意した画像を\includegraphicsでフツーに挿入する」のと同様に遅い、ということ。↩
  4. まだtwemojisパッケージへの移譲をしてなかった0.x版時代に標準として用いられていた画像セットをカスタムファミリの形で提供したもの。中身は0.x版の画像と全く同じなので、0.x版の画像のインストールがそのまま残っているならばこのバンドルをインストールしたのと同様にカスタムファミリ(twemoji-pdf、twemoji-png)が使える。↩
  5. もちろん、bxcoloremojiでPDF形式のカスタムファミリを使用した場合も同じである。さらに、twemojisパッケージ自体がPDF形式の画像を利用しているので、bxcoloremojiで既定のtwemojisモードを利用した場合も同じ話になる。↩
  6. これは画像ファイルの参照先をdata URL(data:imgae/png;…)にすることで実現している。↩
  7. dvisvgm:imgというdvisvgm専用のspecial命令である。↩
  8. もちろん「bxcoloremojiで絵文字画像を挿入する」場合にだけ修正が適用される。通常の\includegraphics命令の動作には影響しない。↩