
2025/12/22 9:14
テキストレンダリングはあなたのことを嫌っています。
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
要約
ウェブ上でのテキストレンダリングは非常に複雑なプロセスであり、単一のシステムがすべての文字を完璧に描画することはできません。そのためブラウザはベスト・エフォート手法に頼ります。パイプライン(スタイリング → レイアウト → シェーピング → ラスター化 → 合成)は密接に結びついており、各段階が他の段階に依存しています。レンダリングは、任意のユーザー入力テキスト、カスタムフォント、色、スタイル、行折返し、およびテキスト選択などのインタラクティブ機能を受け入れる必要があります。
フォントは文字(Unicode スカラー)をグリフにマッピングします。スクリプトは言語ごとのグリフ集合であり、フォントスタイルには太字・斜体・ヒンティング・エイリアシングが含まれます。個々のフォントが必要なすべてのグリフを含むことは稀であるため、カスケード型フォールバックが不可欠です。レガチュア(複数のスカラーやグラフェムクラスを結合するグリフ)と、重なる可能性のある筆記体スクリプトはさらに複雑さを増します。HarfBuzz のようなライブラリがこれらの場合のシェーピングを処理します。
絵文字は追加の課題をもたらします。絵文字はフルカラーグリフであり、グリフ内でスタイルが変化することがあるため、色・透明度・太字/斜体化・サイズスケーリングに関する特別なロジックが必要です。アンチエイリアシングも重要な要素です。グレースケール AA とサブピクセル AA は可読性に影響しますが、サブピクセルオフセットはグリフキャッシュを破壊し、アニメーション中や半透明レイヤーの合成時に困難を生じさせます。ブラウザはそのような状況でサブピクセル AA を無効化するためにヒューリスティックを使用します。Firefox の「Component Alpha」技術はシャープネスを保つためにメモリ使用量を倍増させます。
ミドルレガチュアのスタイリング変更は依然として問題です。ほとんどのブラウザはレガチュアを分割するか、マスクで複数回描画しますが、標準的な解決策は存在しません。業界はフォントフォールバック戦略とアンチエイリアシングヒューリスティックを継続的に改良していますが、ミドルレガチュアスタイリングや絵文字スケーリングの普遍的な標準は近い将来には期待できません。
影響: エンドユーザーはウェブページで視覚的なグリッチや可読性低下を経験する可能性があります。開発者は UI 要素を設計するときにこれらのクワークを考慮し、ブラウザベンダーとフォント作成者はクロスプラットフォームの一貫性向上に取り組む必要があります。
本文
テキストレンダリングはあなたを嫌います
2019年9月28日
1 用語集
| 用語 | 意味 |
|---|---|
| スカラー (Scalar) | Unicode スカラー(コードポイント)– Unicode が定義する最小単位。 |
| 文字 (Character) | 拡張グラフェムクラスター(EGC)– 最大の単位で、複数のスカラーから構成されることもある。 |
| グリフ (Glyph) | フォントが描画する原子単位で、通常は固有 ID を持つ。 |
| 合字 (Ligature) | 複数のスカラー/文字を組み合わせたグリフ;フォントにとっては一つの文字として扱われる。 |
| 絵文字 (Emoji) | フルカラ―グリフ(例:🙈🙉🙊)。 |
フォント
| 用語 | 意味 |
|---|---|
| フォント (Font) | 文字とグリフのマッピング。 |
| スクリプト (Script) | 一つの言語に対するグリフ集合;多くのフォントは一つのスクリプトを実装している。 |
| 筆記体スクリプト (Cursive Script) | グリフが接触し流れるような書体(例:アラビア文字)。 |
| カラー (Color) | フォントで使用される RGB + α 値。 |
| スタイル (Style) | 太字/斜体修飾、ヒンティング、エイリアシング等。 |
2 スタイル・レイアウト・形状は互いに依存?
典型的なパイプライン:
- スタイリング – マークアップを解析し、フォントを問い合わせる。
- レイアウト – テキストを行に分割。
- シェーピング – 行内のグリフと位置を計算。
- ラスタライズ – 必要なグリフをアトラス/キャッシュへ描画。
- 合成 – アトラスから最終的な場所へコピー。
問題点:
- フォントにすべてのグリフが存在するわけではなく、他フォントへのカスケードが必要。
- レイアウトはシェーピングに依存し、シェーピングはレイアウトとスタイリングを必要とする → 循環依存。
解決策概要
- 先にスタイリング – カスケード内で各文字の最適フォントを、スカラーサポートを確認して決定。
- 反復的シェーピング&レイアウト – まずテキストが一行に収まると仮定し、オーバーフローするまでシェープ;その後分割・レイアウトし、必要なら再度繰り返す。
3 テキストは個々の文字ではない
- 合字は隣接文字に依存するため、HarfBuzz 等のシェーピングライブラリを使用。
- 一部言語はほぼ完全に合字で構成される(例:デベンダー・バラカラ
)。ड्ड بسم
3.1 テキストが重なる
筆記体スクリプトではグリフ同士が交差し、透明度処理に問題を起こす。正しい手順は、まず不透明な一時表面へ描画し、その後望む透明度で合成。
3.2 合字途中でスタイルが変わる
ブラウザ間で「中途半端な合字のスタイル適用」が不統一。堅牢な解決策は、マスクと異なる色を使って同じ合字を複数回描画する(Firefox の手法)。
4 絵文字がカラー&スタイルを壊す
- 絵文字は本来カラーである;一部プラットフォームは単色レイヤー、他は画像として提供。
- 太字/斜体の適用は無視されるか合成されることが多く、ブラウザは通常透明度を正しく処理。
- いくつかのシステムでは絵文字サイズを大きめに設定し、可読性向上を図っている。
5 アンチエイリアスは地獄
| AA タイプ | 説明 |
|---|---|
| グレースケール AA | ピクセルの部分的被覆 → 半透明ピクセル。 |
| サブピクセル AA | RGB サブピクセル配置を利用し、水平解像度を向上。 |
5.1 サブピクセルオフセットがグリフキャッシュを壊す
各サブピクセルオフセットは別々のラスタライズを必要とする。実務的妥協策として、水平オフセットは四分割整数にスナップし、垂直精度は不要。
5.2 サブピクセル AA は合成不可
テキストの変換(拡大・回転)でサブピクセル揃えが失われ、可視アーティファクトが発生。ブラウザは多くの場合、アニメーションや透明テキストに対してサブピクセル AA を無効化する。Firefox の Component Alpha はサブピクセル AA を合成できるが、メモリ使用量を二倍にする。
6 エソテリック
6.1 フォントに SVG が含まれることも
Adobe フォントは SVG グリフを埋め込むことがある;多くのシステムでは無視されるが、完全なレンダラーはサポートすべき(アニメーション付き SVG フォントはほぼ非対応)。
6.2 文字が大きすぎる場合
極端に大きいフォントサイズやズームレベルでスクリーンよりも大きいグリフを生成することがある。対処法:描画拒否、縮小ラスタライズ+アップスケール、または直接合成表面へ描画。
6.3 選択はボックスではない
LTR と RTL のテキストを同一行で混在させると、選択が飛び跳ねる。選択アルゴリズムは視覚順序ではなく文字列の実際の順序を追跡する必要がある。
6.4 欠落グリフをどう示すか
「トウフィ」(□) がよく表示される;Firefox はデバッグ用に一ビットピクセルアートのマイクロフォントを使用し、16進数 A–F を描画して欠落文字を可視化。
6.5 スタイルはフォントの一部(除外時以外)
フォントが本物の太字/斜体バリアントを持たない場合、合成する:斜体はギャラウィングで傾け、太字は微小オフセットで複数回描画。
6.6 理想的なテキストレンダリングは存在しない
ユーザーによって好む AA 設定やヒンティングレベルが異なる。堅牢なシステムは次の設定を公開すべき:
- サブピクセル AA の有効/無効
- 全ての AA か全くなしか
- プラットフォーム固有のチューニング(ヒンティング、スムージング、ガンマ)
Core Text、DirectWrite、FreeType 等のネイティブライブラリを活用することで、各プラットフォームの「見た目と感触」を再現できる。
7 補足リンク
- Windows は一部 TrueType フォントを修正しないと動かない
- Firefox には多くの座標空間が存在する