LuaTeXでカラーフォント・絵文字✌(SVG/COLR/CBDT)

[TeX ＆ LaTeX Advent Calendar 2019](https://adventar.org/calendars/4087) 1日目の記事です。2日目は[t-kemmochi](https://twitter.com/t_kemmochi)氏の「[xfakebold.styの紹介](https://qiita.com/t_kemmochi/items/f4f0e31c1f46768a3bce)」です。今年も「[TeX & LaTeX Advent Calendar](https://gist.github.com/zr-tex8r/c3ba9b26820235b3d026fb5e94af374d)」が始まりました。今年の重点テーマは「やっぱり[Lua(La)TeX](https://texwiki.texjp.org/?LuaTeX)しよう」です。[Lua(La)TeX](https://texwiki.texjp.org/?LuaTeX)に関する情報がたくさん集まりそうです。この記事は

![Screenshot at 2019-11-14 21-59-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259309/28f2a9ac-bb51-bb29-a289-dfdb6c379846.png)


のようなカラーフォントをLuaLaTeX（およびその親戚）で使おうという記事です。カラーフォントの応用の一つに絵文字がありますが、LuaTeXに限らずTeX一般で絵文字を少ない手間で使うには[bxcoloremoji.sty](https://github.com/zr-tex8r/BXcoloremoji)もおすすめです。

# [luaotfload 3.1以降](https://ja.osdn.net/projects/luatex-ja/wiki/%E8%B3%87%E6%96%99-luaotfload%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)
以下の作業の多くで2019年11月にリリースされた[luaotfload](https://ja.osdn.net/projects/luatex-ja/wiki/%E8%B3%87%E6%96%99-luaotfload%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)のバージョン3.1以降が必要になります。最新のluaotfloadとluatexをインストールする代表的な方法としては[TeXLive](https://texwiki.texjp.org/?TeX%20Live)と[W32TeX](https://texwiki.texjp.org/?W32TeX)があります。Debian Linuxなら[texlive-luatexパッケージの2019.20191112-1またはそれ以降のバージョン](https://packages.debian.org/testing/texlive-luatex)にも含まれるので`apt-get -t testing install texlive-luatex`でインストールすることもできます。以下ではluaotfloadの\fontコマンドを使いますが

```latex
\font\新フォントコマンド={[フォントファイル名]:フォントオプション１;フォントオプション２;...;}
```

という形式で使います。フォントの名前でもフォント指定できますが詳しくは[luaotfloadの説明書](https://www.ctan.org/pkg/luaotfload)をご覧下さい。またfontspec.styの\fontspecコマンドは

```latex
\fontspec{フォント指定}[RawFeature={\fontに与えるのと同じフォントオプション}]
```

のように使います。\fontspecに与えるフォント指定とオプションの順番は逆にしてもよいです。詳しくは[fontspecの説明書](https://www.ctan.org/pkg/fontspec)をご覧ください。

# OTF(OpenType Font)カラーフォントの形式
詳しい説明は[カラー絵文字〜OpenTypeフォントの仕様を中心に〜](https://qiita.com/496_/items/6910dd76283ba1347327)にあるため、ここでは簡単に紹介します。まず第一にOTFカラーフォントは正式なOTF規格ですが、PDF規格ではOTFカラーフォントに対応しておらず、現在使われているPDFビューワーもOTFカラーフォントを理解できないため、OTFカラーフォントをTeXが扱うためにはカラー字形を頑張ってPDF等に変換する必要があり、開発者が大変です。また字形が画像として埋め込まれることが多いためコピー＆ペーストできるようにするためにTeXが頑張る必要があります。そこらへんの苦労は[Bringing world scripts to LuaTeX: The HarfBuzz experiment, TUGBoat, vol.40, no.1, pp.38-43](https://www.tug.org/TUGboat/Contents/contents40-1.html)に詳しく書かれています。また[Picture Fonts: welcome to a (beautiful) mess](https://meeting.contextgarden.net/2017/talks/2017-09-12-hans-color-fonts/picture-fonts.pdf)にはConTeXtにおけるカラー絵文字の扱いが書いてあります。LuaTeXのカラーフォントの扱いは基本的にはConTeXtと同じになります（しかし[TeXLive 2020からはConTeXtとHarfBuzzが並立する模様](https://www.latex-project.org/news/latex2e-news/ltnews31.pdf)）。

# SVG in OpenType形式
## 欧文フォント
ベクターグラフィックスのよく用いられる形式であるSVG(Scalable Vector Graphics)がそのままフォントファイルに入っている形式です。カラー字形の表現力はこの形式が最も高く、グラデーションを含む字形はこの形式だけで表現できます。**またAdobeが推しているため絵文字以外に非常にたくさんのカラーフォントがこの形式で提供されています**。SVGはそのままPDFに書けないため、AdobeはType 3 PostScriptフォント形式に変換して埋め込み、ConTeXt/LuaTeXはinkscapeを用いてPDFに各字形を変換してそのPDFを埋め込みます。

カラー字形の変換にinkscapeを用いるのでまず[inkscape](https://texwiki.texjp.org/?Inkscape) -A file.pdf file.svgで適当なSVGファイルfile.svgをfile.pdfに変換できるようにする必要があります。上記の準備ができたら、[ColorTubeフォント](https://www.behance.net/gallery/39274241/Colortube)と[Playboxフォント](https://www.fontself.com/colorfontweek/2018#playbox)をダウンロードしてカレントディレクトリにおいて、下記のファイルを`lualatex --shell-escape`でコンパイルすると記事冒頭のPDFファイルができます。`--shell-escape`と`+svg`を付加するのがポイントです。

```latex
\documentclass{minimal}
\usepackage{bxtexlogo}
\bxtexlogoimport{LuaLaTeX}
\usepackage{fontspec}

\begin{document}
\fontspec{Playbox-FREE.otf}[SizeFeatures={Size=16},RawFeature={+svg;+kern;+liga;}]
\noindent
Color Font in \LuaLaTeX

\bigskip
\noindent
\fontspec{ColorTube.otf}[RawFeature={+svg;+kern;}]
Color Font in \LuaLaTeX
\end{document}
```

luaotfload 3.1あたりでは`texmf-dist/tex/luatex/luaotfload/fontloader-2019-10-29.lua:27743: attempt to call a nil value (field 'getindices').`というエラーが出ます。この対応策は`fontloader-2019-10-29.lua` の中の関数`otfsvg.topdf`から`getindices`を呼び出す部分を削除することです。この問題は[luaotfloadのgithub](https://github.com/latex3/luaotfload/issues/96)に連絡済みです(luaotfload 3.12で修正されたので上記のファイルは問題なくPDFに変換される)。無料のカラーフォントを配布しているページをいくつか以下に挙げます。

- [OPENTYPE SVG COLOR FONTS FREE](http://www.augetype.com/warehouse/svgfonts/colorfont-01-en.html)
- [OpenType SVG and Color Fonts Free Download](https://designcrafts.online/opentype-svg-color-fonts-free-download/)
- [21 Free Colorful Color Fonts](https://bashooka.com/resources/free-colorful-color-fonts/)
- [22 Awesome Color Fonts for Download (Free and Premium)](https://superdevresources.com/color-fonts-free-premium/)
- [5 amazing color fonts from top creatives](https://www.fontself.com/colorfontweek/2018)

## 和文フォント
SVGカラー字形を持つ初めての和文フォントとして[Source Han Code JP／源ノ角ゴシック Code JP](https://twitter.com/hatchgogo/status/933209170844643329) がありますが、以下のファイルを

```latex
\documentclass[b5paper,12pt]{ltjsarticle}

% 以下の２行はカラー字形を構成するコードポイントをJAchar扱いとする
\ltjdefcharrange{33}{"2615,"263A,"263B,"2764,"FE0F,"1F4A9,"1F512,"1F916}
\ltjsetparameter{jacharrange={+33}}

\begin{document}
\jfont\myjfont={name:Source Han Code JP:+svg;+ccmp;jfm=ujis;} at 12pt\myjfont
Source Han Code JP--源ノ角ゴシック Codeは\\
７つのカラーグリフ☕☺️☻❤️💩🔒🤖を含みます。
\end{document}
```

`lualatex --shell-escape`でコンパイルすると以下のPDFを得て、カラーフォントはluatexjaでもバッチリ扱えます。

![Screenshot at 2019-11-16 03-53-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259309/9ff2fbfe-5987-476e-f083-cdb1a122a865.png)

SVGカラー字形を**さらに踏み込んで活用した**商用和文フォントとして[「貂明朝」](https://blogs.adobe.com/CCJKType/2018/11/ten-mincho-redux-ja.html)があります。

# COLR/CPALカラーフォント形式
複数の字形と対応する色があり、それらを重ね書きしてカラー字形を表現する形式です。もともとMicrosoftが推していた形式でWindows付属のSegoe UI Emojiがこの形式です。無料で使えるフォントとしては[Twemoji Mozilla](https://github.com/mozilla/twemoji-colr/releases)があります。`TwemojiMozilla.ttf`をカレントディレクトリにおいて

```
\documentclass{minimal}
\begin{document}
\font\twemoji={[./TwemojiMozilla.ttf]:+colr;+ccmp;+dist;}
\font\segoe={name:Segoe UI Emoji:+colr;+ccmp;+dist;}
\noindent
\twemoji ⛄👨‍👩‍👧‍👦💔\\
\segoe ⛄👨‍👩‍👧‍👦💔
\end{document}
```

（TeXLive 2019の最終版に[Twemoji Mozillaが入った](https://ctan.org/pkg/twemoji-colr)ので、TeXLiveやW32TeXの最新版を使っている場合上記の`[./TwemojiMozilla.ttf]`の代わりに`name:Twemoji Mozilla`と書いても大丈夫です）を`lualatex`でコンパイルすると
![Screenshot at 2019-11-10 17-03-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259309/7bbfec51-4ee9-2dd8-3ae3-6f07f1eeb2d5.png)
というPDFができます。[💔の片方が黒くなるバグ](https://github.com/latex3/luaotfload/issues/95)が発生した場合`luaotfload`を新しくすると直ります（バージョン3.1では問題なかった）。

`+colr`を付けるのがポイントで、`fontspec.sty`を使うときは`RawFeature={+colr}`とします。Twemojiが妙に詰まっているのはフォント自体のバグ([ここ](http://tracker.luatex.org/view.php?id=1012#c1716)とか[ここ](https://github.com/mozilla/twemoji-colr/issues/50))である疑いがあります。

# CBDT/CBLCカラーフォント形式
グーグルが推す形式でPNG画像がそのままフォントファイルに入っています。 https://github.com/googlefonts/noto-emoji/tree/master/fonts から `NotoColorEmoji.ttf` をダウンロードしてカレントディレクトリに置いてください。ConTeXtがCBDT/CBLC形式を扱えないため、ConTeXtの代わりに[HarfBuzzを用いて組版できる`lualatex-dev`](http://mirror.ox.ac.uk/sites/ctan.org/macros/latex-dev/base/ltnews31.pdf)と`luaotfload 3.1以降`を用いる必要があります。TeXLiveならびにW32TeXの最新版はlualatex-devとluaotfloadの最新版を含みます。(TeXLive 2020からはHarfBuzzを用いた組版が通常のlualatexに含まれたのでlualatex-devを用いなくても大丈夫です）

```shell-session
$ lualatex-dev emoji6.tex
This is LuaHBTeX, Version 1.11.2 (TeX Live 2020/dev) 
```

のように`LuaHBTeX`と表示されることを確認してください。lualatex-devとluaotfloadの新しい版を使えるようにした上で

```tex
\documentclass{minimal}
\begin{document}
\font\twemoji={[./TwemojiMozilla.ttf]:mode=harf;+ccmp;+dist;}
\font\segoe={name:Segoe UI Emoji:mode=harf;+ccmp;+dist;}
\font\noto={[./NotoColorEmoji.ttf]:mode=harf;+ccmp;+dist;}
\noindent
\twemoji ⛄👨‍👩‍👧‍👦💔\\
\segoe ⛄👨‍👩‍👧‍👦💔\\
\noto ⛄👨‍👩‍👧‍👦💔
\end{document}
```

（TeXLive 2019の最終版に[Noto Color Emojiが入った](https://ctan.org/pkg/noto-emoji)ので、TeXLiveやW32TeXの最新版を使っている場合上記の`[./NotoColorEmoji.ttf]`の代わりに`name:Noto Color Emoji`と書いても大丈夫です）を`lualatex-dev`でコンパイルすると

![Screenshot at 2019-11-10 17-24-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259309/c79f0307-0b3d-2e1b-c94e-9acac0b309bc.png)

というPDFを得ます。`mode=harf`を付けるのがポイントで、`fontspec.sty`を用いるときは`Renderer=HarfBuzz`を付けてください。

# [LuaTeX-ja](https://texwiki.texjp.org/?LuaTeX-ja)で絵文字を用いるときの注意点
[LuaTeX-ja](https://texwiki.texjp.org/?LuaTeX-ja)はunicodeコードポイントを和文(JAchar)と欧文(ALchar)に分けて扱っています。また[unicode絵文字は複数のコードポイントから構成されることがあります](https://qiita.com/nonanona/items/b148c212ba7c24942e93)。絵文字を構成するコードポイントは基本的にALcharですが一部JAcharになっていることがあります。文章中の絵文字の中のコードポイントが一部JAcharになっているとうまく絵文字が出ません。例えば

```latex
\documentclass[b5paper,12pt]{ltjsarticle}
\usepackage{luatexja-fontspec}
%\input emojialchar.tex

\begin{document}
\fontspec[Renderer=HarfBuzz]{NotoColorEmoji.ttf}\noindent
ふえぇ❣️😳💦あと１ヶ月ちょっとでクリスマス🎄🎅なのに彼女💏💑💕がいないって
やば❕❓😱💦⤵️このままだと令和最初‼のクリスマス🎄✨は😦クリ
ぼっち😢💔😖⤵️ぴええん😭💔実は🙊💭フォロワーさんの中に🌝✨好きな
人😘👦💕がいるんだけどＤＭで告白💐💌💖してくれたら
オケ🙆‍♂️✨するのになぁ❤😘
\end{document}

```

を`lualatex-dev`でコンパイルすると
![Screenshot at 2019-11-12 07-37-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259309/5d16bf9c-ee6c-c0a0-b04b-21ed16de0983.png)

のように一部の絵文字が豆腐になります。対処法としては絵文字の中に現れるコードポイントを全部ALchar扱いにするお呪い（詳しくは[LuaTeX-jaの説明書の4.1節](https://ja.osdn.net/projects/luatex-ja/wiki/Documentation)を熟読）を使うと期待通りにPDFを生成します。絵文字に現れるすべてのコードポイントをALchar扱いにするファイルを[emojialchar.tex](https://github.com/emojifreak/All-Emoji-by-HarfTeX-and-LuaTeX-ja/blob/master/emojialchar.tex)に置いてあります。`emojialchar.tex`を`\input`などで読むと先程の豆腐が消えて以下のようなPDFを正しく得られます。

![Screenshot at 2019-11-12 07-36-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259309/ab06da24-9b93-4ae6-9189-9ef4ed30d70e.png)

最初は「🙆‍♀️ ♂」だったのが「🙆‍♂️」の表示が変わっているところが若干興味深いです。これは♂がJAcharなので「🙆‍♂️」がALcharの「🙆‍♀️」とJAcharの「♂」に分解されていることに起因します。一つの絵文字の中にJAcharとALcharが混在すると一つの絵文字が複数の文字に分割されて組まれることは[おそらく仕様です](https://osdn.net/projects/luatex-ja/ticket/39740)。また`fontspec`の代わりにluaotfloadの[\fontコマンドを使うと実行時エラーが起きますが](https://ja.osdn.net/projects/luatex-ja/ticket/39755)、すでに修正されています。

# 複数のフォントの組み合わせ
あるフォントに無い字形（例えば絵文字）を他のフォントから取ってくる方法は、
- 欧文フォントについては[luaotfload説明書の7節](https://www.ctan.org/pkg/luaotfload)に、
- 和文フォントについては[LuaTeX-jaの説明書の9.4節、10.2節、11.1節](https://ja.osdn.net/projects/luatex-ja/wiki/Documentation)に（[zr_tex8r氏による使用例](https://gist.github.com/zr-tex8r/25cbaa861994f84b7a8a874b8741be81)）
書いてあります。欧文フォントの合成の例は以下のような感じになります

```latex
\documentclass{minimal}

\font\colorfont={[./ColorTube.otf]:+svg;+kern;} at 10pt
\font\twemoji={[./TwemojiMozilla.ttf]:+colr;+ccmp;+dist;} at 14pt
\font\combo={combo: 1->\fontid \colorfont ; 2->\fontid \twemoji ,fallback}
\begin{document}
\combo
Font Combination in \TeX❣✌
\end{document}
```

![Screenshot at 2019-11-16 09-39-29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259309/273c83cd-9f7f-f041-48ce-62cd535b4104.png)


# 最後に…
過去の「[TeX & LaTeX Advent Calendar](https://gist.github.com/zr-tex8r/c3ba9b26820235b3d026fb5e94af374d)」で初日が[zr_tex8r氏](http://qiita.com/zr_tex8r)ではなかったことは皆無なので、今後のTeX界での身の振り方を考えたほうがいい気がしてきました…😱

qiita掲載の過去のTeX LaTeX Adventカレンダーの記事一覧はこれ https://qiita.com/search?q=%22LaTeX+Advent%22&sort=stock です。

この記事の手順はTeXファイルとフォントファイルが同一ディレクトリに置かれる前提でしたが、それでは面倒なので頻繁に使うフォントはシステムの標準の場所に置いてlualatexが名前でフォントを見つけられるようにしたほうが便利です。Linuxの場合にそうする手順は[Linux上のLuaTeXに手動でフォントをインストールする手順](https://qiita.com/kakinaguru_zo/items/570dccd9dbd6ec08b8ec)に説明しました。WindowsやMacでも同等なことができますがわからないので、良い説明記事をご存知でしたらコメント等で教えてください。