Ignore color-operators in Type3 glyphs beginning with a d1 operator (issue 12705)

Please refer to the PDF specification at https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf#G8.1977497 and https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf#G7.3998470

This patch removes the color-operators in the evaluator, since that should be more efficient than doing it repeatedly in the main-thread when rendering the Type3 glyphs.
This commit is contained in:
Jonas Jenwald 2020-12-10 14:22:05 +01:00
parent 00b4f86db3
commit 67e5db75d8
4 changed files with 81 additions and 3 deletions

View File

@ -3602,7 +3602,7 @@ class TranslatedFont {
var charProcOperatorList = Object.create(null);
for (const key of charProcs.getKeys()) {
loadCharProcsPromise = loadCharProcsPromise.then(function () {
loadCharProcsPromise = loadCharProcsPromise.then(() => {
var glyphStream = charProcs.get(key);
var operatorList = new OperatorList();
return type3Evaluator
@ -3612,7 +3612,16 @@ class TranslatedFont {
resources: fontResources,
operatorList,
})
.then(function () {
.then(() => {
// According to the PDF specification, section "9.6.5 Type 3 Fonts"
// and "Table 113":
// "A glyph description that begins with the d1 operator should
// not execute any operators that set the colour (or other
// colour-related parameters) in the graphics state;
// any use of such operators shall be ignored."
if (operatorList.fnArray[0] === OPS.setCharWidthAndBounds) {
this._removeType3ColorOperators(operatorList);
}
charProcOperatorList[key] = operatorList.getIR();
for (const dependency of operatorList.dependencies) {
@ -3631,6 +3640,68 @@ class TranslatedFont {
});
return this.type3Loaded;
}
/**
* @private
*/
_removeType3ColorOperators(operatorList) {
if (
typeof PDFJSDev === "undefined" ||
PDFJSDev.test("!PRODUCTION || TESTING")
) {
assert(
operatorList.fnArray[0] === OPS.setCharWidthAndBounds,
"Type3 glyph shall start with the d1 operator."
);
}
let i = 1,
ii = operatorList.length;
while (i < ii) {
switch (operatorList.fnArray[i]) {
case OPS.setStrokeColorSpace:
case OPS.setFillColorSpace:
case OPS.setStrokeColor:
case OPS.setStrokeColorN:
case OPS.setFillColor:
case OPS.setFillColorN:
case OPS.setStrokeGray:
case OPS.setFillGray:
case OPS.setStrokeRGBColor:
case OPS.setFillRGBColor:
case OPS.setStrokeCMYKColor:
case OPS.setFillCMYKColor:
case OPS.shadingFill:
case OPS.setRenderingIntent:
operatorList.fnArray.splice(i, 1);
operatorList.argsArray.splice(i, 1);
ii--;
continue;
case OPS.setGState:
const gStateObj = operatorList.argsArray[i];
let j = 0,
jj = gStateObj.length;
while (j < jj) {
const [gStateKey] = gStateObj[j];
switch (gStateKey) {
case "TR":
case "TR2":
case "HT":
case "BG":
case "BG2":
case "UCR":
case "UCR2":
gStateObj.splice(j, 1);
jj--;
continue;
}
j++;
}
break;
}
i++;
}
}
}
class StateManager {

View File

@ -222,6 +222,7 @@
!issue5734.pdf
!issue4875.pdf
!issue11740_reduced.pdf
!issue12705.pdf
!issue4881.pdf
!issue5994.pdf
!issue6151.pdf

BIN
test/pdfs/issue12705.pdf Normal file

Binary file not shown.

View File

@ -4531,6 +4531,12 @@
"annotations": true,
"type": "eq"
},
{ "id": "issue12705",
"file": "pdfs/issue12705.pdf",
"md5": "d8725b9dcfef72fd4fa4a39cab711624",
"rounds": 1,
"type": "eq"
},
{ "id": "annotation-strikeout",
"file": "pdfs/annotation-strikeout.pdf",
"md5": "6624e6b5bedd2f2855b6ab12bbf93c57",