Parse the font file to determine the correct type/subtype, rather than relying on the (often incorrect) data in the font dictionary

The current font type/subtype detection code is quite inconsistent/unwieldy. In some cases it will simply assume that the font dictionary is correct, in others it will somewhat "arbitrarily" check the actual font file (more of these cases have been added over the years to fix specific bugs).

As is evident from e.g. issue 9949, the font type/subtype detection code is continuing to cause issues. In an attempt to get rid of these hacks once and for all, this patch instead re-factors the type/subtype detection to *always* parse the font file.

Please note that, as far as I can tell, we still appear to need to rely on the composite font detection based on the font dictionary. However, even if the composite/non-composite detection would get it wrong, that shouldn't really matter too much given that there's basically only two different code-paths (for "TrueType-like" vs "Type1-like" fonts).
This commit is contained in:
Jonas Jenwald 2018-08-05 10:34:14 +02:00
parent 9bbca04579
commit 3177f6aa55

View File

@ -550,36 +550,14 @@ var Font = (function FontClosure() {
return;
}
// Some fonts might use wrong font types for Type1C or CIDFontType0C
if (subtype === 'Type1C') {
if (type !== 'Type1' && type !== 'MMType1') {
// Some TrueType fonts by mistake claim Type1C
if (isTrueTypeFile(file)) {
subtype = 'TrueType';
} else {
type = 'Type1';
}
} else if (isOpenTypeFile(file)) {
// Sometimes the type/subtype can be a complete lie (see issue7598.pdf).
subtype = 'OpenType';
}
}
if (subtype === 'CIDFontType0C' && type !== 'CIDFontType0') {
type = 'CIDFontType0';
}
// Some CIDFontType0C fonts by mistake claim CIDFontType0.
if (type === 'CIDFontType0') {
if (isType1File(file)) {
subtype = 'CIDFontType0';
} else if (isOpenTypeFile(file)) {
// Sometimes the type/subtype can be a complete lie (see issue6782.pdf).
subtype = 'OpenType';
} else {
subtype = 'CIDFontType0C';
}
}
if (subtype === 'OpenType' && type !== 'OpenType') {
type = 'OpenType';
// Parse the font file to determine the correct type/subtype, rather than
// relying on the (often incorrect) data in the font dictionary; (see e.g.
// issue6782.pdf, issue7598.pdf, and issue9949.pdf).
[type, subtype] = getFontFileType(file, properties);
if (type !== this.type || subtype !== this.subtype) {
info('Inconsistent font file Type/SubType, expected: ' +
`${this.type}/${this.subtype} but found: ${type}/${subtype}.`);
}
try {
@ -724,6 +702,46 @@ var Font = (function FontClosure() {
return false;
}
function getFontFileType(file, { type, subtype, composite, }) {
let fileType, fileSubtype;
if (isTrueTypeFile(file) || isTrueTypeCollectionFile(file)) {
if (composite) {
fileType = 'CIDFontType2';
} else {
fileType = 'TrueType';
}
} else if (isOpenTypeFile(file)) {
if (composite) {
fileType = 'CIDFontType2';
} else {
fileType = 'OpenType';
}
} else if (isType1File(file)) {
if (composite) {
fileType = 'CIDFontType0';
} else if (type === 'MMType1') {
fileType = 'MMType1';
} else {
fileType = 'Type1';
}
} else if (isCFFFile(file)) {
if (composite) {
fileType = 'CIDFontType0';
fileSubtype = 'CIDFontType0C';
} else {
fileType = 'Type1';
fileSubtype = 'Type1C';
}
} else {
warn('getFontFileType: Unable to detect correct font file Type/Subtype.');
fileType = type;
fileSubtype = subtype;
}
return [fileType, fileSubtype];
}
function buildToFontChar(encoding, glyphsUnicodeMap, differences) {
var toFontChar = [], unicode;
for (var i = 0, ii = encoding.length; i < ii; i++) {