(data, start)
| 4018 | // There are many available formats, but we only support the Windows format 4. |
| 4019 | // This function returns a `CmapEncoding` object or null if no supported format could be found. |
| 4020 | function parseCmapTable(data, start) { |
| 4021 | var i; |
| 4022 | var cmap = {}; |
| 4023 | cmap.version = parse.getUShort(data, start); |
| 4024 | check.argument(cmap.version === 0, 'cmap table version should be 0.'); |
| 4025 | |
| 4026 | // The cmap table can contain many sub-tables, each with their own format. |
| 4027 | // We're only interested in a "platform 3" table. This is a Windows format. |
| 4028 | cmap.numTables = parse.getUShort(data, start + 2); |
| 4029 | var offset = -1; |
| 4030 | for (i = 0; i < cmap.numTables; i += 1) { |
| 4031 | var platformId = parse.getUShort(data, start + 4 + (i * 8)); |
| 4032 | var encodingId = parse.getUShort(data, start + 4 + (i * 8) + 2); |
| 4033 | if (platformId === 3 && (encodingId === 1 || encodingId === 0)) { |
| 4034 | offset = parse.getULong(data, start + 4 + (i * 8) + 4); |
| 4035 | break; |
| 4036 | } |
| 4037 | } |
| 4038 | |
| 4039 | if (offset === -1) { |
| 4040 | // There is no cmap table in the font that we support, so return null. |
| 4041 | // This font will be marked as unsupported. |
| 4042 | return null; |
| 4043 | } |
| 4044 | |
| 4045 | var p = new parse.Parser(data, start + offset); |
| 4046 | cmap.format = p.parseUShort(); |
| 4047 | check.argument(cmap.format === 4, 'Only format 4 cmap tables are supported.'); |
| 4048 | |
| 4049 | // Length in bytes of the sub-tables. |
| 4050 | cmap.length = p.parseUShort(); |
| 4051 | cmap.language = p.parseUShort(); |
| 4052 | |
| 4053 | // segCount is stored x 2. |
| 4054 | var segCount; |
| 4055 | cmap.segCount = segCount = p.parseUShort() >> 1; |
| 4056 | |
| 4057 | // Skip searchRange, entrySelector, rangeShift. |
| 4058 | p.skip('uShort', 3); |
| 4059 | |
| 4060 | // The "unrolled" mapping from character codes to glyph indices. |
| 4061 | cmap.glyphIndexMap = {}; |
| 4062 | |
| 4063 | var endCountParser = new parse.Parser(data, start + offset + 14); |
| 4064 | var startCountParser = new parse.Parser(data, start + offset + 16 + segCount * 2); |
| 4065 | var idDeltaParser = new parse.Parser(data, start + offset + 16 + segCount * 4); |
| 4066 | var idRangeOffsetParser = new parse.Parser(data, start + offset + 16 + segCount * 6); |
| 4067 | var glyphIndexOffset = start + offset + 16 + segCount * 8; |
| 4068 | for (i = 0; i < segCount - 1; i += 1) { |
| 4069 | var glyphIndex; |
| 4070 | var endCount = endCountParser.parseUShort(); |
| 4071 | var startCount = startCountParser.parseUShort(); |
| 4072 | var idDelta = idDeltaParser.parseShort(); |
| 4073 | var idRangeOffset = idRangeOffsetParser.parseUShort(); |
| 4074 | for (var c = startCount; c <= endCount; c += 1) { |
| 4075 | if (idRangeOffset !== 0) { |
| 4076 | // The idRangeOffset is relative to the current position in the idRangeOffset array. |
| 4077 | // Take the current offset in the idRangeOffset array. |
nothing calls this directly
no outgoing calls
no test coverage detected