Zalgo文字は、フォントが行の枠から飛び出したように見えます。
Z̴̡̛̫̹̿a̵̡̳̋l̴̙̓g̶̤̈o̷̜̽
画像でも、通常は壊れたフォントでもありません。普通の基本文字の後に多数の結合記号を置くことで生まれる効果です。
結合記号の本来の仕事
世界の文字体系には、アクセント、母音記号、声調、朗誦記号など、隣の文字と関係する記号が必要です。Unicodeはその多くを幅を進めない結合文字として符号化しています。
é は次のどちらでも表せます。
- 合成済み文字 U+00E9 LATIN SMALL LETTER E WITH ACUTE
- U+0065 LATIN SMALL LETTER Eの後にU+0301 COMBINING ACUTE ACCENT
後者のコードポイントが前者を修飾します。描画エンジンは、通常の1文字分だけカーソルを進めず、基本文字の上にアクセントを配置します。
Zalgo生成器は同じ仕組みを利用し、正常な綴りよりはるかに多い記号を上下や文字の中央へ追加します。
なぜ激しく積み重なるのか
結合文字には、基本文字の周囲で並ぶ順序を決める正規結合クラスがあります。フォントは一般的な組み合わせのためにアンカー情報を持っています。しかし珍しく長い列では、描画側が可能な範囲で処理するしかありません。
きれいに積むフォントもあれば、記号が衝突したり、隣の行へはみ出したり、ボタンから飛び出したりするフォントもあります。文字列は有効でも、何十個ものアクセントを1文字に置くレイアウトは想定されていません。
ブラウザやOSで見え方が変わるのもこのためです。Unicodeが文字と性質を定義し、フォントが形と配置を決めます。
正規化は「アクセントを削除」ではない
Unicode正規化は等価な文字列の比較を容易にします。NFCは可能なら基本文字とアクセントを合成し、NFDは合成済み文字を分解します。どちらも結合記号を正規順序へ並べます。
しかしZalgoを消す機能ではありません。極端な組み合わせの多くには合成済み文字がなく、正規化後も記号は残ります。
「普通の文字に戻す」機能を作るなら、言語に必要な記号と装飾を別途判断しなければなりません。すべて削除すると、ベトナム語、アラビア語、ヘブライ語、インド系文字などを壊します。
1つに見える文字が多数のコードポイントを持つ
Unicodeの分節規則では、基本文字と後続の結合記号を1つの拡張書記素クラスタとして扱います。é が2コードポイントでも、カーソルは1単位として動けます。
Zalgoは同じ規則を極端に使います。1文字に見えるものが10個、20個以上のコードポイントを含み、データベースの長さ制限、通知の切り詰め、選択、行高、検索、読み上げに影響します。
人が見る長さとコンピューターが保存する長さは同じではありません。
正当な基盤から生まれた装飾
結合記号は「悪い文字」ではなく、デジタルな言語表現に不可欠です。この効果は、Unicodeが複雑な文字体系を正しく支えるからこそ成立します。
問題は量と使い方です。大量の記号は画面を読みにくくし、自動処理だけが認識する差を隠すこともあります。見えないUnicode変形や同形文字が言語処理を混乱させることも研究で示されています。
画面を壊さず使うには
- 短い見出しや1単語に限定する
- 強度は低~中程度にする
- 使用先のアプリで確認する
- 内容が重要なら通常版も添える
- アカウント名、URL、メール、安全情報には使わない
Zalgoは「積み重ねるタイポグラフィ」です。基本文字は普通のまま、本物のUnicode記号が異常な形を作ります。
グリッチ文字ジェネレーターで量を調整し、上の顕微鏡で中身を確かめてください。