<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="6" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[6]</anchor-end> 
<dfn><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">レンダリング</anchor></dfn>は、
単純に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>を並べていくだけに思えますが、
実は考えなければならないことがたくさんあって、
非常に複雑で難解な処理なのです。</p><section><h1>文字とレンダリング</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="16" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[16]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>の連続の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">レンダリング</anchor>が個別の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor> (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>) 
の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">レンダリング</anchor>の連続とは異なることがあります。</p><figure class="short list"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="10" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[10]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>と表現の記述</figcaption><ul><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字コード</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">結合文字</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">合成文字</anchor></li><li><code class="charname" xml:lang="en">GCC</code></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">重ね打ち式文字合成</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">書記素クラスター</anchor></li><li><code class="charname" xml:lang="en">ZWJ</code></li><li><code class="charname" xml:lang="en">ZWNJ</code></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">制御文字</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">空白文字</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">スペース</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><sw-ch>˥˩</sw-ch></anchor>, <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><sw-ch>˩˥</sw-ch></anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">国旗絵文字</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">肌の色</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ハングル字母</anchor>の列による<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ハングル音節</anchor>の表現</li><li><code>transcoding hint: group next <var>n</var> characters</code></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">IDS</anchor></li></ul></figure><figure class="list middle"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="8" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[8]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字のレンダリング</anchor></figcaption><ul><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">連なり</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">subtending mark</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">語頭形</anchor>、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">語末形</anchor>など<ul><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アラビア文字</anchor>、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">σ</anchor>などの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor></li><li><code>1st</code> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">上付き</anchor> <code>st</code> などの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント</anchor>ごとの文脈依存<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor></li></ul></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">cursive</anchor> な場合<ul><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アラビア文字</anchor>など、それが一般的な<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">書字体系</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">筆記体</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ラテン文字</anchor>や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">草書体</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">漢字</anchor>・<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">仮名</anchor>など、そうも表現される<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">書字体系</anchor></li><li><code class="charname" xml:lang="en">ZWJ</code></li></ul></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">必要な長さに引き伸ばす</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">合字</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">カーニング</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">shaping</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフの選択</anchor><ul><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォントの選択</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">言語情報によるグリフ選択</anchor></li></ul></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">鏡文字</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">回転<title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">回転 (書字方向)</title></anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">上下反転</anchor></li><li><code class="charname" xml:lang="en">SGR</code></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">機能<title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">フォント機能</title></anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">斜体</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">イタリック</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列座標</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ラスター化</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アンチエイリアシング</anchor></li></ul></figure><figure class="short list"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="12" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[12]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>の周辺</figcaption><ul><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">語境界</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">改行</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ハイフン付け</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">改段落</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">改行記号</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">言語情報</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">書字方向</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">bidi</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ルビ</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">interlinear annotation</anchor></li><li>
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">行内構造</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アキ</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">字間</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">行揃え</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">語間</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">行間</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">改行</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">改段落</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">禁則処理</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">カーソル</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">hit testing</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">置換要素</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基線<title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">基線 (文字)</title></anchor></li></ul></figure><figure class="short list"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="58" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[58]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字のレンダリング</anchor>の処理モデル</figcaption><ul><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OpenType</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">m17nライブラリ</anchor></li></ul></figure></section><section><h1>フォント依存文字</h1><figure class="short list"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="1" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[1]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント</anchor>依存文字</figcaption><ul><li><code class="char">U+005C</code></li><li><code>~</code></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント機能</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">包摂規準</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント依存符号化</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ビルマ文字の文字コード</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">PUA</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">EUDC</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">DRCS</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">機種依存文字</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Unicode非互換割当</anchor></li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">外字</anchor></li></ul></figure></section><section><h1>OpenType の処理モデル</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="35" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[35]</anchor-end> 
<code>cmap</code> を参照する時点では、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>の転送・保管等に使う<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化方式</anchor> (いわゆる<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">外部コード</anchor>)
ではなく<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント符号化</anchor>を知っている必要があります。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Unicode</anchor> の場合、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">UTF-8</anchor> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">バイト列</anchor>や
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">UTF-16</anchor> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">サロゲートペア</anchor>等ではなく、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Unicode符号点</anchor>の列です。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="36" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[36]</anchor-end> 
<code>cmap</code> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字コード</anchor>(列)から<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフID</anchor>への<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">写像</anchor>です。
ほとんどの場合は1つの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor> (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号点</anchor>) が入力ですが、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">異体列</anchor>は1つの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">異体列</anchor>が入力となります。
従って 
<code>cmap</code>
を引くには、
入力の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>を (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">異体列</anchor>とそれ以外の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>) の列に分解する必要があります。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="37" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[37]</anchor-end> 
また、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">異体列</anchor>から <code>cmap</code> を引いた出力は
「<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基底文字</anchor>と同じ<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>」
という回答かもしれませんから、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基底文字</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号点</anchor>で
<code>cmap</code> 
をもう一度引かなければなりません。
(普通は同じ<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント</anchor>の <code>cmap</code> で<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基底文字</anchor>を引けば適切な<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフID</anchor>が返ってくるはずですが、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">データ構造</anchor>的に保証はされていませんから、エラー処理が必要となります。)</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="32" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[32]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Windows</anchor>
は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">サロゲートペア</anchor>, <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">bidi</anchor>, 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">用字系</anchor>依存の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">shaping</anchor> (文字前処理を含む。)
を 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Uniscribe</anchor>
で実装し、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OpenType Layout</anchor>
による<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>の置換と位置決定を
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OTLS</anchor>
で実装する、
という2段階構造になっているようです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="30" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[30]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Uniscribe</anchor>
は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アラビア文字</anchor>,
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ヘブライ文字</anchor>,
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">タイ文字</anchor>については、
古い <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OS</anchor>
が対応していた
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OpenType Layout</anchor>
以前の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント</anchor>にも対応しています。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="31" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;31</anchor-internal></src></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="57" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[57]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Windows</anchor> の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Chrome</anchor> で試してみると、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基底文字</anchor>に続く<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">結合文字</anchor>は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">正準再順序付け</anchor>されているようで、
そうでない順序の <code>GSUB</code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">lookup</anchor> の規則を用意しておいても無視され、
正準化された状態の <code>GSUB</code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">lookup</anchor> の規則があればそれが適用されます。
<time>2025-01-26T13:12:41.400Z</time></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="34" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[34]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">鏡像化</anchor>は <code>cmap</code> を参照する時点でも処理が必要です。
<sw-see xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"> <anchor>書字方向依存グリフ</anchor> </sw-see></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="33" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[33]</anchor-end> 
<code>vert</code> を使った<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">レンダリング</anchor>や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">縦書き</anchor>対応していない<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">レンダリング</anchor>には、
取得した<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>データの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">回転<title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">回転 (書字方向)</title></anchor>が必要となります。
<sw-see xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"> <anchor>縦書きグリフ</anchor> </sw-see></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="38" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[38]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ位置決定</anchor></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="42" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[42]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">機能<title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">フォント機能</title></anchor>については、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">justification</anchor> のために適当な<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">行</anchor>長を実現すべく、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>の置き換えや位置調整を適用し直すことがあります。
<sw-see xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"> <anchor>JSTF</anchor> </sw-see></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="51" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[51]</anchor-end> 
<code>SVG </code> による <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">SVG</anchor> 字形データがあれば、それへの置き換えを行います。
これは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフID</anchor>の列が決定した後で、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">advance width</anchor> や <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">advance height</anchor>
は変化しないはずとされています。
<sw-see xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"> <code xmlns="http://www.w3.org/1999/xhtml">SVG </code> </sw-see>
具体的にどのタイミングかまでは明らかではありませんが、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アンチエイリアス</anchor>関係の処理よりは前でしょうか。
あるいは <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">SVGグリフ</anchor>には<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アンチエイリアス</anchor>処理が適用できないとか、
通常グリフと同時処理はできないとか制約があったりするのでしょうか。</p><ed xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">
<anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="56" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[56]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">色フォント</anchor>/<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">絵文字</anchor>グリフ選択と <code xmlns="http://www.w3.org/1999/xhtml">SVG </code> の関係</ed><ol><li>
<anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="53" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[53]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">variable font</anchor> の処理<ul><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">SVGグリフ</anchor>には適用されない。</li></ul></li><li>
<anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="54" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[54]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">hinting</anchor><ul><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">SVGグリフ</anchor>には適用されない。</li></ul></li><li>
<anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="44" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[44]</anchor-end> 
<code>MERG</code> の指定に従い<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>列を併合します。</li><li>
<anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="45" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[45]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アンチエイリアシング</anchor>の処理を適用します。</li></ol><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="52" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[52]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">SVGグリフ</anchor>への置き換えや<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アニメーション</anchor>によって <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">bounding box</anchor> が変化する可能性があります。
これが<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">行</anchor>配置に影響するときは、再配置が必要になります。
<sw-see xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"> <code xmlns="http://www.w3.org/1999/xhtml">SVG </code> </sw-see></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="55" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[55]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">SVGグリフ</anchor>は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アニメーション</anchor>することがあります。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">印刷</anchor>時などのため、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">アニメーション</anchor>有効、無効の2状態の入力が必要です。</p><refs xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><ul xmlns="http://www.w3.org/1999/xhtml"><li>
<anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="31" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[31]</anchor-end> <cite xml:lang="ja-jp">OpenType glyph processing (part 2) - Typography | <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Microsoft</anchor> Docs</cite>, <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">alib-ms</anchor>, <time>2022-08-27T13:16:47.000Z</time> <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://docs.microsoft.com/ja-jp/typography/develop/processing-part2#uniscribe-in-detail">https://docs.microsoft.com/ja-jp/typography/develop/processing-part2#uniscribe-in-detail</anchor-external></li></ul></refs><section><h1>OpenType Layout の処理モデル</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="14" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[14]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OpenType Layout</anchor> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント</anchor>を使って<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>を表示する<rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文章処理クライアント<rt xmlns="http://www.w3.org/1999/xhtml">text-processing client</rt></rubyb>は、
次のようにして<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>から<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>列を得るとされています。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="13" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;13</anchor-internal></src></p><figure class="steps"><ol><li>
<anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="15" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[15]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント</anchor>の <code>cmap</code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">表<title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">OpenType表</title></anchor>に基づき、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字符号</anchor>列を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><rubyb>グリフ索引<rt xmlns="http://www.w3.org/1999/xhtml">glyph index</rt></rubyb><title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">グリフID</title></anchor>列に変換します。</li><li>
<anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="17" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[17]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント</anchor>の <code>GSUB</code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">表<title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">OpenType表</title></anchor>に基づき、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>列を編集します。</li><li>
<anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="18" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[18]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント</anchor>の <code>GPOS</code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">表<title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">OpenType表</title></anchor>と
<code>BASE</code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">表<title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">OpenType表</title></anchor>に基づき、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>の<rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">位置<rt xmlns="http://www.w3.org/1999/xhtml">position</rt></rubyb>を決定します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="19" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[19]</anchor-end> 
<rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>設計座標</anchor><rt xmlns="http://www.w3.org/1999/xhtml">design coordinates</rt></rubyb> (高解像度で装置非依存)
で装置非依存<rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>改行</anchor><rt xmlns="http://www.w3.org/1999/xhtml">line break</rt></rubyb>を決定します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="20" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[20]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">利用者</anchor>の指定がある場合、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント</anchor>の <code>JSTF</code> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">表<title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">OpenType表</title></anchor>に基づき、
<rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>行揃え</anchor><rt xmlns="http://www.w3.org/1999/xhtml">justifies the lines</rt></rubyb>をします。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="21" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[21]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">行</anchor>を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ラスター化</anchor>し、
<rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>装置座標</anchor><rt xmlns="http://www.w3.org/1999/xhtml">device coordinates</rt></rubyb> (出力装置の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">解像度</anchor>に対応するもの)
に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>群を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">レンダリング</anchor>します。</li></ol></figure><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="22" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[22]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OpenType</anchor> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">仕様書</anchor>ではこのうち最後の出力だけを <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OS</anchor>
の処理とし、他を文章処理クライアントの処理としています。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="13" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;13</anchor-internal></src>
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">装置</anchor>依存の処理かどうかで区分しているのでしょうか。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Windows</anchor> の場合他の処理も <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OTLS</anchor> を使って実装でき、
広い意味では全体が <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OS</anchor> の範疇であります。
逆に出力が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ハードウェア</anchor>でなく<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">画像ファイル</anchor>等なら全体が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">応用</anchor>レベルで実装されていることもありそうです。</p><refs xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><ul xmlns="http://www.w3.org/1999/xhtml"><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="13" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[13]</anchor-end> <cite xml:lang="ja-jp">Advanced typographic tables - OpenType Layout (OpenType 1.9) - Typography | <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Microsoft</anchor> Docs</cite>, <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">PeterCon</anchor>, <time>2022-08-28T02:47:24.000Z</time> <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://docs.microsoft.com/ja-jp/typography/opentype/spec/ttochap1#text-processing-with-opentype-layout-fonts">https://docs.microsoft.com/ja-jp/typography/opentype/spec/ttochap1#text-processing-with-opentype-layout-fonts</anchor-external></li></ul></refs></section></section><section><h1>レンダリング処理と文字性の維持</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="23" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[23]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>列に変換し<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">レンダリング</anchor>する一連の処理により、
異なる<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>が同じ<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>で表現されたり、
複数の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">合字</anchor><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>に置き換えられたり、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">表示順</anchor>が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">論理順</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>の位置関係から入れ替わっていたりしますが、
多くの場合に元の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>との対応関係を保持し続ける必要があります。</p><example xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><p xmlns="http://www.w3.org/1999/xhtml"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="24" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[24]</anchor-end> 例えば<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列の選択</anchor>からの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">コピー</anchor>を実現するためには、
選択した<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>列から元の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>が復元できる必要があります。</p></example><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="25" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[25]</anchor-end> 
異なる<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>が同じ<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>になったり、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字コード</anchor>があっても表示には直接反映されなかったりもするので、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>の列だけを使って<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>を生成するのは困難で、
入力の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>と出力の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>の対応関係を保持するのが一般的みたいです。</comment-p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="29" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[29]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">PDF</anchor> が作り方により、
または表示ソフトウェアの品質により、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">コピペ</anchor>でおかしな<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>が生成されることがある、
というのはよく知られた問題です。</comment-p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="27" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[27]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">bidi</anchor> や <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">shaping</anchor> の処理では<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>の順序が入れ替わって表示の順序が作られます。
関係性は相当複雑になるものの、元の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>との対応付けはできます。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="26" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[26]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OpenType Layout</anchor> では文章処理クライアントが<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>と<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>の関係を追跡し続けることになっています。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="13" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;13</anchor-internal></src>
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">合字</anchor><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>に置き換えられて複数<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>が1<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>にまとめられたりすることはあるものの、
対応付けを維持したままの <code>GSUB</code> による置換は容易に実現できます。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="28" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[28]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OpenType</anchor> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">フォント</anchor>は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">合字</anchor>における<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">キャレット</anchor>位置の情報を持つことが出来ます。
複数の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>が1つの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>にまとめられていても、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>単位で<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">選択範囲<title xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">文字列の選択</title></anchor>を指定することができます。
<sw-see xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"> <anchor>キャレット</anchor> </sw-see>
ただしそのような情報が欠けていることもありますし、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>が図形的に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>単位に分割できない場合もあります。
そのときは不自然な挙動になってしまいます。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="40" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[40]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">OpenType</anchor> <code>GPOS</code> <f xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><code xmlns="http://www.w3.org/1999/xhtml">lookupType</code></f> <n xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">5</n>
(Mark-to-Ligature Attachment Positioning, MarkLigPos)
は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">合字グリフ</anchor>上の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">anchor point</anchor> をいくつか指定できます。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">マークグリフ</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">配置</anchor>に当たっては、
そのいずれかの <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">anchor point</anchor> を選ばなければなりません。
<sw-see xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"> <anchor>グリフ位置決定</anchor> </sw-see></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="41" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[41]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">shaping engine</anchor> による文字前処理や
<code>GSUB</code> による<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>の置き換えがあると、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">合字グリフ</anchor>と<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">マークグリフ</anchor>の元になった<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基底文字</anchor>と<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">結合文字</anchor>の関係 (など)
は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">グリフ</anchor>列から読み取れなくなってしまうかもしれません。
しかし実装はその関係性を追跡しておかなければ<rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">なりません<rt xmlns="http://www.w3.org/1999/xhtml">must</rt></rubyb> <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="39" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;39</anchor-internal></src>。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基底文字</anchor>が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">合字グリフ</anchor>のどの部分に変化したかに応じて、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">結合文字</anchor>に由来する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">マークグリフ</anchor>をどの <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">anchor point</anchor>
を使って<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">配置</anchor>するかを決定します。</p><refs xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><ul xmlns="http://www.w3.org/1999/xhtml"><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="39" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[39]</anchor-end> 
<cite xml:lang="ja-jp"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">GPOS</anchor> — Glyph Positioning Table (OpenType 1.9) - Typography | Microsoft Docs</cite>, <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">PeterCon</anchor>, <time>2022-09-07T13:06:36.000Z</time> <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://docs.microsoft.com/ja-jp/typography/opentype/spec/gpos#lookup-type-5-mark-to-ligature-attachment-positioning-subtable">https://docs.microsoft.com/ja-jp/typography/opentype/spec/gpos#lookup-type-5-mark-to-ligature-attachment-positioning-subtable</anchor-external></li></ul></refs></section><section><h1>動的なフォント変更</h1><p><sw-see xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"> <anchor>font-display</anchor>, <anchor>CSSアニメーション</anchor> </sw-see></p></section><section><h1>セキュリティー</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="4" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[4]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字のセキュリティー</anchor>参照。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="3" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[3]</anchor-end> <cite xml:lang="ja">あるUNICODE文字がAppleデバイス上でアプリを破壊する――iOS、Mac、Watchの主要ソフトすべてに影響 | TechCrunch Japan</cite>
(<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Taylor Hatmaker</anchor>著, <time>2018-02-19 16:13:56 +09:00</time>)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://jp.techcrunch.com/2018/02/16/2018-02-15-iphone-text-bomb-ios-mac-crash-apple/">http://jp.techcrunch.com/2018/02/16/2018-02-15-iphone-text-bomb-ios-mac-crash-apple/</anchor-external></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="5" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[5]</anchor-end> <cite xml:lang="ja">#PS4 特定の文字列のメッセージを受け取るとクラッシュする事案が多数発生しているらしい…対処法はあるようなのでやってみて - Togetter</cite>
(<time>2018-10-15 21:56:42 +09:00</time>)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://togetter.com/li/1276875">https://togetter.com/li/1276875</anchor-external></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="7" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[7]</anchor-end> <cite xml:lang="ja">AppleのOSをクラッシュさせる文字列がまた見つかる | スラド IT</cite>
(<time>2020-04-26 11:17:35 +09:00</time>)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://it.srad.jp/story/20/04/25/2016238/">https://it.srad.jp/story/20/04/25/2016238/</anchor-external></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="49" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[49]</anchor-end> 
<cite xml:lang="ja">Mac OS XとiOSで特定のアラビア語文字列を表示させるとクラッシュする問題が見つかる | スラド アップル</cite>, <time>2024-01-22T13:43:32.000Z</time> <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://apple.srad.jp/story/13/09/03/0824238/">https://apple.srad.jp/story/13/09/03/0824238/</anchor-external></p></section><section><h1>テスト</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[2]</anchor-end> <cite xml:lang="en">unicode-org/text-rendering-tests: Test suite for text rendering</cite>
(<time>2017-05-16 13:12:37 +09:00</time>)
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://github.com/unicode-org/text-rendering-tests">https://github.com/unicode-org/text-rendering-tests</anchor-external></p></section><section><h1>関連</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="9" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[9]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">レタリング</anchor>とは違います。</p></section><section><h1>メモ</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="11" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[11]</anchor-end> <cite xml:lang="en">Text Rendering Hates You</cite>, <time>2021-07-07T04:15:13.000Z</time>, <time>2021-11-15T08:57:15.274Z</time> <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://gankra.github.io/blah/text-hates-you/">https://gankra.github.io/blah/text-hates-you/</anchor-external></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="43" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[43]</anchor-end> <cite xml:lang="ja">ケケモコソカメニハさんはTwitterを使っています: 「Qtさんフォールバックフォントを選ぶときに隣接する文字を考慮するらしく、こういうことが起きます。 スクリーンショットの状況はUbuntu Monoが◆を持っていないため。左の◆はDejaVu Sans Mono、aはUbuntu Mono、「あ」と右の◆はNoto Sans Mono CJK JP。 https://t.co/AKD9HfhYiJ」 / Twitter</cite>, <time>午前3:39 · 2022年11月9日<attrvalue xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">2022-11-08T18:39:28.000Z</attrvalue></time>, <time>2022-11-09T04:52:53.000Z</time> <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://twitter.com/ytomino/status/1590051393716768768">https://twitter.com/ytomino/status/1590051393716768768</anchor-external></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="46" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[46]</anchor-end> <cite>クメール文字が書けない - Helpfeel社のScrapboxを一部公開</cite>, <time>2023-07-06T09:34:07.000Z</time> <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://scrapbox.io/nota-private-sample/%E3%82%AF%E3%83%A1%E3%83%BC%E3%83%AB%E6%96%87%E5%AD%97%E3%81%8C%E6%9B%B8%E3%81%91%E3%81%AA%E3%81%84">https://scrapbox.io/nota-private-sample/%E3%82%AF%E3%83%A1%E3%83%BC%E3%83%AB%E6%96%87%E5%AD%97%E3%81%8C%E6%9B%B8%E3%81%91%E3%81%AA%E3%81%84</anchor-external></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="47" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[47]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor> (の情報システム上での表現) の知識がない技術者が設計すると <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="46" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;46</anchor-internal> のようなことが起きる。
欧米の技術者がシステムを設計するとアジア人が使えないものができるのと同じ原理。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="48" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[48]</anchor-end> 
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">書記素クラスター</anchor>にうまく分割できればいいみたいな話になってるけど、それで<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">語頭形</anchor>とかの表示ちゃんとできてるんだろうか?</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="50" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[50]</anchor-end> 
<cite xml:lang="ja">Unicode はサービス拒否攻撃のリスク有り (#2767675) | iOSベータ版に「肌の色を指定できる」絵文字が登場 | スラド</cite>, <time>2024-01-23T13:56:08.000Z</time> <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://srad.jp/comment/2767675">https://srad.jp/comment/2767675</anchor-external></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="59" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[59]</anchor-end> 
<cite xml:lang="ja">XユーザーのMasato Kinugawaさん: 「合字になる1文字目に ::first-letter で色を変えるスタイルを適用するとどうなるか、さらにフォントサイズを変えるとどうなるかのテスト。ブラウザごとにバラバラ。 https://t.co/VLXvcLZOt7 https://t.co/YKuG9Nr4Xq」 / X</cite>, <time>午前0:37 · 2024年7月5日<attrvalue xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">2024-07-04T15:37:02.000Z</attrvalue></time>, <time>2025-12-07T10:23:53.000Z</time> <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://x.com/kinugawamasato/status/1808887754090295805">https://x.com/kinugawamasato/status/1808887754090295805</anchor-external><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="60" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[60]</anchor-end> 
<cite xml:lang="ja">XユーザーのMasato Kinugawaさん: 「合字になる1文字目を:before + contentに置き、残りをテキストとして置いた場合、合字ができるかどうか(とついでにスタイルがどうあたるか)のテスト。 Chrome/Firefoxで合字ができた。CSS injectionで合字経由で文字列をリークする時にprefixとして便利な場合がありそう。 https://t.co/M9cXH4nPT3 https://t.co/s35tslFJq4」 / X</cite>, <time>午前2:07 · 2024年7月5日<attrvalue xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:">2024-07-04T17:07:47.000Z</attrvalue></time>, <time>2025-12-07T10:23:53.000Z</time> <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://x.com/kinugawamasato/status/1808910589135368687">https://x.com/kinugawamasato/status/1808910589135368687</anchor-external></li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="61" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[61]</anchor-end> <cite>WebKit Features for Safari 26.2 | WebKit</cite>, <time>2025-12-16T02:29:09.000Z</time> <anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="https://webkit.org/blog/17640/webkit-features-for-safari-26-2/#text-shaping-across-inline-boxes">https://webkit.org/blog/17640/webkit-features-for-safari-26-2/#text-shaping-across-inline-boxes</anchor-external></p></section></body></html>