第24章 双方向性(BIDI)

24–1 双方向性とは

英語のような左から右に書く文章の中にアラビア文字やヘブライ語のような右から左に書く文字が混在することがある。これをBIDI(双方向性)という。Unicodeの文字データベースでは、各文字に表24・1 Unicodeの双方向性文字タイプに示すような双方向性の特性値を定義している。

表24・1 Unicodeの双方向性文字タイプ
分類 タイプ 説明 方向制御コード名、一般の文字
強い L 左から右 LRM、アルファベット、シラビック、漢字、欧州・アラビア語以外の十進数
LRE、LRO左から右LRE、LRO
R右から左RLM、ヘブライ語のアルファベットと主要な句読点
AL右から左アラビア語、Thaana、シリア語のアルファベット、それらの言語特有の主要な句読点
RLE,RLO右から左RLE,RLO
弱いPDF方向性の回復PDF
EN欧州の番号欧州の十進数、東Arabic-Indic系の十進数
ES欧州の番号区切りプラス記号、マイナス記号
ET欧州の番号終了温度、通貨記号
ANアラビア文字番号Arabic-Indicの十進数、アラビア文字の十進、千単位の区切り
CS普通の番号区切りコロン、コンマ、フル・ストップ、No-Break-Space
NSM非空白区切りUnicodeでMn、Meとマークされた文字
BN中立の境界上記以外の整形、制御記号
中立 Bパラグラフ区切りU+2029パラグラフ区切り、改行機能
Sセグメント区切りTab
WSホワイトスペース空白、数字の空白、行の区切り、FF、一般的な禁則空白
ONその他中立他の全ての文字、Object Replacement Characterなどを含む

Unicode Consortium.“The Unicode Standard, Version 5.0.” Addison-Wesley, 2007. p.1257 を元に作成

また、表24・2 Unicodeの方向制御コードに示す方向制御用の文字コードを追加している。方向制御コードは表示の順序を決定するためにのみ使用する。このコードはパラグラフ単位で有効でパラグラフ区切(U+2029)で効果が終了する。

表24・2 Unicodeの方向制御コード
分類 コード 名称説明
埋め込み RLEU+202BRight-to-Left Embedding 続く文字を右から左へ埋め込む
LREU+202A Left-to-Right Embedding続く文字を左から右へ埋め込む
オーバライド RLOU+202E Right-to-Left Override続く文字は右から左方向として扱う
LROU+202D Left-to-Right Override続く文字は左から右方向として扱う
終了PDFU+202C Pop Directional Formatting双方向性の状態を、直前のLRE、RLE、RLO、LROの状態に戻す
暗黙の双方向性マーク RLMU+200F Right-to-Left MarkRight-to-Left ゼロ幅マーク
LRMU+200E Left-to-Right MarkLeft-to-Right ゼロ幅マーク

Unicode Consortium.“The Unicode Standard, Version 5.0.” Addison-Wesley, 2007. p.1253を元に作成

W3Cの“Unicode in XML and other Markup Languages”では、表24・2 Unicodeの方向制御コードに示した文字のうち、埋め込み・オーバライド・終了(LRE、RLE、LRO、RLO、PDF:U+202A..U+202E)は、マークアップと同時に使うのが適切でない(Characters not Suitable for use With Markup)が、暗黙の双方向性マーク(RLM、LRM:U+200E、U+200F)は、マークアップと同時に使うのが適切である(Format Characters Suitable for Use with Markup)とされている。テキストにコードを埋め込むと編集時の保守性が下がるため、XMLドキュメントではできるだけ上位のマークアップで指定する方がコンテキストが明確になり保守性も良くなる。XSL-FOではUnicodeの方向制御コードの代わりにfo:bidi-overrideを使うべきである。本章での説明はBIDIについての基本的な理解のためである。

24–1–1 Unicode BIDIアルゴリズム

進行方向の異なる文字が入れ子になっていると、文字の進行方向に関して曖昧さが生まれることがある。これを処理するため、Unicodeの仕様ではBIDIアルゴリズムを定義している。これは文字の特性に基づく暗黙の部分と、埋め込み、オーバライドを明示的に制御する部分がある。Unicode BIDIの処理はテキストのストリームに対して次の3段階の処理を行う。

  1. インプットされたテキストをパラグラフに分解する。
  2. テキストの埋め込みレベルを解決する。文字の双方向特性とUnicodeの方向制御コードを使って、解決済みの埋め込みレベルを決定する。
  3. テキストを行に分解した後で、解決済みの埋め込みレベルを使って行単位でテキストを表示のために並び替える。

埋め込みレベルを決定する部分がUnicode BIDIアルゴリズムの中核である。Unicode BIDIでは、パラグラフを同じ方向性をもつ文字の並びに分解し、各並びに埋め込みレベルを付与する。この際、オーバライド・コード(RLO、LRO)の個所は、文字自体のもつ方向性をオーバライド・コードで指定した方向性に切り替える。

各文字の解決済み埋め込みレベルはパラグラフの埋め込みレベルと等しいかそれより大きくなる。右から左へのテキストは奇数になり、左から右へのテキストは偶数になる。例えば英語のパラグラフでは英語の埋め込みレベルは0、それに埋め込まれたアラビア語のテキストは1、さらにその中に埋め込まれた英語のテキストは2である。それに加えて、数字のテキストはパラグラフよりも大きなレベルになる。

次に同じ埋め込みレベルの中で、十進数、数字の区切りなどの弱い方向性、空白などの中立文字を処理して、解決済みの埋め込みレベルを決定する。

24–2 ニュートラル文字とミラーリング

ラテンアルファベットやアラビア文字のように強い方向性を持つ文字以外に、中立(ニュートラル)の文字がある。スペースや括弧などの記号類は中立である。括弧のような対になった文字がRight-to-Leftの状態になった場合、グリフを左右反転させる処理がある。これをミラーリングという。Unicodeではこのミラーリング対象の文字一覧を定めている。

例えば、FOの中でアラビア語を括弧で括った文字列の場合

<fo:block>‭شصض(شصض) ENGLISH‬</fo:block>(アラビア文字列の先頭にU+202Dを置き、強制的に左から右に並べている。)

一般的に中立の文字は周辺の文字の方向性に影響を受ける。Left-to-RightとLeft-to-Rightにはさまれた文字はLeft-to-Rightになり、Right-to-LeftとRight-to-Leftにはさまれた文字はRight-to-Leftになる。この周辺の方向性が対立した場合は、上位の方向性(つまりfo:blockのwriting-mode)に従う。そこで上のfo:blockの部分は、次のように組版される。

شصض (شصض) ENGLISH

左から二つ目(右側)の“)”は反転しない。この問題を解決するにはUnicodeの方向制御コードを使う、二つの方法がある。

①左から二つ目の“)”の後にRLM(U+200F)を挿入して、右から左に書くコンテキストであることを明確にする。

<fo:block>‭شصض (شصض) &#x200F;ENGLISH‬</fo:block>

②アラビア文字列をRLE(U+202B~U+202C)で囲む。

<fo:block>‭&#x202B;شصض (شصض) &#x202C;ENGLISH‬</fo:block>

この二つはいずれも次のように表示される。

شصض (شصض) ‏ENGLISH

24–3 fo:bidi-override

fo:bidi-overrideは、Unicode BIDIのアルゴリズムに対してテキストの文字列を特定の方向に向かって書くことを強制する。unicode-bidiとdirectionプロパティの二つでインラインFOの、Unicode BIDIアルゴリズムで使用するinline-progression-directionをセットする。

24–3–1 方向制御

プロパティunicode-bidiプロパティで指定した値は、マークアップを削除して、あたかも方向制御コードを付加したテキスト文字列のようにUnicode BIDI処理に受け渡される。

表24・3 unicode-bidiプロパティ
プロパティ値説明
normal(初期値)双方向性のアルゴリズムに関連して、新しいレベルの埋め込みを開始しない。
embedインラインレベルの要素については、双方向性アルゴリズムに関連して新しい埋め込みを開始する。この埋め込みの方向は、directionプロパティで与えられる。要素の内部では、暗黙のうちに並び替えを行う。これは、開始点ではLRE(U+202A、direction="ltr"に対して)または、RLE(U+202B、direction="rtl"に対して)に相当し、終了点ではPDF(U+202C)に相当する。
bidi-overrideインラインレベルの要素またはインラインレベルのみを含む要素では、オーバーライドを生成する。言い換えると、並び替えでは双方向性アルゴリズムを無視してdirectionプロパティの指定する順序通りとなる。これは、開始点ではLRO(U+202D、direction="ltr"に対して)または、RLO(U+202B、direction="rtl"に対して)に相当し、終了点ではPDF(U+202C)に相当する。

24–3–2 方向指定

プロパティdirectionプロパティは、unicode-bidi="embed"またはunicode-bidi="override"とともに指定して、Unicode BIDIアルゴリズムのための、ブロックのライティング方向と埋め込みとオーバーライドの方向を指定する。

この他、表の欄のレイアウト、水平方向のオーバーフロー、text-align="justify"を指定した時の段落の不完全な最終行の位置を指定する。writing-modeプロパティとの整合性をたもつため、directionプロパティは、そこに適用されるwriting-modeプロパティと同じ初期値を持つ。もし、同じFOにdirectionプロパティが明示的に指定されていれば、directionプロパティは、writing-modeからセットするinline-progression-directionを上書きする。

directionプロパティはグリフがベースラインに対して直立する文字だけに影響を与える。つまり、横組ではグリフが回転していない文字列に対して、縦組ではグリフが回転する文字列に対して有効である。

表24・4 directionプロパティ
プロパティ値説明
ltr(初期値)左から右方向
rtl右から左方向

ニュートラルとミラーリングの項で方向整形コードを使った例は、fo:bidi-overrideを使っても同様のことができる。

24–3–3 fo:bidi-overrideを使った例

<fo:block>
  &#x0634;&#x0635;&#x0636; (&#x0634;&#x0635;&#x0636;) ENGLISH
</fo:block>
<fo:block>
  <fo:bidi-override unicode-bidi="embed" 
                  direction="rtl">
  &#x0634;&#x0635;&#x0636; (&#x0634;&#x0635;&#x0636;) 
  </fo:bidi-override>
  ENGLISH
</fo:block>

上の行は左からアラビア文字を3文字、開き括弧、アラビア文字3文字、閉じ括弧、ラテンアルファベットを並べている。下の行はアラビア文字の区間をfo:bidi-overrideで方向を明確化する。組版結果は次の通り。

images/bidi-override.png

図24・1 bidi-overrideの組版例