/
928.txt
485 lines (375 loc) · 16.2 KB
/
928.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
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
* 仕様書
[REFS[
-
[1] [CITE@en-us[cmap - Character To Glyph Index Mapping Table ([[OpenType]] 1.9) - Typography | Microsoft Docs]]
([[PeterCon]], [TIME[2022-08-16T01:57:58.000Z]])
<https://docs.microsoft.com/en-us/typography/opentype/spec/cmap>
-
[2] [CITE@en[Character to Glyph Mapping Table - [[TrueType]] Reference Manual - Apple Developer]]
([[Apple Inc.]], [TIME[2022-07-12T17:06:26.000Z]], [TIME[2022-08-16T01:58:07.176Z]])
<https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html>
]REFS]
* 概要
[39]
[[OpenType]] における[[文字コード]]には2つの側面があります。
- [40] 1つは、[[フォント]]に関係する[[文字列]]データの記述に使われるものです。
例えば [CODE[name][name (OpenType)]] [[表][OpenType表]]の[[フォント名]]が関係します。
- [41] 1つは、[[フォント]]に格納された[[グリフ]]データの参照 (利用)
方法としての[[文字]]の記述に使われるものです。
具体的には [CODE[cmap]] [[表][OpenType表]]が[[文字コード]]と[[グリフID]]の対照表となっています。
[42]
[CODE[name][name (OpenType)]] [[表][OpenType表]]と
[CODE[cmap]] [[表][OpenType表]]は、
利用する[[文字コード]]を記述し、その[[文字コード]]によって[[文字]]を記述または参照しています。
[43]
その他のいくつかの[[文字]]データは[[符号化方式]]が[[決め打ち]]です。
- [44] [[タグ][OpenTypeタグ]]は [[UTF-8]] (ただし [[ASCII]] のみ) です。
- [45] [[グリフ名]]
- [38] [[UTF-16BE]] が使われることがあります。
* 文字符号化
[49]
[CODE[cmap]] [[表][OpenType表]]には異なる[[文字符号化]]の[[部分表]]を含められます。
[[文字符号化]]は、
([CODE[platformID]], [CODE[encodingID]], [CODE[language]])
の3つの値の組で識別されます。
[SRC[>>1]]
[67]
[CITE[OpenType]] [[仕様書]]では
[CODE[cmap]]
[[表][OpenType表]]の
[DFN[Unicode[RUBYB[[RUBY[部][ぶ]][RUBY[分][ぶん]][RUBY[表][ひょう]]][subtable]]]]という語が使われています。
[F[[CODE[platformID]]]] [N[0]], [N[3]]
で
[F[[CODE[encodingID]]]] [N[1]], [N[10]]
を表すとされています。
[SRC[>>1]]
[68]
[[Unicode部分表]]とその他の何種類かの[[部分表]]は、
[[Unicode]] の[[符号位置]](列)から[[グリフID]]への対応関係を表します。
その他の[[部分表]]は、
[[非Unicode]]の[[文字符号化]]から[[グリフID]]への対応関係を表します。
;; [69] 現在ではほぼすべての実装が [[Unicode]] を使って [CODE[cmap]]
を引いています。以前 ([[平成時代]]初期頃まで) は[[非Unicode]]
の実装もありました。
現在では[[非Unicode]]の [CODE[cmap]] [[部分表]]を含まない[[フォント]]も多いです。
[[MacRoman]] の [CODE[cmap]] [[部分表]]を含む[[フォント]]も多いですが、
[[互換性]]のためというよりは、[[互換性]]が必要だった時代の名残りの慣習と思われます。
現在使われている[[フォント]]の [[MacRoman]] [CODE[cmap]]
は使い物にならないおかしなデータのことも多いです。
** [CODE[platformID]]
[50]
[DFN[[CODE[platformID]]]]
は、
次のいずれかです。
[FIG(table)[ [51] [CODE[platformID]]
:v: [[数値]]
:n: 名前 [SRC[>>1]]
:note: メモ
:v:[N[0]]
:n:Unicode
:v:[N[1]]
:n:Macintosh
:v:[N[2]]
:n:[I[ISO [deprecated__&&]&&__]]
:note: [[OpenType]] 1.3 から[RUBYB[[[非推奨]]][deprecated]]
[SRC[>>1]]
:v:[N[3]]
:n:Windows
:v:[N[4]]
:n:Custom
:v:[ [N[240]], [N[255]] ]
:note:[[利用者定義]]の[[プラットフォーム]]に[RUBYB[[[予約]]][reserved]]
[SRC[>>1]]
]FIG]
[55]
[CODE[platformID]] は [CODE[encodingID]] の[[名前空間]]を区別する役割がありますが、
それ以外の意味も処理方法も規定がありません。例えば [[Linux]]
の実装が [[Windows]] [CODE[platformID]] を使ってはいけないということはありません。
[[プラットフォーム]]ごとに[[文字コード]]の体系がまったく違っていた旧時代の[[遺物]]と考えるべきなのでしょう。
[53]
すべての値に対応しなければならないとする規定はありません。
未対応のものは無視して構わないと思われます。
[52]
未知の値に遭遇したときどう処理するべきか不明確です。
それが含まれるものは無視するのが妥当でしょう。
[54]
利用者定義の値について、使い方に何の規定もありません。
[CODE[encodingID]] は好きに使って良いのでしょう。
未知の値は無視して構わないと考えるのが妥当でしょう。
** 各IDの実利用例
[24]
互換性のためか
[CODE[platformID]] = 0 (Macintosh),
[CODE[encodingID]] = 0 ([[MacRoman]])
で、
[N[0x100]], [N[0x101]]
だけの
[CODE[cmap]]
部分表が含まれる[[フォント]]がままあります。
[32]
[CITE[[[Nishiki-teki]]]]
は
[CODE[platformID]] = 0 ([[Unicode]]),
[CODE[encodingID]] = 10
という
[CODE[cmap]] subtable
を持っています。
でも
[CODE[platformID]] 0 [CODE[encodingID]] 10
は
[[Microsoft]] の仕様書にも [[Apple]] の仕様書にも載っていません。
[33]
中身は [[Unicode]] のようです。
[CODE[platformID]] = 3 ([[Windows]])
だと
[CODE[encodingID]] = 10 が [[Unicode]]
なので、
それの誤りなのでしょうか。
[34]
[CITE[Makoto Comic]]
にも
[CODE[platformID]] = 0 ([[Unicode]]),
[CODE[encodingID]] = 10
があります。
* [CODE[cmap]] 表
[56]
[CODE[cmap]] [[表][OpenType表]]の [DFN[[F[[CODE[encodingRecords]]]]]]
に含められる [DFN[[CODE[EncodingRecord]]]]
は、
その
[F[[CODE[platformID]]]],
[F[[CODE[encodingID]]]],
[F[部分表]]の [F[[CODE[language]]]]
の優先順で[[整列]]しなければ[RUBYB[なりません][must]]。
[SRC[>>1]]
ここでの[[順序]]は[[数値]]の小さい順と思われます。
[57]
[CODE[cmap]] [[表][OpenType表]]にあっては
[CODE[EncodingRecord]]
の
[F[[CODE[platformID]]]],
[F[[CODE[encodingID]]]],
[F[部分表]]の [F[[CODE[language]]]]
の組み合わせは、
高々1回しか出現[RUBYB[でき][may]]ません。
[SRC[>>1]]
[58]
[[順序]]が不適切な場合や重複を含む場合にどう処理するべきなのかは定かではありません。
[[順序]]を無視する実装もあり得ますし、
求めるものより大きな値が出現したら探索を止める実装もあり得ます。
最初の一致を採る実装も、[[無作為]]に選ぶ実装もあり得ます。
エラーにする実装もあり得ます。
主要な実装はどうしているのでしょうか?
[59]
各[[部分表]]は、
[F[[CODE[format]]]] が [N[14]] の場合を除き、
排他的であります。
つまり[[応用]]は、そのうちの1つだけを選び、他を無視する[RUBYB[べき][should]]です。
[SRC[>>1]]
[60]
[[Unicode部分表]]が含まれる場合で、
16ビットの
[F[[CODE[format]]]]
のものと
32ビットの
[F[[CODE[format]]]]
のものが両方含まれるなら、32ビットの[[部分表]]に含まれる[[文字]]は、
16ビットの[[部分表]]に含まれる[[文字]]の[[超集合]]である[RUBYB[べき][should]]です。
[[応用]]は、
32ビットの[[部分表]]を使う[RUBYB[べきです][should]]。
[SRC[>>1]]
;; [61] 仕様上は要求されていませんが、常識的に考えて32ビットの[[部分表]]のうち
[ [CODE[U+0000]], [CODE[U+FFFE]] ]
の部分と16ビットの[[部分表]]が一致しているべきです。
[63]
[F[[CODE[platformID]]]] が違い
[F[[CODE[format]]]]
が同じ
[[Unicode部分表]]が含まれる場合、
[[応用]]はそのいずれを選んでも[RUBYB[構いません][may]]が、
その[[フォント]]の利用時にどの[[部分表]]が選ばれるかは一貫している[RUBYB[べきです][should]]。
[SRC[>>1]]
;; [62] 複数の[[部分表]]を含めても[[応用]]が使うのは1つだけです。
これによって対応する[[文字コード]]が異なる[[プラットフォーム]]で共通して使える[[フォント]]を提供できるというわけです。
実際に多くの[[フォント]]がそうしていますが、
一方で敢えて重複した[[部分表]]を含めない[[フォント]]もあります。
([CODE[format]] [N[14]] を除けば)
もはや[[プラットフォーム]]の違いによる互換性の問題はおおむね解消しており、
必要だからというより今までそうしてきたからというところが大きそうです。
-*-*-
[46]
[CODE[cmap]] では、
[[フォント]]中に対応する[[グリフ]]を持たない[[文字コード]]は[[グリフID]]
[N[0]]
に[[写像]]する[RUBYB[べきです][should]]。
[SRC[>>1]]
[SEE[ [[グリフID]] ]]
** [CODE[format]]
[47]
[CODE[cmap]]
[[表][OpenType表]]の
[DFN[[F[[CODE[format]]]]]]
は[[文字コード]]から[[グリフID]]への[[写像]]の記述方法を表します。
[SRC[>>1]]
[48]
多くの方法が定義されていますが、新しい[[フォント]]はそのうちの
[N[4]], [N[12]]、
用途により
[N[13]], [N[14]]
が適切です。
それ以外は新しい[[フォント]]には[RUBYB[推奨されません][not recommended]]。
[SRC[>>1]]
-*-*-
[4]
[CODE[format]] = 0 :
[ [N[0x00]], [N[0xFF]] ]
の[[ビット組合せ]]に対応する[[グリフID]]が順番に格納されています。
[SRC[>>1, >>2]]
[5] 古い時代に用いられていたもので、今はあまり使われていません。
対応していない実装もあります。
-*-*-
[6]
[CODE[format]] = 2 :
1バイトまたは2バイトの[[多バイト符号]]に対応する[[グリフID]]が順番に格納されています。
[SRC[>>1, >>2]]
[7] 古い時代に用いられていたもので、今はあまり使われていません。
対応していない実装もあります。
-*-*-
-
[8]
[CODE[format]] = 4 :
16ビット符号用。
[SRC[>>1, >>2]]
-
[9]
[CODE[format]] = 6 :
16ビット符号用。
[SRC[>>1, >>2]]
-
[17]
[CODE[format]] = 12 :
32ビット符号用。
[SRC[>>1, >>2]]
-
[14]
[CODE[format]] = 10 :
32ビット符号用。
[SRC[>>1, >>2]]
[11]
4, 6 は [[Unicode BMP]] 用,
12, 10 は [[Unicode]] 全体に使われています。
[10]
4, 12 は連続した[[符号位置]]に[[グリフID]]が割り当てられた密なもの、
6, 10 は疎なものに適した[[データ構造]]になっています。
[28]
6
に対応していない実装もあります。
[16]
10 はあまり使われておらず、
[[Windows]] は対応していません。
[SRC[>>1, >2]]
[20]
当初 4 が使われ後に 12 が使われるようになった経緯のため、
古い実装は 12 に対応していません。
多くの[[フォント]]は 4 と 12 の両方の [CODE[cmap]] 部分表を含めているようです。
古い実装は 4 の方を見るので、 [[BMP]] の[[文字]]だけは使えます。
[64]
[F[[CODE[format]]]] が [N[4]] と [N[6]]
の
[[Unicode部分表]]を同時に含める[RUBYB[べきではありません][should]]。
[F[[CODE[format]]]] が [N[10]] と [N[12]]
の
[[Unicode部分表]]を同時に含める[RUBYB[べきではありません][should]]。
これらの場合、 [N[4]] や [N[12]] を使う[RUBYB[べきです][should]]。
[SRC[>>1]]
[15]
[CODE[format]] = 13 は [CODE[format]] = 12 の変種。
複数の連続した[[符号位置]]の範囲を1つの[[グリフID]]に割り当てる。
[SRC[>>1, >>2]]
[18]
[[last-resort]] font
(適当な[[グリフ]]を用意できないときに代替[[グリフ]]を提供するための[[フォント]])
用とされています。
その性質上ほとんど使われておらず、
対応していない実装もあります。
-*-*-
[12]
[CODE[format]] = 8 :
16ビットまたは32ビットの符号用。
[SRC[>>1, >>2]]
[13]
[CODE[U+10FFFF]] まで使う [[Unicode]] を想定したものでしたが、
あまり使われていません。
対応していない実装もあります。
-*-*-
[21]
[CODE[format]] = 14 :
[[UVS]]
用。
[SRC[>>1, >>2]]
[22]
他の [CODE[format]] と違って入力が1つの[[文字]] ([[符号位置]])
ではなく2つの[[文字]] ([[符号位置]])。
[[Unicode]] の[[異体列]]の専用の仕組みになっています。
(2, 8 の入力は多バイトであっても1文字。 4, 6, 10, 12, 13 も同じ。
4, 6, 8, 10, 12, 13 は [[Unicode]] 想定であっても、専用ではない。)
[23]
同じく複数の [[Unicode文字]]で1つのものを表現する[[結合列]]や[[合字]]は
[CODE[GSUB]]
で[[グリフ]]レベルの操作を使っていますが、 [[VS]]
だけなぜか専用の仕組みが [CODE[cmap]] に[[文字]]レベルで追加されました。
[25]
[[異体列]]に対し「[[異体選択子]]なしと同じ」を指定するものと、
[[グリフID]]を指定するものの2種類の指定方法があります。
前者が得られた場合には他の
[CODE[cmap]] 部分表を使って再探索することになります。
[26]
実際の[[フォント]]は前者の方法を使わずすべて後者の方法によるものと、
前者の方法を適宜使うものがあります。
前者を使った方がデータ量はいくらか少なくなるのでしょうが、
[[グリフ]]取得が少し遅くなります。
といっても現在の[[計算機]]の性能からみればどちらの差分もほとんど誤差みたいなものでしょう。
;; [27] その誤差みたいな節約のために前者の方法を導入してるのが無駄に思えるのですが、
[[OpenType]] の複雑性の中ではそれも誤差みたいな複雑性かもしれませんw
[29]
[[VS]] は[[日本語]]や[[蒙古文字]]の表示には必須の機能ですが、
[[欧米]]では必要とされないことや、
比較的歴史の浅い機能であることから、
14 に対応していない実装もあります。
[30]
[[日本語]]用[[フォント]]で多くの文字を含んだものにはよく使われています。
;; [31] 14 を使わなくても [CODE[GSUB]] でも対応できますが
(そちらの方が対応してる実装は多いかも知れませんが)、
そのような[[フォント]]があるのかは不明。
[65]
[[Unicode部分表]]が使われる場合、
[F[[CODE[platformID]]]] [N[0]]
[F[[CODE[encodingID]]]] [N[5]]
[F[[CODE[format]]]] [N[14]]
の[[部分表]]で [[UVS]] に対応することができます。
[SRC[>>1]]
;; [66] とだけしか定められてはいないのですが、
[[Unicode部分表]]がないときは [CODE[format]] [N[14]]
は使えないということでしょうか。
(実用上それ以外で [CODE[format]] [N[14]] を使いたいことはなさそうですが。)
-*-*-
[3]
[CITE@en[[[GitHub]] - nixeneko/nxTokiACF]], [TIME[2022-08-16T01:59:19.000Z]] <https://github.com/nixeneko/nxTokiACF>
[CODE[format]] = 0, 4
[19] [CITE@en[Release Version 14.000 Release · unicode-org/last-resort-font · GitHub]], [TIME[2022-08-16T02:36:51.000Z]] <https://github.com/unicode-org/last-resort-font/releases/tag/14.000>
[CODE[LastResort-Regular.ttf]]
は
7.89MB
の[[フォント]]。
[CODE[format]] = 12 と [CODE[format]] = 4 (空)。
[CODE[LastResortHE-Regular.ttf]]
は
506KB
の[[フォント]]。
[CODE[format]] = 13 と [CODE[format]] = 4 (空)。
(ファイルサイズの違いは [CODE[format]] の違いに起因するものではない。)
* メモ
[35] [CITE@ja-jp[OpenType glyph processing (part 2) - Typography | Microsoft Docs]], [[alib-ms]], [TIME[2022-08-27T08:46:01.000Z]] <https://docs.microsoft.com/ja-jp/typography/develop/processing-part2#cmap-table>
[36] >>35 公式ドキュメントですが、ここでは [CODE[CMAP]] になっています。
[CODE[cmap]] にしないと正常動作しないと思いますが、どうなんでしょう。
[37] [[Character-level mirroring]] では [CODE[cmap]] で得られる値が [N[0]] か検査します。