JDK21 で追加された Emoji サポート深掘り


JDK21 の Emoji サポート

JDK21 で java.lang.Character に絵文字関連のメソッドが6個追加されました。

public static boolean isEmoji(int codePoint)
public static boolean isEmojiPresentation(int codePoint)
public static boolean isEmojiModifier(int codePoint)
public static boolean isEmojiModifierBase(int codePoint)
public static boolean isEmojiComponent(int codePoint)
public static boolean isExtendedPictographic(int codePoint)

Character#isEmoji で絵文字かどうかを判定することができる他、Emoji Character Properties の判定用のメソッドが追加されました。

以下の Issue によるものです。

bugs.openjdk.org

絵文字の一覧はfull-emoji-listで確認することができます(環境別でどのように表示されるかを確認できます)。

実装では emoji-data.txt を元にコードポイントをキーにした Emoji properties のMapを作っているだけです。

なお、JDK21 における Unicode は 15.0 が対象バージョンとなっています(JDK22 にてUnicode 15.1 となる予定です)。


正規表現のクラスについても以下のようにそれぞれ追加されています。

Matcher emojiP   = Pattern.compile("\\p{IsEmoji}").matcher("..");
Matcher emojiPP  = Pattern.compile("\\p{IsEmoji_Presentation}").matcher("..");
Matcher emojiMP  = Pattern.compile("\\p{IsEmoji_Modifier}").matcher("..");
Matcher emojiMBP = Pattern.compile("\\p{IsEmoji_Modifier_Base}").matcher("..");
Matcher emojiCP  = Pattern.compile("\\p{IsEmoji_Component}").matcher("..");
Matcher extPP    = Pattern.compile("\\p{IsExtended_Pictographic}").matcher("..");


ここでは、Emoji Character Properties の意味について見ていきます。


Emoji Character Properties

絵文字のコードポイントには、以下のような Emoji Character Properties が定義されています。

  • Emoji(Emoji) : 絵文字の場合Yes
  • Emoji_Presentation(EPres) : デフォルトの表示形式が絵文字スタイルの場合Yes、色なしスタイルの場合No
  • Emoji_Modifier(EMod) : 前の文字を修飾する絵文字の場合Yes 人の肌の色を変更する場合に利用される
  • Emoji_Modifier_Base(EBase) : Emoji_Modifier により修飾される元の絵文字の場合Yes
  • Emoji_Component(EComp) : 通常は絵文字キーボードに個別の選択肢として表示されない絵文字シーケンスで使用される文字の場合Yes (例えば200D zero width joiner ゼロ幅接合子はEmoji:No, Emoji_Component:Yes)
  • Extended_Pictographic(ExtPict) : 将来のセグメンテーションのために使用される文字(一部の Emoji_Component 文字を除くすべての Emoji 文字が含まれる)

それぞれのコードポイントが、どの Emoji Character Properties を持つかは、以下で定義されています。

https://www.unicode.org/Public/15.1.0/ucd/emoji/emoji-data.txtwww.unicode.org


Emoji_Presentation

Emoji には、同じコードで、白黒のテキスト形式のものと、色付きのいわゆる絵文字形式のもの(または片方のみ)を持つものがあります。

Emoji_Presentation では、デフォルトでどちらの表示形式とするか を表します。 色付きの絵文字をデフォルトとする場合に、Emoji_Presentation=Yes となります。

例えば、U+2139 (information)Emoji_Presentation=No で、白黒のテキスト形式がデフォルトとなります。

色付き絵文字形式を表示することもでき、それには Unicode の異体字セレクタ(Variation Selectors) により字形を選択します。絵文字のセレクタには U+FE0F emoji variation selector があり、特定の文字の後ろにこのセレクタをつけることで絵文字を選択することができます。

逆の例で、例えば U+2615 (hot beverage)Emoji_Presentation=Yes で、デフォルトで色付き絵文字形式となります。 これには白黒のテキスト形式の字形もあり、U+FE0E text variation selector を付けることでこれを選択できます。

UNICODE EMOJI の Presentation_Style の定義にもあるとおり、どちらのプレゼンテーションスタイルで表示されるかは、その表示環境(Webページなのか、テキスト処理主体かなど)によっても異なるものとされています。

表示される字形は様々な要因次第ですが、Character#isEmojiPresentation ではUnicode上、絵文字形式での表示がデフォルトとなっているかどうかを取得することができます。


Emoji_Modifier と Emoji_Modifier_Base

肌の露出した絵文字の肌の色を変更するための emoji sequence (複数のコードでを組み合わせて1つの絵文字を構成する)です。

Emoji_Modifier=Yes となっているものは U+1F3FB ~ U+1F3FF (light skin tone ~ dark skin tone) で以下となります。

Emoji_Modifier_Base=Yes となっている絵文字は以下のものです。

Emoji_Modifier_Base 文字の後ろに、Emoji_Modifier 文字を付与することで、以下のような絵文字の表示となります(emoji modifieremoji modifier base の並びを emoji modifier sequence と呼びます)。

これらのプロパティを Character#isEmojiModifier() および Character#isEmojiModifierBase() で判断することができます。


Emoji_Component

先ほどの Emoji_Modifier のように、他の絵文字と組み合わせる(emoji sequence を構成する)ことで絵文字を構成する要素が、Emoji_Component=Yes としてマークされています。

Emoji_Component には以下のものがあります。

それぞれの使われ方を見ていきます。


emoji keycap sequence

[0-9#*] に続き、 U+FE0F(VARIATION SELECTOR-16)U+20E3(combining enclosing keycap) を加えることで emoji keycap sequence となり、以下のようになります。

emoji flag sequence

U+1F1E6..U+1F1FF(regional indicator symbol letter a..z) を2つ並べることで emoji flag sequence となり以下のようになります。

コードは ISO 3166-1 の国コードとなります。

emoji tag sequence (ETS)

emoji tag sequence は、基準となる絵文字(tag_base)に加え、それを修飾する内容をタグ仕様(tag_spec)として並べ、タグの終了(tag_end)で終わるものです。

tag_spec は U+E0020 .. U+E007E の範囲で、U+E0030.. U+E0039 が0~9、U+E0061 .. U+E007A が a~z となっており、任意のタグ内容を付与することができます。

tag_end は U+E007F 固定となります。


例えば U+1F3F4 black flag に gbeng というタグを付与することで、Flag Emoji Tag Sequences として、例えば以下のような国旗を得ることができます。

emoji ZWJ sequence

絵文字は、U+200D(ZWJ:zero width joiner) で合成し、emoji ZWJ sequence とすることができます(対応するグリフがあれば)。

ZWJ は、ゼロ幅接合子と呼ばれ、アラビア文字などを表記する際に文字を連結するために使われますが、絵文字においても使うことができます。

例えば以下のように、3つの絵文字をU+200D で以下のように合成できます。

Color を変えたり

Gender sign で性別指定したり

Direction を指定したり

様々な組み合わせがあります(Directionの指定は多くの環境で現在はまだサポートされていません)。

さらに、U+1F9B0 .. U+1F9B3 は Hair component であり、以下のように頭髪を変更できます。

先に紹介した Emoji_Modifier とは異なり、こちらは U+200D(ZWJ) で連結する必要があります。

emoji ZWJ sequence の一覧はemoji-zwj-sequences.txtで確認することができます。


まとめ

JDK21 で java.lang.Character に絵文字関連のメソッドが追加され、Emoji Character Properties の判定が可能になりました。

これらのメソッドで判定できる Emoji Character Properties の意味合いについて説明しました。 たかが絵文字ですが、Unicode Emoji の仕様はそれなりにややこしく、特に、単純に文字数を得ることができないので注意が必要です。