@@ -35,6 +35,12 @@ class cmap extends Table {
35
35
"rangeShift " => self ::uint16,
36
36
);
37
37
38
+ private static $ subtable_v12_format = array (
39
+ "length " => self ::uint32,
40
+ "language " => self ::uint32,
41
+ "ngroups " => self ::uint32
42
+ );
43
+
38
44
protected function _parse () {
39
45
$ font = $ this ->getFont ();
40
46
@@ -46,74 +52,108 @@ protected function _parse() {
46
52
for ($ i = 0 ; $ i < $ data ["numberSubtables " ]; $ i ++) {
47
53
$ subtables [] = $ font ->unpack (self ::$ subtable_header_format );
48
54
}
55
+
49
56
$ data ["subtables " ] = $ subtables ;
50
57
51
58
foreach ($ data ["subtables " ] as $ i => &$ subtable ) {
52
59
$ font ->seek ($ cmap_offset + $ subtable ["offset " ]);
53
60
54
61
$ subtable ["format " ] = $ font ->readUInt16 ();
55
62
56
- // @todo Only CMAP version 4
57
- if ($ subtable ["format " ] != 4 ) {
63
+ // @todo Only CMAP version 4 and 12
64
+ if (( $ subtable ["format " ] != 4 ) && ( $ subtable [ " format " ] != 12 ) ) {
58
65
unset($ data ["subtables " ][$ i ]);
59
66
$ data ["numberSubtables " ]--;
60
67
continue ;
61
68
}
62
69
63
- $ subtable += $ font ->unpack (self ::$ subtable_v4_format );
64
- $ segCount = $ subtable ["segCountX2 " ] / 2 ;
65
- $ subtable ["segCount " ] = $ segCount ;
70
+ if ($ subtable ["format " ] == 12 ) {
66
71
67
- $ endCode = $ font ->readUInt16Many ( $ segCount );
72
+ $ font ->readUInt16 ( );
68
73
69
- $ font ->readUInt16 (); // reservedPad
74
+ $ subtable += $ font ->unpack ( self :: $ subtable_v12_format );
70
75
71
- $ startCode = $ font ->readUInt16Many ($ segCount );
72
- $ idDelta = $ font ->readInt16Many ($ segCount );
76
+ $ glyphIndexArray = array ();
77
+ $ endCodes = array ();
78
+ $ startCodes = array ();
73
79
74
- $ ro_start = $ font ->pos ();
75
- $ idRangeOffset = $ font ->readUInt16Many ($ segCount );
80
+ for ($ p = 0 ; $ p < $ subtable ['ngroups ' ]; $ p ++) {
76
81
77
- $ glyphIndexArray = array ();
78
- for ($ i = 0 ; $ i < $ segCount ; $ i ++) {
79
- $ c1 = $ startCode [$ i ];
80
- $ c2 = $ endCode [$ i ];
81
- $ d = $ idDelta [$ i ];
82
- $ ro = $ idRangeOffset [$ i ];
82
+ $ startCode = $ startCodes [] = $ font ->readUInt32 ();
83
+ $ endCode = $ endCodes [] = $ font ->readUInt32 ();
84
+ $ startGlyphCode = $ font ->readUInt32 ();
83
85
84
- if ($ ro > 0 ) {
85
- $ font ->seek ($ subtable ["offset " ] + 2 * $ i + $ ro );
86
+ for ($ c = $ startCode ; $ c <= $ endCode ; $ c ++) {
87
+ $ glyphIndexArray [$ c ] = $ startGlyphCode ;
88
+ $ startGlyphCode ++;
89
+ }
86
90
}
87
91
88
- for ($ c = $ c1 ; $ c <= $ c2 ; $ c ++) {
89
- if ($ ro == 0 ) {
90
- $ gid = ($ c + $ d ) & 0xFFFF ;
92
+ $ subtable += array (
93
+ "startCode " => $ startCodes ,
94
+ "endCode " => $ endCodes ,
95
+ "glyphIndexArray " => $ glyphIndexArray ,
96
+ );
97
+
98
+ }
99
+ else if ($ subtable ["format " ] == 4 ) {
100
+
101
+ $ subtable += $ font ->unpack (self ::$ subtable_v4_format );
102
+
103
+ $ segCount = $ subtable ["segCountX2 " ] / 2 ;
104
+ $ subtable ["segCount " ] = $ segCount ;
105
+
106
+ $ endCode = $ font ->readUInt16Many ($ segCount );
107
+
108
+ $ font ->readUInt16 (); // reservedPad
109
+
110
+ $ startCode = $ font ->readUInt16Many ($ segCount );
111
+ $ idDelta = $ font ->readInt16Many ($ segCount );
112
+
113
+ $ ro_start = $ font ->pos ();
114
+ $ idRangeOffset = $ font ->readUInt16Many ($ segCount );
115
+
116
+ $ glyphIndexArray = array ();
117
+ for ($ i = 0 ; $ i < $ segCount ; $ i ++) {
118
+ $ c1 = $ startCode [$ i ];
119
+ $ c2 = $ endCode [$ i ];
120
+ $ d = $ idDelta [$ i ];
121
+ $ ro = $ idRangeOffset [$ i ];
122
+
123
+ if ($ ro > 0 ) {
124
+ $ font ->seek ($ subtable ["offset " ] + 2 * $ i + $ ro );
91
125
}
92
- else {
93
- $ offset = ($ c - $ c1 ) * 2 + $ ro ;
94
- $ offset = $ ro_start + 2 * $ i + $ offset ;
95
126
96
- $ font ->seek ($ offset );
97
- $ gid = $ font ->readUInt16 ();
127
+ for ($ c = $ c1 ; $ c <= $ c2 ; $ c ++) {
128
+ if ($ ro == 0 ) {
129
+ $ gid = ($ c + $ d ) & 0xFFFF ;
130
+ }
131
+ else {
132
+ $ offset = ($ c - $ c1 ) * 2 + $ ro ;
133
+ $ offset = $ ro_start + 2 * $ i + $ offset ;
134
+
135
+ $ font ->seek ($ offset );
136
+ $ gid = $ font ->readUInt16 ();
98
137
99
- if ($ gid != 0 ) {
100
- $ gid = ($ gid + $ d ) & 0xFFFF ;
138
+ if ($ gid != 0 ) {
139
+ $ gid = ($ gid + $ d ) & 0xFFFF ;
140
+ }
101
141
}
102
- }
103
142
104
- if ($ gid > 0 ) {
105
- $ glyphIndexArray [$ c ] = $ gid ;
143
+ if ($ gid > 0 ) {
144
+ $ glyphIndexArray [$ c ] = $ gid ;
145
+ }
106
146
}
107
147
}
108
- }
109
148
110
- $ subtable += array (
111
- "endCode " => $ endCode ,
112
- "startCode " => $ startCode ,
113
- "idDelta " => $ idDelta ,
114
- "idRangeOffset " => $ idRangeOffset ,
115
- "glyphIndexArray " => $ glyphIndexArray ,
116
- );
149
+ $ subtable += array (
150
+ "endCode " => $ endCode ,
151
+ "startCode " => $ startCode ,
152
+ "idDelta " => $ idDelta ,
153
+ "idRangeOffset " => $ idRangeOffset ,
154
+ "glyphIndexArray " => $ glyphIndexArray ,
155
+ );
156
+ }
117
157
}
118
158
119
159
$ this ->data = $ data ;
0 commit comments