/
922.txt
463 lines (373 loc) · 18.7 KB
/
922.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
[61] [DFN[[CODE[GSUB]]]] は[[グリフ]]の置き換えを、
[DFN[[CODE[GPOS]]]] は[[グリフ]]の配置に関する情報を記述する
[[OpenType]] [[フォント]]の[[表][OpenType表]]です。
* 仕様書
[REFS[
-
[12]
[CITE@ja-jp[OpenType layout common table formats (OpenType 1.9) - Typography | [[Microsoft]] Docs]], [[PeterCon]], [TIME[2022-08-29T13:36:14.000Z]] <https://docs.microsoft.com/ja-jp/typography/opentype/spec/chapter2#features-and-lookups>
-
[67]
[CITE@ja-jp[OpenType layout common table formats (OpenType 1.9) - Typography | [[Microsoft]] Docs]], [[PeterCon]], [TIME[2022-08-30T11:17:29.000Z]] <https://docs.microsoft.com/ja-jp/typography/opentype/spec/chapter2#lookup-table>
-
[72]
[CITE@ja-jp[OpenType layout common table formats (OpenType 1.9) - Typography | [[Microsoft]] Docs]], [[PeterCon]], [TIME[2022-08-30T11:42:01.000Z]] <https://docs.microsoft.com/ja-jp/typography/opentype/spec/chapter2#common-structures-for-contextual-lookup-subtables>
- [1]
[CITE@en-us[GSUB — Glyph Substitution Table (OpenType 1.9) - Typography | Microsoft Docs]], [[PeterCon]], [TIME[2022-08-13T05:25:57.000Z]] <https://docs.microsoft.com/en-us/typography/opentype/spec/gsub>
]REFS]
* 構造
[5]
[CODE[GSUB]] には[[グリフ]]の置き換えのための対応表データが入っていて、
[CODE[GPOS]] には[[グリフ]]の利用に関係する[[座標]]等のデータが入っています。
[4]
[CODE[GSUB]],
[CODE[GPOS]]
とも似たような構造になっています。
末端のデータ等細部が微妙に違っているので注意が必要です。
[62]
どちらも、
まず対象となる[[用字系]]と[[言語系]]について、
それに関わる[[機能][フォント機能]]がいくつかあって、
[[機能][フォント機能]]における [[lookup]] がいくつかあり、
その [[lookup]] に条件と処理が書かれているという構造です。
* 処理
[58] 表示処理全体の中での位置は[[文字のレンダリング]]参照。
[60] [[機能][フォント機能]]の選択方法は[[機能][フォント機能]]参照。
* 機能
[8]
[CODE[GSUB]] [[表]],
[CODE[GPOS]] [[表]]は[[用字系]]や[[言語系]]に対して適用可能な[[機能][フォント機能]]を記述できます。
[SEE[ [[フォント機能]] ]]
[59]
[[機能][フォント機能]]に対して、実施されるべき操作を [[lookup]] として記述できます。
[46]
[CODE[GSUB]] [[表]],
[CODE[GPOS]] [[表]]には同じ[[タグ][機能タグ]]の[[機能][フォント機能]]を複数個含められます。
[[用字系]]や[[言語系]]に対してどの[[機能]]を適用するかを選択できますから、
同じ[[機能][フォント機能]]でも[[用字系]]と[[言語系]]に合わせて違う [[lookup]]
が適用されるようにできます。
* lookup
[63]
[CODE[GSUB]] や [CODE[GPOS]] を適用するには、
[[用字系]], [[言語系]], [[機能][フォント機能]]から利用する
[[lookup]]
を決定します。
[SEE[ 選び方は[[フォント機能]] ]]
[64]
複数の [[lookup]] を適用する場合、
適用順序は
[CODE[LookupList]]
の出現順とします。
[SRC[>>12, >>67]]
1つの
[[lookup]]
で[[グリフ]]列を先頭から末尾まで処理し、
次の
[[lookup]]
へと進みます。
[SRC[>>67]]
[65]
[[フォント]]開発者は、
複数の[[機能][フォント機能]]を同時適用するときの相互作用を考慮して
[CODE[LookupList]]
中の [[lookup]] の順序を決められます。
1つの[[機能][フォント機能]]に複数の [[lookup]]
を結びつけることが出来ますから、
サンドイッチ式の適用も記述できます。
;; [66] ただし、全体の処理において[[機能][フォント機能]]ごとに複数回に分けて適用する場合もあり
[SEE[ [[フォント機能]] ]]、
その場合は[[フォント]]開発者の制御が及ばなくなります。
[68]
同時に複数の[[機能][フォント機能]]を適用する場合、
それらの [[lookup]] の[RUBYB[[[和集合]]][union]]を使います。
[SRC[>>67]]
つまり重複した [[lookup]] があるときは、1回分だけ適用されます。
[69]
なお、[[機能][フォント機能]]ごとに異なる部分[[グリフ]]列にのみ適用することができます。
[SRC[>>67]]
[70]
同じ [[lookup]] で異なる部分[[グリフ]]列に適用されるべきときはどうなるのでしょう。
適用対象の[[グリフ]]も[[和集合]]になるのでしょうか。
-*-*-
[13] [[lookup]]
は,
[CODE[lookupType]]
と
[CODE[substFormat]]
にもよりますが、
[[グリフ]]の列の一致条件を3通り記述できます。すなわち、
- [DFN[[RUBYB[[RUBY[後][あと]][RUBY[戻][もど]]り][backtrack]]]]する[[グリフ]]の0個以上の列
- [DFN[[RUBYB[[RUBY[入][にゅう]][RUBY[力][りょく]]][input]]]]の[[グリフ]]の1個以上の列
- [DFN[[RUBYB[[RUBY[先][さき]][RUBY[読][よ]]み][lookahead]]]]する[[グリフ]]の0個以上の列
[73]
ここで[[グリフ]]列は[[論理順]]とします。
[SRC[>>72]]
[14]
[[入力]]の[[グリフ]]列は、指定された処理が施される対象となります。
[15]
[[後戻り]]は[[入力]]の直前、
[[先読み]]は[[入力]]の直後にあるべき[[グリフ]]列で、
一致するかどうかの判断には使いますが、
処理の対象にはなりません。
[16]
一致した場合、[[入力]]の次の[[グリフ]]に進んで一致するかどうかの検査を繰り返します
[SRC[>>67]]。
[[先読み]]列があれば、その先頭からということになります。
[17]
ただし、
[CODE[GPOS]] の [CODE[lookupType]] [N[2]]
は2つの[[グリフ]]の組に対して値を設定するもので、
常に2つの[[グリフ]]が[[入力]]となるのですが、
第2[[グリフ]]に与えられた値がないときには、
その次の処理の[[入力]]は前の処理の第2[[グリフ]]からとなります。
[SRC[>>67, >>72]]
;; [18] 1つ [[lookup]] についての処理において、
[CODE[GPOS]] の組の例外を除き、
[[入力]]列を処理して得られた出力に二重に処理が適用されることはありません。
[71]
[[先読み]]と[[後戻り]]が一致する[[グリフ]]は、
[[機能][フォント機能]]の適用対象となる[[グリフ]]でなくても構いません。
[SRC[>>67]]
[19]
[[入力]]の第2の[[グリフ]]以降[[先読み]]の最後の[[グリフ]]までの各[[グリフ]]の前、
あるいは[[後戻り]]の各[[グリフ]]の後には、
特定の種類の[[グリフ]]があったとしても、
一致判定においては無視する場合があります。
その条件は
[[lookup]]
の
[F[[CODE[lookupFlag]]]]
で記述されます。
- [20] [[lookup]] の [F[[CODE[lookupFlag]]]] の
[DFN[[CODE[IGNORE_BASE_GLYPHS]]]]
(ビット1)
が指定されている場合、
[CODE[GDEF]] [[表]]の[[グリフ級定義]]で [N[1]] (基底) とされた[[グリフ]]は無視します。
[SRC[>>1]]
- [21] [[lookup]] の [F[[CODE[lookupFlag]]]] の
[DFN[[CODE[IGNORE_LIGATURES]]]]
(ビット2)
が指定されている場合、
[CODE[GDEF]] [[表]]の[[グリフ級定義]]で [N[2]] (合字) とされた[[グリフ]]は無視します。
[SRC[>>1]]
- [22] [[lookup]] の [F[[CODE[lookupFlag]]]] の
[DFN[[CODE[IGNORE_MARKS]]]]
(ビット3)
が指定されている場合、
[CODE[GDEF]] [[表]]の[[グリフ級定義]]で [N[3]] (マーク) とされた[[グリフ]]は無視します。
[SRC[>>1]]
- [28]
[[lookup]] の [F[[CODE[lookupFlag]]]] の
[CODE[IGNORE_MARKS]]
が指定されていない場合、
-- [25] [[lookup]] の [F[[CODE[lookupFlag]]]] の
[DFN[[CODE[USE_MARK_FILTERING_SET]]]]
(ビット4)
が指定されている場合、
[[lookup]] の [DFN[[F[[CODE[markFilteringSet]]]]]]
を参照します。
[SRC[>>1]]
---
[26]
[DFN[[CODE[MarkFilteringSet]]]]
は
[CODE[uint16]]
です。
第[VAR[i]]ビットが[[マークグリフ集合群]]の第[VAR[i]]番の集合を表すと思われます。
---
[27]
指定された[[マークグリフ集合]]に''ない''[[マーク]]グリフは無視します。
[SRC[>>1]]
---
[30] ここでいう[[マーク]]は
[CODE[GDEF]] [[表]]の[[グリフ級定義]]で [N[3]] (マーク) とされた[[グリフ]]を指すと思われます。
--[29]
[[lookup]] の [F[[CODE[lookupFlag]]]] の
[CODE[USE_MARK_FILTERING_SET]]
が指定されていない場合、
--- [23] [[lookup]] の [F[[CODE[lookupFlag]]]] の
[DFN[[CODE[MARK_ATTACHMENT_TYPE_MASK]]]]
(ビット8 - ビット15)
が [N[0]] でない場合、
この16ビットを[[級値]]と解釈します。
[[マーク添付級]]が指定された値では''ない''[[マーク]]グリフは無視します。
[SRC[>>1]]
---- [24] ここでいう[[マーク]]は
[CODE[GDEF]] [[表]]の[[グリフ級定義]]で [N[3]] (マーク) とされた[[グリフ]]を指すと思われます。
[34]
[[マーク]]系の機能が3つあります。
[[アラビア文字]]のように前後の文字との位置関係によって[[グリフ]]を変化させつつ、
主たる[[グリフ]]に付随する[[マーク]]は[[合字]]化の判定で適宜無視したりしなかったり、
といった条件を記述するために用意されているようです。
[35]
[[マーク添付級]]と[[マークグリフ集合]]は似たような機能ですが、
[[マークグリフ集合]]の方が記述能力が高い (複雑) です。
[[マークグリフ集合]]の方が後から追加された機能です。
[[マーク添付級]]だけでは不十分ということで追加されたのでしょうか。
[36]
[[グリフ級]]に基づく無視は
[CODE[GSUB]]
[CODE[lookupType]] [N[6]] と共にしばしば使われているようです。
[CODE[lookupType]] [N[6]]
では一致した[[入力列]]に更に他の [[lookup]]
を適用することになりますが、
このとき[[入力列]]の何番目の位置の[[グリフ]]であるかに依存して適用する
[[lookup]]
を決めます
([CODE[seqLookupRecords]])。
何番目であるかには、無視された[[グリフ]]を算入しません。
従って無視された[[グリフ]]の有無でどの [[lookup]] がどの[[グリフ]]に適用されるかは変化しませんし、
無視された[[グリフ]]には [[lookup]] が適用されません。
ただし一致した[[入力列]]の[[グリフ]]に対して [[lookup]]
を適用するときに、その [[lookup]] が前後の条件を記述していれば、
無視された[[グリフ]]の有無がその結果に影響を与える可能性はあります。
[37]
[CODE[GSUB]]
[CODE[lookupType]] [N[4]] (複数の[[グリフ]]の列から1つの[[合字]]への置き換え)
での利用も禁止されているわけではありませんが、
その意味するところは定かではありません。
無視して読み飛ばした[[グリフ]]も含めて[[入力列]]の全体が置き換えられるべきなのでしょうか?
[54]
[CODE[GPOS]] [CODE[lookupType]] [N[2]] ([[グリフ]]の組に対する位置調整)
での利用も禁止されているわけではありませんが、
どう適用されるべきなのか明確ではありません。
第1グリフは適用対象の[[グリフ]]の範囲が指定されますが、
第2グリフは任意(すべて)の[[グリフ]]が対象となり得ますから、
読み飛ばしとの相互作用をどうするべきか、
処理結果にいくつかの解釈が存在し得ます。
[56]
[CODE[GPOS]] [CODE[lookupType]] [N[4]], [N[5]], [N[6]]
は[[マーク]]と[[基底]], [[合字]], [[マーク]]との位置関係を調整するものです。
これらも読み飛ばしとの相互作用がどう扱われるのが想定される挙動なのか不明瞭です。
-*-*-
[31]
[[入力列]],
[[先読み列]],
[[後戻り列]]として指定できる[[グリフ]]の列の長さ ([[グリフ]]の数)
には上限が規定されていません。
[[表]]に於いて個数を表す値が [CODE[uint16]] なので、
2[SUP[16]] - 1 が構造上の上限となります。
無視して読み飛ばす[[グリフ]]の個数にも上限が規定されていません。
[32]
実際の[[自然言語]]の記述に使うための[[フォント]]でそこまで長いものが必要にはなり得ませんから、
それよりずっと小さな、しかし十分大きな個数で探索を打ち切るような実装が普通でしょうし、
それをしないで杜撰に実装すると[[セキュリティー][文字のセキュリティー]]の問題にもなり得ます。
[33]
実際上どれくらいの長さが必要なのでしょうかね。
16個では少し心もとない気がします。
128個だと過大な気がします。
-*-*-
[51]
[CODE[GSUB]]
[CODE[lookupType]] [N[5]] は [CODE[lookupType]] [N[6]] に容易に書き換えられるようです。
[N[5]] の利用例が少ないのは [N[5]] の機能では不十分な場合が多いのでしょう。
[55]
[CODE[GPOS]]
は[[カーニング]]で
[N[2]]
が使われていることが多いようです。
[CODE[GPOS]]
[CODE[lookupType]]
[N[1]], [N[2]] しか対応していない実装もあります。
-*-*-
[47]
[[lookup]]
は[[機能]]から参照されて適用されるものと、
他の
[[lookup]]
から参照されるものとがあります。
[48]
[[入れ子]]の [[lookup]] は
[CODE[GSUB]]
[CODE[lookupType]] [N[1]] が多いですが、
[N[2]] の例もあります。
[49]
仕様書には[[入れ子]]にできる [CODE[lookupType]] の制限は特にないようですが、
どれも適用できるのか不安感はあります。
[52]
[CODE[GSUB]]
[CODE[lookupType]] [N[4]], [CODE[substFormat]] [N[1]]
を使った事例があります。
このとき入力の複数の隣接した[[グリフ]]が[[合字]]化された1つの[[グリフ]]に置き換えられることがあります。
[53]
もしその場合に[[入力列]]側で無視される[[グリフ]]が間に挟まっていたらどう処理されるべきなのか、
[[入れ子]]の [[lookup]] で使われる [CODE[sequenceIndex]] が指すのが[[合字]]化により消失する[[グリフ]]のときどう処理されるべきなのか、
よくわかりません。
[50]
実装によっては
[CODE[GSUB]]
[CODE[lookupType]] [N[1]], [CODE[substFormat]] [N[2]]
しか対応していないこともあるようです。
[57]
[[入れ子]]の [[lookup]] と >>17 の挙動の関係も若干不明瞭です。
[[入れ子]]の [[lookup]] でも適用される旨が仕様書には書かれている
[SRC[>>72]]
のですが、どういうイメージなのでしょう。
[74]
[[入れ子]]を二重以上深くできるのか不明です。仕様書では特に禁止はしていませんが。
* 文脈
[6]
[CODE[GSUB]],
[CODE[GPOS]]
とも必須の[[表]]ではなく、
不要な[[フォント]]には入っていません。
どちらかだけの[[フォント]]もあります。
[7]
といっても使わないで済むのは[[欧米]]や[[東アジア]]の昔ながらの簡易的な表示に使う[[フォント]]くらいのものです。
それ以外の地域で使われる[[文字]]の多くは
[CODE[GSUB]] や [CODE[GPOS]]
の機能が必要です。
[[欧米]]や[[東アジア]]の[[文字]]も、[[カーニング]]や[[縦書き]]や[[合字]]など、
高品質
[WEAK[(現在の計算機環境では標準的に実現されているレベルも含む。)]]
な[[文字のレンダリング]]にはそうした機能が必要となります。
* [CODE[GSUB]] 代替グリフの選択
@@
* 関連
[75]
実装の効率化のため、
[CODE[GPOS]] による[[添付点]]の情報を [CODE[GDEF]] に要約して記述することが出来ます。
* 実例
[10] 各 [[feature]] の利用例は [[font feature]] 参照。
[9]
[CITE[[[Nishiki-teki]]]]
は
[CODE[GSUB]],
[CODE[GPOS]]
ともに
[[script]]
が多数あって、
[CODE[langSysRecords]]
をも複数使っています。
また
[CODE[GSUB]],
[CODE[GPOS]]
ともに同じ [[feature]] tag の別の feature list item があります。
- [39] [CITE@ja['''['''こかげ''']''' フォント : Nu みちしるべ]], [TIME[2020-11-05T13:34:49.000Z]], [TIME[2022-08-18T05:18:48.827Z]] <http://kokagem.sakura.ne.jp/font/michishirube/>
--[40] [CITE@ja[「Nu みちしるべ」フォントの中身を見る - omuronの備忘録]], [TIME[2022-08-18T05:19:07.000Z]] <https://omuron.hateblo.jp/entry/2020/11/07/142500>
-[42] [CITE@en[GitHub - ayaka14732/FanWunMing: A Simplified-Chinese-to-Traditional-Chinese font based on GenYoMin, which can handle the one-to-many problem | 繁媛明朝是基於源樣明體開發的簡轉繁字型,能處理一簡對多繁]], [TIME[2022-08-18T05:28:22.000Z]] <https://github.com/ayaka14732/FanWunMing>
--[43] [CITE@zh-HK[正確實現簡轉繁字型]], [[三日月綾香]], [TIME[2022-07-05T04:28:59.000Z]], [TIME[2022-08-18T05:29:34.570Z]] <https://ayaka.shn.hk/s2tfont/hant/>
[45] >>42
[CODE[GSUB]]
1, 2; 3, 1
[CODE[GPOS]]
1, 1; 1, 2; 9, 1 (2, 1)
[44]
[CITE@en[โครงการอักษรอีสาน]], [TIME[2022-03-22T07:25:24.000Z]], [TIME[2022-08-18T05:37:35.328Z]] <https://linux.thai.net/~thep/esaan-scripts/>
[CITE[Khottabun]]
[CODE[GSUB]]
2, 1; 4, 1; 5, 2; 6, 1; 6, 2
([[入れ子]]の lookup が 2, 1; 4, 1)
[CODE[GPOS]]
4, 1; 6, 1
[41] [CITE@ja[Ken Lunde 小林剣さんはTwitterを使っています: 「Rendering 김일성, 김정일 & 김정은 via the #OpenType 'ccmp' GSUB feature using chaining contextual substitutions. 🇰🇵 🤔 #KPS9566 #UTC154 @DPRK_News https://t.co/Fi41NOsWsQ」 / Twitter]], 午前11:42 · 2018年1月7日 [TZ[+09:00]], [TIME[2022-08-18T05:03:26.000Z]] <https://twitter.com/ken_lunde/status/949833681354375168>
* 歴史
[11]
[CITE@en[opentype-layout/proposals at master · OpenType/opentype-layout · GitHub]], [TIME[2022-08-17T07:14:06.000Z]] <https://github.com/OpenType/opentype-layout/tree/master/proposals>
* メモ
[38]
[CITE[Spec for Thai OpenType Creation]], [TIME[2022-03-22T07:23:44.000Z]], [TIME[2022-08-18T02:34:48.288Z]] <https://linux.thai.net/~thep/th-otf/>
-
[2]
[CITE[Manipulating OpenType Lookups — FontForge 20220308 documentation]], [TIME[2022-07-16T19:58:44.000Z]], [TIME[2022-08-13T05:26:05.464Z]] <https://fontforge.org/docs/ui/dialogs/lookups.html>
[3] [CITE@ja[GSUB テーブル (1) - ScriptList]], [TIME[2022-08-13T05:26:21.000Z]] <https://aznote.jakou.com/prog/opentype/17_gsub1.html>