GPOS テーブル (2)

GPOS LookupType 4〜6
ここでは、GPOS の LookupType 4〜6 を解説します。

3つとも、マークグリフの配置を行います。
プログラム
>> 24_gpos_type4.c

GPOS の LookupType 4〜6 のデータを表示するプログラムです。
共通テーブル
LookupType 4〜6 で共通して使われるテーブルです。
MarkArray
各マークグリフのクラス値と、Anchor テーブルへのオフセット位置のリストです。

※ class = 0 は明示的に指定する必要があります。

uint16 markCount配列の数
MarkRecord markRecords[markCount]MarkRecord の配列。
マークグリフの Coverage テーブルの各グリフに対応している。

▼ MarkRecord
uint16 markClassマークグリフのクラス値
Offset16 markAnchorOffsetAnchor テーブルへのオフセット位置。
(MarkArray の先頭を 0 とする)
LookupType 4 (ベースグリフにマークを配置)
ベースグリフ (通常の単一グリフ) にマークを配置します。

サブテーブルのフォーマットは1つのみです。
Format 1
uint16 posFormatフォーマット番号 = 1
Offset16 markCoverageOffsetマークグリフの Coverage テーブルへのオフセット位置。
(サブテーブルの先頭を 0 とする)
Offset16 baseCoverageOffsetベースグリフの Coverage テーブルへのオフセット位置
uint16 markClassCountマークグリフのクラス数
Offset16 markArrayOffsetMarkArray テーブルへのオフセット位置。
(サブテーブルの先頭を 0 とする)
Offset16 baseArrayOffsetBaseArray テーブルへのオフセット位置

▼ BaseArray
uint16 baseCount配列の数
BaseRecord baseRecords[baseCount]BaseRecord の配列。
ベースグリフの Coverage テーブルの各グリフに対応している。

▼ BaseRecord
Offset16 baseAnchorOffset[markClassCount]Anchor テーブルへのオフセット位置。
(BaseArray の先頭を 0 とする)

各マーククラスに対応している。
使い方
まず、ベースグリフとマークグリフを、各 Coverage テーブルから検索します。

次に、MarkArray テーブルから、マークグリフのクラス値と Anchor テーブルのオフセット値を取得します。
マークグリフ側の接続位置が取得できます。

さらに、BaseArray テーブルの、指定ベースグリフの BaseRecord の位置へ飛びます。

ここには、そのベースグリフと接続する各マークグリフのクラス分の、ベースグリフ側の接続位置のデータ (のオフセット位置) が格納されています。

あらかじめ取得しているマークグリフのクラス値を添字として、Anchor テーブルのオフセット位置を取得します。

あとは、2つの接続位置が重なるように調整すれば OK です。
出力例
{Lookup} lookupType <4> | lookupFlag:0x0000 | subTableCount:1

*** SubTable (format:1) ***

## Coverage (format:1) ##

[1319] (̛) U+031B | 0

## Coverage (format:1) ##

[16] (O) U+004F | 0
[22] (U) U+0055 | 1
[42] (o) U+006F | 2
[1274] (◌) U+25CC | 3

markClassCount: 1

## MarkArray ##

[0] class:0 / {Anchor} format:1 | x:300 | y:486

## BaseArray ##

[0] mark<0> / {Anchor} format:1 | x:420 | y:646
[1] mark<0> / {Anchor} format:1 | x:503 | y:666
[2] mark<0> / {Anchor} format:1 | x:411 | y:486
[3] mark<0> / {Anchor} format:1 | x:415 | y:486

マークグリフは U+031B で、クラス値は 0、アンカー位置は (300, 486) です。

対応するベースグリフは4つで、「(O) U+004F」の場合は、アンカー位置が (420, 646) となっています。

ベースグリフの (420, 646) に、マークグリフの (300, 486) の位置が合わさるように移動すれば、
「Ơ (U+01A0)」の形状となります。
LookupType 5 (合字グリフにマークを配置)
合字グリフの各合体元の位置に合わせて、マークを配置します。
アラビア語などのフォントで存在している場合があります。

サブテーブルのフォーマットは、1つのみです。
Format 1
uint16 posFormatフォーマット番号 = 1
Offset16 markCoverageOffsetマークグリフの Coverage テーブルへのオフセット位置。
(サブテーブルの先頭を 0 とする)
Offset16 ligatureCoverageOffset合字グリフの Coverage テーブルへのオフセット位置
uint16 markClassCountマークグリフのクラス数
Offset16 markArrayOffsetMarkArray テーブルへのオフセット位置。
(サブテーブルの先頭を 0 とする)
Offset16 ligatureArrayOffsetLigatureArray テーブルへのオフセット位置

▼ LigatureArray
uint16 ligatureCount配列の数
Offset16 ligatureAttachOffsets[ligatureCount]LigatureAttach テーブルへのオフセット位置。
(LigatureArray の先頭を 0 とする)

合字グリフの Coverage テーブルの各グリフに対応している。

▼ LigatureAttach
uint16 componentCount配列の数
ComponentRecord componentRecords[componentCount]ComponentRecord の配列。
合字の元グリフの数だけある。
テキストの方向順。

▼ ComponentRecord
Offset16 ligatureAnchorOffsets[markClassCount]Anchor テーブルへのオフセット位置。
(LigatureAttach の先頭を 0 とする)
0 の場合あり。
出力例
{Lookup} lookupType <5> | lookupFlag:0x0001 | subTableCount:1

*** SubTable (format:1) ***

## Coverage (format:2) ##

[81] (ً ) U+064B | 0
[82] (ٌ ) U+064C | 1
[83] (ٍ ) U+064D | 2
[84] (َ ) U+064E | 3
[85] (ُ ) U+064F | 4
...

## Coverage (format:1) ##

[247] ( ) U+FDF2 | 0

markClassCount: 2

## MarkArray ##

[0] class:0 / {Anchor} format:1 | x:0 | y:0
[1] class:0 / {Anchor} format:1 | x:0 | y:0
[2] class:1 / {Anchor} format:1 | x:0 | y:0
[3] class:0 / {Anchor} format:1 | x:0 | y:0
[4] class:0 / {Anchor} format:1 | x:0 | y:0
[5] class:1 / {Anchor} format:1 | x:-30 | y:-15
...

## LigatureArray ##

[0] comp<0> mark<0> / {Anchor} format:1 | x:1701 | y:1702
[0] comp<0> mark<1> / {Anchor} format:1 | x:1590 | y:-210
[0] comp<1> mark<0> / {Anchor} format:1 | x:1173 | y:1620
[0] comp<1> mark<1> / {Anchor} format:1 | x:1089 | y:-258
[0] comp<2> mark<0> / {Anchor} format:1 | x:435 | y:1215
[0] comp<2> mark<1> / {Anchor} format:1 | x:489 | y:-252



U+FDF2 の合字グリフは、「U+FEDF」「U+FEE0」「U+FEEA」の3つのグリフを合体した形状です。

上の図で言うと、左側が「U+FEEA」、真ん中が「U+FEE0」、右側が「U+FEDF」です。

LigatureAttach は、この合体元の各グリフに対応しています。

接続するマークグリフが U+064B の場合、クラス値は 0、アンカー位置は (0, 0) となっています。

「U+FEDF」の位置に合わせてマークを配置する場合は、「[0] comp<0> mark<0>」のデータを使います。
図で言うと、「Anchor-2#0」の位置です。

「U+FEE0」の位置に合わせて配置する場合は、「[0] comp<1> mark<0>」のデータを使います。
図で言うと、「Anchor-2#1」の位置です。
LookupType 6 (マークグリフにマークを配置)
マークグリフに対して、マークを配置します。
フォーマット構造的には LookupType 4 と同じです。
Format 1
uint16 posFormatフォーマット番号 = 1
Offset16 mark1CoverageOffset結合させるマークグリフの Coverage テーブルへのオフセット位置。
(サブテーブルの先頭を 0 とする)
Offset16 mark2CoverageOffsetベースとなるマークグリフの Coverage テーブルへのオフセット位置
uint16 markClassCountマークグリフのクラス数
Offset16 mark1ArrayOffsetMarkArray テーブルへのオフセット位置。
(サブテーブルの先頭を 0 とする)
Offset16 mark2ArrayOffsetMark2Array テーブルへのオフセット位置

▼ Mark2Array
uint16 mark2Count配列の数
Mark2Record mark2Records[mark2Count]Mark2Record の配列。
ベースとなるマークグリフの Coverage テーブルの、各グリフに対応している。

▼ Mark2Record
Offset16 mark2AnchorOffsets[markClassCount]Anchor テーブルへのオフセット位置。
(Mark2Array の先頭を 0 とする)

各マーククラスに対応している。
LookupType 7,8
LookupType 7, 8 に関しては、省略します。
よって、GPOS はこれで終了です。