From a254de86fb6c04c15a660a45eb0ad385670fd96d Mon Sep 17 00:00:00 2001 From: vyv03354 Date: Sat, 26 Jan 2013 22:08:45 +0900 Subject: [PATCH] CFF parser didn't count hints defined by hstem/vstem --- src/fonts.js | 18 +++++++++--------- test/unit/font_spec.js | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/fonts.js b/src/fonts.js index 500bc732b..ffb3f2a21 100644 --- a/src/fonts.js +++ b/src/fonts.js @@ -5453,9 +5453,9 @@ var CFFFont = (function CFFFontClosure() { var CFFParser = (function CFFParserClosure() { var CharstringValidationData = [ null, - { id: 'hstem', min: 2, resetStack: true }, + { id: 'hstem', min: 2, resetStack: true, stem: true }, null, - { id: 'vstem', min: 2, resetStack: true }, + { id: 'vstem', min: 2, resetStack: true, stem: true }, { id: 'vmoveto', min: 1, resetStack: true }, { id: 'rlineto', min: 2, resetStack: true }, { id: 'hlineto', min: 1, resetStack: true }, @@ -5463,19 +5463,19 @@ var CFFParser = (function CFFParserClosure() { { id: 'rrcurveto', min: 6, resetStack: true }, null, { id: 'callsubr', min: 1, undefStack: true }, - { id: 'return', min: 0, resetStack: true }, + { id: 'return', min: 0, undefStack: true }, null, // 12 null, null, // endchar null, null, null, - { id: 'hstemhm', min: 2, resetStack: true }, + { id: 'hstemhm', min: 2, resetStack: true, stem: true }, null, // hintmask null, // cntrmask { id: 'rmoveto', min: 2, resetStack: true }, { id: 'hmoveto', min: 1, resetStack: true }, - { id: 'vstemhm', min: 2, resetStack: true }, + { id: 'vstemhm', min: 2, resetStack: true, stem: true }, { id: 'rcurveline', min: 8, resetStack: true }, { id: 'rlinecurve', min: 8, resetStack: true }, { id: 'vvcurveto', min: 4, resetStack: true }, @@ -5491,7 +5491,7 @@ var CFFParser = (function CFFParserClosure() { null, { id: 'and', min: 2, stackDelta: -1 }, { id: 'or', min: 2, stackDelta: -1 }, - { id: 'not', min: 2, stackDelta: -1 }, + { id: 'not', min: 1, stackDelta: 0 }, null, null, null, @@ -5811,9 +5811,6 @@ var CFFParser = (function CFFParserClosure() { } else if (value == 255) { // number (32 bit) j += 4; stackSize++; - } else if (value == 18 || value == 23) { - hints += stackSize >> 1; - validationCommand = CharstringValidationData[value]; } else if (value == 19 || value == 20) { hints += stackSize >> 1; j += (hints + 7) >> 3; // skipping right amount of hints flag data @@ -5822,6 +5819,9 @@ var CFFParser = (function CFFParserClosure() { validationCommand = CharstringValidationData[value]; } if (validationCommand) { + if (validationCommand.stem) { + hints += stackSize >> 1; + } if ('min' in validationCommand) { if (!undefStack && stackSize < validationCommand.min) { warn('Not enough parameters for ' + validationCommand.id + diff --git a/test/unit/font_spec.js b/test/unit/font_spec.js index b2436778d..96d7a33f1 100644 --- a/test/unit/font_spec.js +++ b/test/unit/font_spec.js @@ -96,6 +96,28 @@ describe('font', function() { expect(topDict.getByName('Private')).toEqual([45, 102]); }); + it('parses a CharString having cntrmask', function() { + var bytes = new Uint8Array([0, 1, // count + 1, // offsetSize + 0, // offset[0] + 38, // end + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 1, // hstem + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 3, // vstem + 20, // cntrmask + 22, 22, // fail if misparsed as hmoveto + 14 // endchar + ]); + parser.bytes = bytes; + var charStrings = parser.parseCharStrings(0); + expect(charStrings.count).toEqual(1); + // shoudn't be sanitized + expect(charStrings.get(0).length).toEqual(38); + }); + it('parses predefined charsets', function() { var charset = parser.parseCharsets(0, 0, null, true); expect(charset.predefined).toEqual(true);