4
4
import check from '../check.js' ;
5
5
import parse from '../parse.js' ;
6
6
import table from '../table.js' ;
7
+ import { eightBitMacEncodings } from '../types.js' ;
8
+ import { getEncoding } from '../tables/name.js' ;
9
+
10
+ function parseCmapTableFormat0 ( cmap , p , platformID , encodingID ) {
11
+ // Length in bytes of the index map
12
+ cmap . length = p . parseUShort ( ) ;
13
+ // see https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6name.html
14
+ // section "Macintosh Language Codes"
15
+ cmap . language = p . parseUShort ( ) - 1 ;
16
+
17
+ const indexMap = p . parseByteList ( cmap . length ) ;
18
+ const glyphIndexMap = Object . assign ( { } , indexMap ) ;
19
+ const encoding = getEncoding ( platformID , encodingID , cmap . language ) ;
20
+ const decodingTable = eightBitMacEncodings [ encoding ] ;
21
+ for ( let i = 0 ; i < decodingTable . length ; i ++ ) {
22
+ glyphIndexMap [ decodingTable . charCodeAt ( i ) ] = indexMap [ 0x80 + i ] ;
23
+ }
24
+ cmap . glyphIndexMap = glyphIndexMap ;
25
+ }
7
26
8
27
function parseCmapTableFormat12 ( cmap , p ) {
9
28
//Skip reserved.
@@ -150,11 +169,15 @@ function parseCmapTable(data, start) {
150
169
let format14Parser = null ;
151
170
let format14offset = - 1 ;
152
171
let offset = - 1 ;
172
+ let platformId = null ;
173
+ let encodingId = null ;
153
174
for ( let i = cmap . numTables - 1 ; i >= 0 ; i -= 1 ) {
154
- const platformId = parse . getUShort ( data , start + 4 + ( i * 8 ) ) ;
155
- const encodingId = parse . getUShort ( data , start + 4 + ( i * 8 ) + 2 ) ;
175
+ platformId = parse . getUShort ( data , start + 4 + ( i * 8 ) ) ;
176
+ encodingId = parse . getUShort ( data , start + 4 + ( i * 8 ) + 2 ) ;
156
177
if ( ( platformId === 3 && ( encodingId === 0 || encodingId === 1 || encodingId === 10 ) ) ||
157
- ( platformId === 0 && ( encodingId === 0 || encodingId === 1 || encodingId === 2 || encodingId === 3 || encodingId === 4 ) ) ) {
178
+ ( platformId === 0 && ( encodingId === 0 || encodingId === 1 || encodingId === 2 || encodingId === 3 || encodingId === 4 ) ) ||
179
+ ( platformId === 1 && encodingId === 0 ) // MacOS <= 9
180
+ ) {
158
181
offset = parse . getULong ( data , start + 4 + ( i * 8 ) + 4 ) ;
159
182
// allow for early break
160
183
if ( format14Parser ) {
@@ -178,12 +201,17 @@ function parseCmapTable(data, start) {
178
201
const p = new parse . Parser ( data , start + offset ) ;
179
202
cmap . format = p . parseUShort ( ) ;
180
203
181
- if ( cmap . format === 12 ) {
204
+ if ( cmap . format === 0 ) {
205
+ parseCmapTableFormat0 ( cmap , p , platformId , encodingId ) ;
206
+ } else if ( cmap . format === 12 ) {
182
207
parseCmapTableFormat12 ( cmap , p ) ;
183
208
} else if ( cmap . format === 4 ) {
184
209
parseCmapTableFormat4 ( cmap , p , data , start , offset ) ;
185
210
} else {
186
- throw new Error ( 'Only format 4, 12 and 14 cmap tables are supported (found format ' + cmap . format + ').' ) ;
211
+ throw new Error (
212
+ 'Only format 0 (platformId 1, encodingId 0), 4, 12 and 14 cmap tables are supported ' +
213
+ '(found format ' + cmap . format + ', platformId ' + platformId + ', encodingId ' + encodingId + ').'
214
+ ) ;
187
215
}
188
216
189
217
// format 14 is the only one that's not exclusive but can be used as a supplement.
@@ -361,4 +389,4 @@ function makeCmapTable(glyphs) {
361
389
362
390
export default { parse : parseCmapTable , make : makeCmapTable } ;
363
391
364
- export { parseCmapTableFormat14 } ;
392
+ export { parseCmapTableFormat0 , parseCmapTableFormat14 } ;
0 commit comments