diff --git a/src/core/cff_parser.js b/src/core/cff_parser.js index 6a47d16be91738..f4289bac1a1bff 100644 --- a/src/core/cff_parser.js +++ b/src/core/cff_parser.js @@ -96,6 +96,9 @@ var CFFStandardStrings = [ 'Black', 'Bold', 'Book', 'Light', 'Medium', 'Regular', 'Roman', 'Semibold' ]; +const NUM_STANDARD_CFF_STRINGS = 391; +const MAX_SID_INDEX = 64999; + var CFFParser = (function CFFParserClosure() { var CharstringValidationData = [ null, @@ -931,11 +934,11 @@ var CFFStrings = (function CFFStringsClosure() { } CFFStrings.prototype = { get: function CFFStrings_get(index) { - if (index >= 0 && index <= 390) { + if (index >= 0 && index <= (NUM_STANDARD_CFF_STRINGS - 1)) { return CFFStandardStrings[index]; } - if (index - 391 <= this.strings.length) { - return this.strings[index - 391]; + if (index - NUM_STANDARD_CFF_STRINGS <= this.strings.length) { + return this.strings[index - NUM_STANDARD_CFF_STRINGS]; } return CFFStandardStrings[0]; }, @@ -1295,6 +1298,17 @@ var CFFCompiler = (function CFFCompilerClosure() { output.add(compiled.output); var topDictTracker = compiled.trackers[0]; + // Create names for all of the glyphs so they can be put in the charset + // below. + let firstGlyphSid = cff.strings.strings.length + NUM_STANDARD_CFF_STRINGS; + let numGlyphNames = cff.charStrings.count; + if ((firstGlyphSid + numGlyphNames) > MAX_SID_INDEX) { + numGlyphNames = MAX_SID_INDEX - firstGlyphSid; + warn('Too many glyphs to give them all unique names.'); + } + for (let i = 0; i < numGlyphNames; i++) { + cff.strings.add('g' + i); + } var stringIndex = this.compileStringIndex(cff.strings.strings); output.add(stringIndex); @@ -1312,7 +1326,7 @@ var CFFCompiler = (function CFFCompilerClosure() { output.add(encoding); } } - var charset = this.compileCharset(cff.charset); + var charset = this.compileCharset(cff.charset, firstGlyphSid); topDictTracker.setEntryLocation('charset', [output.length], output); output.add(charset); @@ -1580,11 +1594,18 @@ var CFFCompiler = (function CFFCompilerClosure() { } return this.compileIndex(charStringsIndex); }, - compileCharset: function CFFCompiler_compileCharset(charset) { - let length = 1 + (this.cff.charStrings.count - 1) * 2; - // The contents of the charset doesn't matter, it's just there to make - // freetype happy. - let out = new Uint8Array(length); + compileCharset: function CFFCompiler_compileCharset(charset, + firstGlyphSid) { + // Freetype requires the number of charset strings be correct and MacOS + // requires that they all be unique when printing. + let numGlyphsLessNotDef = this.cff.charStrings.count - 1; + let out = new Uint8Array([ + 2, // format + (firstGlyphSid >> 8) & 0xFF, + firstGlyphSid & 0xFF, + (numGlyphsLessNotDef >> 8) & 0xFF, + numGlyphsLessNotDef & 0xFF, + ]); return this.compileTypedArray(out); }, compileEncoding: function CFFCompiler_compileEncoding(encoding) {