/
928.txt
1025 lines (810 loc) · 33.4 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
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
* 仕様書
[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]]
[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]] は好きに使って良いのでしょう。
未知の値は無視して構わないと考えるのが妥当でしょう。
[74]
[F[[CODE[platformID]]]] [N[1]] ([[Macintosh]])
の
[CODE[cmap]] [[部分表]]はかつての [[Macintosh]] では[RUBYB[[[必須]]][required]]でしたが、
現在の [[Apple]] の[[プラットフォーム]]では[RUBYB[[[非推奨]]][discouraged]]です。
[SRC[>>1]]
** [CODE[encodingID]]
[70]
[DFN[[F[[CODE[encodingID]]]]]]
の意味は
[F[[CODE[platformID]]]] に依存します。
[CODE[encodingID]]
には次のものがあります。
[FIG(table)[
:p:[F[[CODE[platformID]]]]
:e:[F[[CODE[encodingID]]]]
:o:[CITE[OpenType]] の説明 [SRC[>>1]]
:r:制限 [SRC[>>1]]
:u:[[Unicode部分表]]
:note:メモ
:p:[N[0]] ([[Unicode]])
:e:[N[0]]
:o:[[Unicode 1.0]] semantics
:r:[RUBYB[[[非推奨]]][deprecated]]
:u:○
:p:[N[0]] ([[Unicode]])
:e:[N[1]]
:o:[[Unicode 1.1]] semantics
:r:[RUBYB[[[非推奨]]][deprecated]]
:u:○
:p:[N[0]] ([[Unicode]])
:e:[N[2]]
:o:[[ISO/IEC 10646]] semantics
:r:[RUBYB[[[非推奨]]][deprecated]]
:u:○
:p:[N[0]] ([[Unicode]])
:e:[N[3]]
:o:[[Unicode 2.0]] and onwards semantics, [[Unicode BMP]] only
:r:[CODE[cmap]] [[部分表]] [F[[CODE[format]]]] [N[4]], [N[6]] で使う[RUBYB[べき][should]]
:u:○
:p:[N[0]] ([[Unicode]])
:e:[N[4]]
:o:[[Unicode 2.0]] and onwards semantics, [[Unicode]] full repertoire
:r:[CODE[cmap]] [[部分表]] [F[[CODE[format]]]] [N[10]], [N[12]] で使う[RUBYB[べき][should]]
:u:○
:p:[N[0]] ([[Unicode]])
:e:[N[5]]
:o:[[Unicode Variation Sequences]]
:r:[CODE[cmap]] [[部分表]] [F[[CODE[format]]]] [N[14]] でのみ使う[RUBYB[べき][should]]
:u:○
:p:[N[0]] ([[Unicode]])
:e:[N[6]]
:o:[[Unicode]] full repertoire
:r:[CODE[cmap]] [[部分表]] [F[[CODE[format]]]] [N[13]] でのみ使う[RUBYB[べき][should]]
:u:○
:p:[N[0]] ([[Unicode]])
:e:[N[10]]
:note:
[[Unicode符号点]]。
[[仕様書]]にないが利用例あり。
:u:○
:p:[N[0]] ([[Unicode]])
:e:その他
:u:○
:p:[N[1]] ([[Macintosh]])
:e:その他
:r:[RUBYB[非推奨][discouraged]]
:p:[N[2]] ([[ISO]])
:e:[N[0]]
:o:7-bit [[ASCII]]
:r:[RUBYB[[[非推奨]]][deprecated]]
:p:[N[2]] ([[ISO]])
:e:[N[1]]
:o:[[ISO 10646]]
:r:[RUBYB[[[非推奨]]][deprecated]]
:p:[N[2]] ([[ISO]])
:e:[N[2]]
:o:[[ISO 8859-1]]
:r:[RUBYB[[[非推奨]]][deprecated]]
:p:[N[2]] ([[ISO]])
:e:その他
:p:[N[3]] ([[Windows]])
:e:[N[0]]
:o:[[Symbol]]
:note:[SEE[ [[symbol encoding]] ]]
:r:
通常は [CODE[cmap]] [F[[CODE[format]]]] [N[4]]。
新たには [[Unicode]] を使う[RUBYB[べき][should]]。
:p:[N[3]] ([[Windows]])
:e:[N[1]]
:o:[[Unicode BMP]]
:u:○
:r:非 [[BMP]] [RUBYB[使用禁止][must not]]
:p:[N[3]] ([[Windows]])
:e:[N[2]]
:o:[[ShiftJIS]]
:p:[N[3]] ([[Windows]])
:e:[N[3]]
:o:[[PRC]]
:p:[N[3]] ([[Windows]])
:e:[N[4]]
:o:[[Big5]]
:p:[N[3]] ([[Windows]])
:e:[N[5]]
:o:[[Wansung]]
:p:[N[3]] ([[Windows]])
:e:[N[6]]
:o:[[Johab]]
:p:[N[3]] ([[Windows]])
:e:[N[7]]
:o:Reserved
:p:[N[3]] ([[Windows]])
:e:[N[8]]
:o:Reserved
:p:[N[3]] ([[Windows]])
:e:[N[9]]
:o:Reserved
:p:[N[3]] ([[Windows]])
:e:[N[10]]
:o:[[Unicode]] full repertoire
:u:○
:p:[N[3]] ([[Windows]])
:e:その他
:p: [N[4]] (Custom)
:e:[ [N[0]], [N[255]] ]
:o:OTF Windows NT compatibility mapping
:r:
[CODE[cmap]] [F[[CODE[format]]]] [N[0]], [N[6]] で[RUBYB[なければ][must]]。
新たに使う[RUBYB[べきではない][should not]]。
:p: [N[4]] (Custom)
:e:その他
:p:[ [N[240]], [N[255]] ]
:note:[[利用者定義]]に[[予約]]
:p:その他
]FIG]
[67]
[CITE[OpenType]] [[仕様書]]では
[CODE[cmap]]
[[表][OpenType表]]の
[DFN[Unicode[RUBYB[[RUBY[部][ぶ]][RUBY[分][ぶん]][RUBY[表][ひょう]]][subtable]]]]という語が使われています。
[F[[CODE[platformID]]]] [N[0]]
と
[F[[CODE[platformID]]]] [N[3]]
[F[[CODE[encodingID]]]] [N[1]], [N[10]]
を表すとされています。
[SRC[>>1]]
[75]
また [[Windows]] 用の[[フォント]]を作成するときは
[DFN[[RUBYB[[[Unicode]] [CODE[cmap]] [RUBY[部][ぶ]][RUBY[分][ぶん]][RUBY[表][ひょう]]][Unicode [CODE[cmap]] subtable]]]]を常に使う[RUBYB[べき][should]]ともされています。
この [[Unicode]] [CODE[cmap]] [[部分表]]は
[F[[CODE[platformID]]]] [N[3]]
[F[[CODE[encodingID]]]] [N[1]], [N[10]]
を意味するとされています。
[SRC[>>1]]
[78]
[[Unicode]] の [[BMP]] のみと全体とは [CODE[format]] が違えば区別可能なはずです。
にも関わらず [CODE[encodingID]] と [CODE[format]]
の両方に違う値を指定させて区別しています。
[CODE[format]] [N[13]] 専用の [CODE[encodingID]] もそうです。
[CODE[format]] だけでの区別では実装上の問題があったのでしょうか。
** [CODE[language]]
[93]
[DFN[[F[[CODE[language]]]]]]
は[[文字符号化]]の[[言語]]を表します。
[92]
[F[[CODE[platformID]]]] [N[1]] ([[Macintosh]])
''以外''の
[CODE[cmap]] [[部分表]]の
[F[[CODE[language]]]]
は、
[N[0]]
でなければ[RUBYB[なりません][must]]。
[SRC[>>1]]
[94]
[F[[CODE[platformID]]]] [N[1]] ([[Macintosh]])
の
[CODE[cmap]] [[部分表]]の
[F[[CODE[language]]]]
は、
- [RUBYB[言語依存][language-specific]]のとき、 [[Macintosh language ID]] + [N[1]]
- 言語依存でないとき、 [N[0]]
とします。
[SRC[>>1]]
[95]
[[Mac OS Roman]]
[CODE[cmap]]
では、
言語依存の符号化ではありませんから、
[N[0]]
としなければ[RUBYB[なりません][must]]。
[SRC[>>1]]
[EG[
[96]
[[Mac OS Turkish]]
[CODE[cmap]]
では、
[[Turkish]] の [[Macintosh language ID]] が [N[17]]
なので、
[F[[CODE[language]]]]
は
[N[18]]
とします。
[SRC[>>1]]
]EG]
[105]
[F[[CODE[language]]]]
は
[F[[CODE[format]]]]
依存の[[部分表]]に属しています。
ということは古い
[[Macintosh]]
でしか使われていないこの欄をいつまでも残しておく必要も無さそうなものですが、
新しそうな
[CODE[format]]
でもそのまま引き継がれています。
[106]
ただし
[CODE[format]] [N[14]]
には
[CODE[language]]
欄がありません。この [CODE[format]] だけ
[[Unicode]]
に完全に依存している
(= [CODE[language]] があってもまったく使いようがない)
関係なのでしょうかね。
(他は、少なくても理屈の上では、
[[Unicode]] に限定されていないので使い道がないとはいえない。)
** [CODE[platformID]] [N[4]]
[79]
[CODE[platformID]] [DFN[[N[4]]]] (Custom)
は、
[CODE[encodingID]] [ [N[0]], [N[255]] ] が
[DFN[OTF Windows NT compatibility mapping]]
として使われます。
[SRC[>>1]]
[81]
[CODE[platformID]] [N[4]]
は、
[[Type 1]]
[[フォント]]由来の [[OpenType]] [[フォント]]を通じて古い[[応用]]との互換性を維持するための[[遺物]]です。
[CODE[cmap]] [CODE[platformID]] [N[4]]
を使って、
[[非Unicode]] [[応用]]に対して[[フォント]]を
[[Windows ANSI符号化]]されているように見せかけられます。
[SRC[>>1]]
[82]
[[Windows ANSI符号化]]でない [[Type 1]] [[フォント]]、
例えば[[キリル文字]]や[[中欧]]フォントは、
過去 [[Adobe]] が出荷した際に
[CODE[.PFM]] ファイルの [CODE[CharSet]] 欄を
[N[0]] ([[Windows ANSI]])
としていました。
[[ATM for Windows 9x]]
は
[CODE[CharSet]]
を無視していました。
[SRC[>>1]]
[83]
[[Adobe]] は
[[Encoding]] が [[StandardEncoding]] でない [[Type1]] [[フォント]]から変換された
[[OpenType]] [[フォント]]において
[CODE[cmap]] [CODE[platformID]] [N[4]]
を使います。
[SRC[>>1]]
[84]
[CODE[platformID]] [N[4]]
の
[F[[CODE[encodingID]]]]
は、
元の [[Type 1]] [[フォント]]の [CODE[.PFM]]
ファイルの
[[Windows]] charset 値 [ [N[0]], [N[255]] ]
に設定しなければ[RUBYB[なりません][must]]。
[SRC[>>1]]
[85]
[CODE[platformID]] [N[4]] [CODE[encodingID]] [ [N[0]], [N[255]] ]
が
[[CFF]] アウトラインの [[OpenType]] [[フォント]]で使われた場合、
[[Windows NT]] の [[OTF]] フォントドライバーは、
次のように動作します。
[SRC[>>1]]
- [86] [[文字コード]] [ [N[0]], [N[255]] ]
に符号化されている[[グリフ]]を、
[[Windows ANSI]] [[コードページ1252]]における [[Unicode符号点]]に対応付けます。
- [87] [[Windows ANSI]] ([CODE[CharSet]] [N[0]]) を[[フォント]]が対応する
[COD[CharSet]] の一覧に追加します。
- [88] [CODE[encodingID]] を [[Windows]] [CODE[CharSet]] 値とみなし、
[[フォント]]が対応する [CODE[CharSet]] の一覧に追加します。
[90]
[CODE[cmap]] の[[符号化]]は、
[[CFF]] の[[符号化]]と[RUBYB[同一][identical]]でなければ[RUBYB[なりません][must]]。
[SRC[>>1]]
[80]
[CODE[platformID]] [N[4]]
は、現在広くは用いられていません。
新しい[[フォント]]では使うべき[RUBYB[ではありません][should not]]。
[SRC[>>1]]
[89]
[CODE[cmap]] [[部分表]]の [F[[CODE[format]]]] は [N[0]], [N[6]]
でなければ[RUBYB[なりません][must]]。
[SRC[>>1]]
[91] [[フォント依存符号化]]も参照。
** 各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]] 表
[111]
[CODE[cmap]] は一部例外を除き、1つの[[文字]] (を表す[[符号位置]]、[[ビット組合せ]])
に対して1つの[[グリフ]]を与える[[写像]]です。
;; [112]
[[言語]]的な理由や[[文字コード]]設計の事情で複数の[[文字]]を1つの[[グリフ]]で表したい場合
([[合字]])
や、
[[書体]]設計的な事情で1つの[[文字]]を複数の[[グリフ]]で表したい場合には、
[CODE[cmap]] だけでは実現できず、 [CODE[GSUB]]
(または [[shaping engine]] による文字前処理)
との組み合わせが必要となります。
-*-*-
[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]]
[97]
明示的には定められていませんが、その趣旨からして、
未対応の組み合わせが出現しても、
実装は黙って無視するべきと思われます。
[98]
指定されたすべての組み合わせが未対応の場合にどうするかは定められていません。
エラーとしてまったく受理しない実装もあるかもしれませんし、
黙って他の[[フォント]]にフォールバックするような実装戦略もあるかもしれません。
;; [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]]
[104]
いくつかの
[CODE[format]]
は[[データ構造]]上、
矛盾した値を記述することができます。
例えば開始よりも終了が小さな値の範囲を記述できたり、
小さい順に[[整列]]と規定されている (が構文上は無視できる)
ことがあります。
それらの一部は仕様書上で明確に禁止されています。
しかし禁止されている場合や当然に異常とみなされる場合に、
どう処理するべきかは明確ではありません。
(これは [CODE[cmap]] に限らず [[OpenType]] 全般でそうです。)
*** [CODE[format]] [N[0]] (1バイト符号)
[4]
[CODE[format]] = 0 :
[ [N[0x00]], [N[0xFF]] ]
の[[ビット組合せ]]に対応する[[グリフID]]が順番に格納されています。
[SRC[>>1, >>2]]
[100]
古い [[Macintosh]] ではこれが標準でした。 [SRC[>>1]]
[5]
新しい [[Apple]] の[[プラットフォーム]]では必須ではありません。 [SRC[>>1]]
今はあまり使われていません。
対応していない実装もあります。
*** [CODE[format]] [N[2]] (1バイトと2バイトの多バイト符号)
[6]
[CODE[format]] = 2 :
1バイト (8ビット) または2バイト (16ビット)
の[[多バイト符号]]に対応する[[グリフID]]が順番に格納されています。
[SRC[>>1, >>2]]
[99]
記述のない[[バイト]]は[[グリフID]] [N[0]] に対応するものと解釈されます。
[SRC[>>1]]
[101]
[[CJK]] の[[非Unicode]]の[[多バイト符号]]に適していました。
[7] 古い時代に用いられていたもので、今はあまり使われていません。
対応していない実装もあります。
*** [CODE[format]] [N[4]], [N[6]], [N[12]], [N[10]], [N[13]] (16ビット符号と32ビット符号)
-
[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]] 部分表を含めているようです。
(そうできると明記されていますが、必須ではありません。 [SRC[>>1]])
古い実装は 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]]
[76]
[[Windows]] ([CODE[platformID]] [N[3]])
で
[[Unicode]] [[BMP]]
のみ対応する[[フォント]]は、
[F[[CODE[encodingID]]]] [N[1]]
[F[[CODE[format]]]] [N[4]]
[[部分表]]を使わなければ[RUBYB[なりません][must]]。
[SRC[>>1]]
[77]
[[Windows]] ([CODE[platformID]] [N[3]])
で
[[Unicode]] 非 [[BMP]]
に対応する[[フォント]]は、
[F[[CODE[encodingID]]]] [N[10]]
[F[[CODE[format]]]] [N[12]]
[[部分表]]を使わなければ[RUBYB[なりません][must]]。
[SRC[>>1]]
[15]
[CODE[format]] = 13 は [CODE[format]] = 12 の変種。
複数の連続した[[符号位置]]の範囲を1つの[[グリフID]]に割り当てる。
[SRC[>>1, >>2]]
[18]
[[last-resort]] font
(適当な[[グリフ]]を用意できないときに代替[[グリフ]]を提供するための[[フォント]])
用とされています。
その性質上ほとんど使われておらず、
対応していない実装もあります。
[73]
[F[[CODE[format]]]] [N[13]]
[[部分表]]は、
[F[[CODE[platformID]]]] [N[0]]
[F[[CODE[encodingID]]]] [N[6]]
でのみ使う[RUBYB[べきです][should]]。
[SRC[>>1]]
-*-*-
[114]
[CODE[format]] [N[4]]
の[[部分表]]のサイズ上限を超えるような[[フォント]]を作ろうとすると、
[[AFDKO]] の [CODE[makeotf]]
は最初の2つの segment だけ残して後は捨ててしまいます。 [SRC[>>113]]
[115]
[[Windows]]
の[[メモ帳]]や [[Microsoft Excel]]
は
[CODE[format]] [N[4]]
が存在すること、という
[[heuristics]]
を実装しています。
それへの対処として、
[CODE[format]] [N[12]]
を使うときでも
[CODE[format]] [N[4]]
[[部分表]]を含めなければなりません。
[SRC[>>113]]
(その場合でも [CODE[format]] [N[12]] が使われるので、
[CODE[format]] [N[4]] は不完全でも存在していればOKらしいです。)
[REFS[
- [113]
[CITE@en[GitHub - adobe-type-tools/[[Adobe-KR]]: The Adobe-KR-9 Character Collection]], [TIME[2022-09-29T11:52:44.000Z]] <https://github.com/adobe-type-tools/Adobe-KR/#special-notes-5>
]REFS]
- [116] [CITE@en[[[GitHub]] - trueroad/HaranoAjiFonts-generator: 原ノ味フォント生成プログラム / Harano Aji Fonts generator]], [TIME[2022-09-29T15:48:27.000Z]] <https://github.com/trueroad/HaranoAjiFonts-generator#cmap>
>原ノ味フォント 20200516 から、KR のみ format 4 と format 12 に対し、 Unicode コードポイントで一つだけ抜けている (両隣は存在するが該当箇所は存在しない)ものに .notdef を割り当てる加工をしています。 これは、何もしないと format 4 のサイズが 64 KB を超えてしまい、 ttx でのフォント生成が例外で落ちてしまったためです。 format 12 はサイズの問題がないし format 4 の情報もすべて含んだ上位互換なので、 format 4 がなくてもいいだろうと削除してみたら落ちなくなりましたが、 Windows がフォントとして認識してくれません。 仕方なく format 4 の仕様書とにらめっこしてサイズを低減する方法を模索し、 上記の処理を入れました。 なお format 12 も BMP の範囲は format 4 と同じである必要があるため、 BMP 範囲内のみ同じ処理を入れてあります。
>原ノ味フォント 20200612 から、 [SNIP[]]KR で入れていた Unicode コードポイントで一つだけ抜けているものに .notdef を割り当てる加工 をやめ、代わりに Adobe-KR のドキュメントに記載されている format 4 から CJK Unified Ideographs (U+4E00..U+9FFF) と CJK Compatibility Ideographs (U+F900..U+FAFF) のブロックを削除する方法に変更しました。 これは .notdef を割り当てる加工をしていて、 かつ(関係ないはずの) GPOS テーブルが存在すると、 なぜか Windows がフォントを認識してくれないことが分かったためです。 OpenType 仕様的には(というか Windows 向けとしては) format 4 と format 12 の BMP 部分は一致するようにするのが推奨されていますが、 サイズ的に収まらないので仕方がなく Adobe お勧めの対処法に従った処理を行ったものです。
*** [CODE[format]] [N[8]] (16ビットと32ビットの混合符号)
[12]
[CODE[format]] = 8 :
16ビットまたは32ビットの符号用。
[SRC[>>1, >>2]]
[103]
上位が [N[0x0000]] となる32ビット符号に
[[グリフ]]を割り当てることも禁止はされていません。
しかし [N[0x0000]] と上位 [N[0x0000]] の32ビット符号の両方に[[グリフ]]を割り当てることは[RUBYB[禁止][may not]]されています。
[SRC[>>1]]
そのような場合にどうするべきなのかは不明。
[13]
[CODE[U+10FFFF]] まで使う [[Unicode]] を想定したものでした。
[102]
この
[CODE[format]]
はあまり使われていません。
対応していない実装もあります。
[RUBYB[非推奨][discouraged]]とされています [SRC[>>1]]。
*** [CODE[format]] [N[14]] (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]] に対応することができます。
[F[[CODE[format]]]] [N[14]]
[[部分表]]は、
[F[[CODE[platformID]]]] [N[0]]
[F[[CODE[encodingID]]]] [N[5]]
でのみ使う[RUBYB[べきです][should]]。
[SRC[>>1]]
;; [66] とだけしか定められてはいないのですが、
[[Unicode部分表]]がないときは [CODE[format]] [N[14]]
は使えないということでしょうか。
(実用上それ以外で [CODE[format]] [N[14]] を使いたいことはなさそうですが。)
[71]
[[UVS]] は、[CODE[cmap]] [[表]]で [F[[CODE[format]]]] [N[14]] [[部分表]]で指定する[RUBYB[べき][should]]です。
[SRC[>>1]]
;; [72] この「べき」[[規定]]の意味するところは不明瞭です。
[CODE[GSUB]] による [[UVS]] の実装を否定する趣旨と理解していいのでしょうか。
*** [CODE[format]] の実利用例
[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]] の違いに起因するものではない。)
** 処理
[107]
[CODE[cmap]]
は[[文字のレンダリング]]のために[[フォント]]の[[グリフ]]を取得する過程の1つとして参照されます。
[SEE[ [[文字のレンダリング]] ]]
[108]
[CODE[cmap]] の[[写像]]を引く[[入力]]となる[[文字コード]]は、
必ずしも[[情報交換]]に使う
[[Unicode文字列]]を構成する[[Unicode符号位置]]の列そのものではないことに注意が必要です。
[109]
[[bidi]] に関係して[[鏡像化]]のための[[符号位置]]の書き換えが事前に発生していることがあります。
[SEE[ [[書字方向依存グリフ]] ]]
[110]
その他 [[shaping]] に属する前処理で[[符号位置]]の変更が事前に発生していることがあります。
[SEE[ [[shaping engine]] ]]
* 関連