Merge pull request #8627 from yurydelendik/issue-8591

Fallback on font widths if CFF data is broken
This commit is contained in:
Brendan Dahl 2017-08-02 10:53:14 -07:00 committed by GitHub
commit 5b7f712ca7
2 changed files with 41 additions and 17 deletions

View File

@ -268,12 +268,14 @@ var CFFParser = (function CFFParserClosure() {
cff.charset = charset; cff.charset = charset;
cff.encoding = encoding; cff.encoding = encoding;
var charStringsAndSeacs = this.parseCharStrings( var charStringsAndSeacs = this.parseCharStrings({
charStringIndex, charStrings: charStringIndex,
topDict.privateDict.subrsIndex, localSubrIndex: topDict.privateDict.subrsIndex,
globalSubrIndex.obj, globalSubrIndex: globalSubrIndex.obj,
cff.fdSelect, fdSelect: cff.fdSelect,
cff.fdArray); fdArray: cff.fdArray,
privateDict: topDict.privateDict,
});
cff.charStrings = charStringsAndSeacs.charStrings; cff.charStrings = charStringsAndSeacs.charStrings;
cff.seacs = charStringsAndSeacs.seacs; cff.seacs = charStringsAndSeacs.seacs;
cff.widths = charStringsAndSeacs.widths; cff.widths = charStringsAndSeacs.widths;
@ -601,11 +603,8 @@ var CFFParser = (function CFFParserClosure() {
state.stackSize = stackSize; state.stackSize = stackSize;
return true; return true;
}, },
parseCharStrings: function CFFParser_parseCharStrings(charStrings, parseCharStrings({ charStrings, localSubrIndex, globalSubrIndex, fdSelect,
localSubrIndex, fdArray, privateDict, }) {
globalSubrIndex,
fdSelect,
fdArray) {
var seacs = []; var seacs = [];
var widths = []; var widths = [];
var count = charStrings.count; var count = charStrings.count;
@ -623,6 +622,7 @@ var CFFParser = (function CFFParserClosure() {
}; };
var valid = true; var valid = true;
var localSubrToUse = null; var localSubrToUse = null;
var privateDictToUse = privateDict;
if (fdSelect && fdArray.length) { if (fdSelect && fdArray.length) {
var fdIndex = fdSelect.getFDIndex(i); var fdIndex = fdSelect.getFDIndex(i);
if (fdIndex === -1) { if (fdIndex === -1) {
@ -634,7 +634,8 @@ var CFFParser = (function CFFParserClosure() {
valid = false; valid = false;
} }
if (valid) { if (valid) {
localSubrToUse = fdArray[fdIndex].privateDict.subrsIndex; privateDictToUse = fdArray[fdIndex].privateDict;
localSubrToUse = privateDictToUse.subrsIndex;
} }
} else if (localSubrIndex) { } else if (localSubrIndex) {
localSubrToUse = localSubrIndex; localSubrToUse = localSubrIndex;
@ -644,7 +645,11 @@ var CFFParser = (function CFFParserClosure() {
globalSubrIndex); globalSubrIndex);
} }
if (state.width !== null) { 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) { if (state.seac !== null) {
seacs[i] = state.seac; seacs[i] = state.seac;

View File

@ -28,6 +28,13 @@ describe('CFFParser', function() {
return result; return result;
} }
// Stub that returns `0` for any privateDict key.
var privateDictStub = {
getByName(name) {
return 0;
},
};
var fontData, parser, cff; var fontData, parser, cff;
beforeAll(function (done) { beforeAll(function (done) {
@ -163,7 +170,10 @@ describe('CFFParser', function() {
]); ]);
parser.bytes = bytes; parser.bytes = bytes;
var charStringsIndex = parser.parseIndex(0).obj; 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); expect(charStrings.count).toEqual(1);
// shoudn't be sanitized // shoudn't be sanitized
expect(charStrings.get(0).length).toEqual(38); expect(charStrings.get(0).length).toEqual(38);
@ -180,7 +190,10 @@ describe('CFFParser', function() {
237, 247, 22, 247, 72, 204, 247, 86, 14]); 237, 247, 22, 247, 72, 204, 247, 86, 14]);
parser.bytes = bytes; parser.bytes = bytes;
var charStringsIndex = parser.parseIndex(0).obj; 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.count).toEqual(1);
expect(result.charStrings.get(0).length).toEqual(1); expect(result.charStrings.get(0).length).toEqual(1);
expect(result.seacs.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]); 237, 247, 22, 247, 72, 204, 247, 86, 14]);
parser.bytes = bytes; parser.bytes = bytes;
var charStringsIndex = parser.parseIndex(0).obj; 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.count).toEqual(1);
expect(result.charStrings.get(0).length).toEqual(9); expect(result.charStrings.get(0).length).toEqual(9);
expect(result.seacs.length).toEqual(0); expect(result.seacs.length).toEqual(0);
@ -215,7 +231,10 @@ describe('CFFParser', function() {
14]); 14]);
parser.bytes = bytes; parser.bytes = bytes;
var charStringsIndex = parser.parseIndex(0).obj; 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.count).toEqual(1);
expect(result.charStrings.get(0)[0]).toEqual(14); expect(result.charStrings.get(0)[0]).toEqual(14);
expect(result.seacs.length).toEqual(0); expect(result.seacs.length).toEqual(0);