1絵文字の中にJAcharとALcharのコードポイントが混在すると複数の文字に分割されて組まれる
LuaTeX-ja を読み込まない以下のソースでも起こります.
% luatex (not lualatex) \input luaotfload.sty \font\a=ipaexm.ttf\a ❤ \bye
❤ (U+2764) は IPAex明朝に収録されていません.luaotfload 2.98 以降では,標準で存在しない文字の後に .notdef グリフ(今回の場合は U+F0000)が置かれるようになっていますが,これが悪さをしているような気がします(上のソースで ❤ を \char"F0000 に変えても同じエラーが起こります).そのため luaotfload の「仕様」ではないような気もします…….
早速ご確認ありがとうございます。 ❤を含むフォントを和文フォントにしてもdocumentclass{minimal}とは相当違うPDFができるので報告します。
\documentclass{ltjsarticle}
\usepackage{luatexja-fontspec}
\setmainjfont{Segoe UI Emoji}
\begin{document}
\font\twemoji={[./TwemojiMozilla.ttf]:+colr;+ccmp;+dist;}
\font\segoe={name:Segoe UI Emoji:+colr;+ccmp;+dist;}
\noindent
\twemoji 👩❤️💋👨\\
\segoe 👩❤️💋👨
\end{document}
をlualatexでPDFにすると添付のjatest6.pdfのようなものが手元ではできましたが、これは直感的に期待するPDFではなかったです…
documentclass{minimal}を用いた下記ファイルからできるPDFをjatest7.pdfとして添付します。希望としてはjatest7.pdfのようなものがltjsarticle.clsでもできればありがたいです…
\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}
希望としてはjatest7.pdfのようなものがltjsarticle.clsでもできればありがたいです…
LuaTeX-ja では,段落や水平ボックスが終了したとき,次のような順序で処理が進みます.
👩❤️💋👨 のような合字を組む場合は,全体が同じフォントになっている必要があるので,構成要素の全てのコードポイントが JAchar か ALchar で統一されている必要があります.ただ,JAchar ケースでは HarfBuzz 対応の部分をあまり理解していませんし,「絵文字が和文文字」とは言い難いように思うので,実質的には「全部 ALchar にする」しかないわけです.
ただ,手動設定が少なくて済むように,デフォルトの JAchar, ALchar の範囲を変えることはやって良いかもしれません.emoji_2600_27ff.txt に,U+2600--U+27FF の範囲の各文字についての次の情報を載せています.
コメントありがとうございます。ユニコードの絵文字規格で1(絵)文字が複数のコードポイントからなるというところに根本的な問題(というか規格の出来の悪さ)があるという認識ですが、理想論を申し上げればALchar/JAcharの判定手順を、「複数のコードポイントからなる1文字の中にあるコードポイント」と「単独で出てくるコードポイント」とで異なる処理をすれば絵文字の中に出てくるコードポイントがJAcharなのか問題は無くなるとは思われます。ただそれに手間を掛ける価値は少なそうで費用対効果が相当悪そうなのも認識しているので、絵文字を構成するコードポイントの一部がJAchar扱いとなっていてそういう絵文字を使うときにはそのコードポイントをALcharに使用者が設定し直す必要がある仕様である、ということでこのチケットをクローズして下さっても異存ありません。
自分はそういう現象に遭遇したら簡単に対応できるため特に困っていませんが、一般ユーザーにそれを要求するのは敷居が高い印象はあります。TeXは絵文字使うためのものではないと言われればそれまでですが…
luaotfload.sty のバグはgithubに報告しました https://github.com/latex3/luaotfload/issues/119
以下の話題も新たにチケットを起こすのがいいのかも知れませんが、続きのコメントとして書きます。
・variation selector FE0F は現状ではALcharになっています。
・FE0Fが最後に続くとfully-qualified絵文字になるがFE0Fを取り除くとunqualified絵文字になる系列がemoji 12.1にはたくさんあります。
https://unicode.org/Public/emoji/12.1/emoji-test.txt
から拾うと以下のようなものがあります(他にもあります)。 現状のコードポイントの分類では以下の例の第一コードポイントがすべてJAcharになっていて第二コードポイント(FE0F)が ALcharなので、fully-qualified絵文字がわざわざunqualified絵文字とvariation selectorに分けて扱われることになり、 あまりいい分類には見えないです。
263A FE0F ; fully-qualified # ☺️ E2.0 smiling face
263A ; unqualified # ☺ E2.0 smiling face
2639 FE0F ; fully-qualified # ☹️ E2.0 frowning face
2639 ; unqualified # ☹ E2.0 frowning face
2620 FE0F ; fully-qualified # ☠️ E2.0 skull and crossbones
2620 ; unqualified # ☠ E2.0 skull and crossbones
2763 FE0F ; fully-qualified # ❣️ E2.0 heart exclamation
2763 ; unqualified # ❣ E2.0 heart exclamation
2764 FE0F ; fully-qualified # ❤️ E2.0 red heart
2764 ; unqualified # ❤ E2.0 red heart
1F573 FE0F ; fully-qualified # 🕳️ E2.0 hole
1F573 ; unqualified # 🕳 E2.0 hole
270C FE0F ; fully-qualified # ✌️ E2.0 victory hand
270C ; unqualified # ✌ E2.0 victory hand
261D FE0F ; fully-qualified # ☝️ E2.0 index pointing up
261D ; unqualified # ☝ E2.0 index pointing up
どうも絵文字に関しては「標準でサポートするのは苦労が多い割に……」という感じがだんだんしてきています. luatexja-adjust(≒「おもちゃ箱」)のような,必要に応じて読み込む追加パッケージとして実装するのが現実的ではないでしょうか.
現在,文字範囲は原則 Unicode のブロックで決めていますが,Latin-1 Supplement と General Punctuation だけを例外として,これらの中で文字範囲を分割しています(範囲 8, 9).例えば「絵文字で用いられる頻度が高い U+2600--U+27FF でも同様に……」などとすると,収集がつかなくなり,「結果的には Adobe-Japan1 か否か」になってしまいそうな気がしています.
また,確かに JAchar/ALchar の判定を(例えば Grapheme cluster などの)sequence 単位で行うというのも面白い話です.しかし,(調べたわけではないので感覚になってしまいますが)通常のテキストだと同じ Unicode block + Variation Selector ぐらいでほとんど済むのでは,と思っています.
h7k への返信
どうも絵文字に関しては「標準でサポートするのは苦労が多い割に……」という感じがだんだんしてきています. luatexja-adjust(≒「おもちゃ箱」)のような,必要に応じて読み込む追加パッケージとして実装するのが現実的ではないでしょうか. 現在,文字範囲は原則 Unicode のブロックで決めていますが,Latin-1 Supplement と General Punctuation だけを例外として,これらの中で文字範囲を分割しています(範囲 8, 9).例えば「絵文字で用いられる頻度が高い U+2600--U+27FF でも同様に……」などとすると,収集がつかなくなり,「結果的には Adobe-Japan1 か否か」になってしまいそうな気がしています.
個人的には絵文字は無視していいんじゃないかという気はします…
すでにクロースされている #39513 と本質的に同じ気もしますがあえて新しいチケットとしています。またこの動作は「仕様」じゃないかという気もしていますが「仕様」であるならすみません。unicode絵文字の一つの文字(?)の中にJAchar扱いされる文字(?)が混じっているとエラーで止まります。例えば
%\documentclass{ltjsarticle} \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}はエラーを起こさずに(harftexやluahbtexではなくて)lualatexを用いてPDFになりますが、ドキュメントクラスをltjsarticleにすると
というエラーで止まります。luatex, luaotfload, luatexjaはTeXLiveで最新版にしています。