From c830021b078a92448d4f7dc8281bfcec1e2873be Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Fri, 7 Jul 2017 15:12:52 -0500 Subject: [PATCH] Fixes CFF data glyph widths --- src/core/cff_parser.js | 31 ++++++++++++++++++------------- test/unit/cff_parser_spec.js | 27 +++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/core/cff_parser.js b/src/core/cff_parser.js index f0c1e3749..2c044131f 100644 --- a/src/core/cff_parser.js +++ b/src/core/cff_parser.js @@ -268,12 +268,14 @@ var CFFParser = (function CFFParserClosure() { cff.charset = charset; cff.encoding = encoding; - var charStringsAndSeacs = this.parseCharStrings( - charStringIndex, - topDict.privateDict.subrsIndex, - globalSubrIndex.obj, - cff.fdSelect, - cff.fdArray); + var charStringsAndSeacs = this.parseCharStrings({ + charStrings: charStringIndex, + localSubrIndex: topDict.privateDict.subrsIndex, + globalSubrIndex: globalSubrIndex.obj, + fdSelect: cff.fdSelect, + fdArray: cff.fdArray, + privateDict: topDict.privateDict, + }); cff.charStrings = charStringsAndSeacs.charStrings; cff.seacs = charStringsAndSeacs.seacs; cff.widths = charStringsAndSeacs.widths; @@ -601,11 +603,8 @@ var CFFParser = (function CFFParserClosure() { state.stackSize = stackSize; return true; }, - parseCharStrings: function CFFParser_parseCharStrings(charStrings, - localSubrIndex, - globalSubrIndex, - fdSelect, - fdArray) { + parseCharStrings({ charStrings, localSubrIndex, globalSubrIndex, fdSelect, + fdArray, privateDict, }) { var seacs = []; var widths = []; var count = charStrings.count; @@ -623,6 +622,7 @@ var CFFParser = (function CFFParserClosure() { }; var valid = true; var localSubrToUse = null; + var privateDictToUse = privateDict; if (fdSelect && fdArray.length) { var fdIndex = fdSelect.getFDIndex(i); if (fdIndex === -1) { @@ -634,7 +634,8 @@ var CFFParser = (function CFFParserClosure() { valid = false; } if (valid) { - localSubrToUse = fdArray[fdIndex].privateDict.subrsIndex; + privateDictToUse = fdArray[fdIndex].privateDict; + localSubrToUse = privateDictToUse.subrsIndex; } } else if (localSubrIndex) { localSubrToUse = localSubrIndex; @@ -644,7 +645,11 @@ var CFFParser = (function CFFParserClosure() { globalSubrIndex); } if (state.width !== null) { - widths[i] = state.width; + const nominalWidth = privateDictToUse.getByName('nominalWidthX'); + widths[i] = nominalWidth + state.width; + } else { + const defaultWidth = privateDictToUse.getByName('defaultWidthX'); + widths[i] = defaultWidth; } if (state.seac !== null) { seacs[i] = state.seac; diff --git a/test/unit/cff_parser_spec.js b/test/unit/cff_parser_spec.js index 7df4bc113..ee5b8fcbe 100644 --- a/test/unit/cff_parser_spec.js +++ b/test/unit/cff_parser_spec.js @@ -28,6 +28,13 @@ describe('CFFParser', function() { return result; } + // Stub that returns `0` for any privateDict key. + var privateDictStub = { + getByName(name) { + return 0; + }, + }; + var fontData, parser, cff; beforeAll(function (done) { @@ -163,7 +170,10 @@ describe('CFFParser', function() { ]); parser.bytes = bytes; var charStringsIndex = parser.parseIndex(0).obj; - var charStrings = parser.parseCharStrings(charStringsIndex).charStrings; + var charStrings = parser.parseCharStrings({ + charStrings: charStringsIndex, + privateDict: privateDictStub, + }).charStrings; expect(charStrings.count).toEqual(1); // shoudn't be sanitized expect(charStrings.get(0).length).toEqual(38); @@ -180,7 +190,10 @@ describe('CFFParser', function() { 237, 247, 22, 247, 72, 204, 247, 86, 14]); parser.bytes = bytes; var charStringsIndex = parser.parseIndex(0).obj; - var result = parser.parseCharStrings(charStringsIndex); + var result = parser.parseCharStrings({ + charStrings: charStringsIndex, + privateDict: privateDictStub, + }); expect(result.charStrings.count).toEqual(1); expect(result.charStrings.get(0).length).toEqual(1); expect(result.seacs.length).toEqual(1); @@ -202,7 +215,10 @@ describe('CFFParser', function() { 237, 247, 22, 247, 72, 204, 247, 86, 14]); parser.bytes = bytes; var charStringsIndex = parser.parseIndex(0).obj; - var result = parser.parseCharStrings(charStringsIndex); + var result = parser.parseCharStrings({ + charStrings: charStringsIndex, + privateDict: privateDictStub, + }); expect(result.charStrings.count).toEqual(1); expect(result.charStrings.get(0).length).toEqual(9); expect(result.seacs.length).toEqual(0); @@ -215,7 +231,10 @@ describe('CFFParser', function() { 14]); parser.bytes = bytes; var charStringsIndex = parser.parseIndex(0).obj; - var result = parser.parseCharStrings(charStringsIndex); + var result = parser.parseCharStrings({ + charStrings: charStringsIndex, + privateDict: privateDictStub, + }); expect(result.charStrings.count).toEqual(1); expect(result.charStrings.get(0)[0]).toEqual(14); expect(result.seacs.length).toEqual(0);