From 198e9a3db1dceaef6532c88f85e0671f78ac43f2 Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Tue, 20 Sep 2022 18:39:20 +0200 Subject: [PATCH] Initialize values in the path bounding box before flushing the operator list (bug 1791583) OperatorList.addOp can trigger a flush if it's required, hence the values passed to it must be correctly initialized in order to avoid some wrong values in the renderer. Because of that a clip path was considered as empty, nothing was clipped, hence the wrong rendering in bug 1791583. --- src/core/evaluator.js | 66 +++++++++++++++++++++++------------ test/pdfs/bug1791583.pdf.link | 2 ++ test/test_manifest.json | 7 ++++ 3 files changed, 52 insertions(+), 23 deletions(-) create mode 100644 test/pdfs/bug1791583.pdf.link diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 874060c55..e10501baa 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -1359,7 +1359,6 @@ class PartialEvaluator { if (!args) { args = []; } - let minMax; if ( lastIndex < 0 || operatorList.fnArray[lastIndex] !== OPS.constructPath @@ -1376,7 +1375,26 @@ class PartialEvaluator { operatorList.addOp(OPS.save, null); } - minMax = [Infinity, -Infinity, Infinity, -Infinity]; + let minMax; + switch (fn) { + case OPS.rectangle: + const x = args[0] + args[2]; + const y = args[1] + args[3]; + minMax = [ + Math.min(args[0], x), + Math.max(args[0], x), + Math.min(args[1], y), + Math.max(args[1], y), + ]; + break; + case OPS.moveTo: + case OPS.lineTo: + minMax = [args[0], args[0], args[1], args[1]]; + break; + default: + minMax = [Infinity, -Infinity, Infinity, -Infinity]; + break; + } operatorList.addOp(OPS.constructPath, [[fn], args, minMax]); if (parsingText) { @@ -1386,28 +1404,30 @@ class PartialEvaluator { const opArgs = operatorList.argsArray[lastIndex]; opArgs[0].push(fn); Array.prototype.push.apply(opArgs[1], args); - minMax = opArgs[2]; - } + const minMax = opArgs[2]; - // Compute min/max in the worker instead of the main thread. - // If the current matrix (when drawing) is a scaling one - // then min/max can be easily computed in using those values. - // Only rectangle, lineTo and moveTo are handled here since - // Bezier stuff requires to have the starting point. - switch (fn) { - case OPS.rectangle: - minMax[0] = Math.min(minMax[0], args[0], args[0] + args[2]); - minMax[1] = Math.max(minMax[1], args[0], args[0] + args[2]); - minMax[2] = Math.min(minMax[2], args[1], args[1] + args[3]); - minMax[3] = Math.max(minMax[3], args[1], args[1] + args[3]); - break; - case OPS.moveTo: - case OPS.lineTo: - minMax[0] = Math.min(minMax[0], args[0]); - minMax[1] = Math.max(minMax[1], args[0]); - minMax[2] = Math.min(minMax[2], args[1]); - minMax[3] = Math.max(minMax[3], args[1]); - break; + // Compute min/max in the worker instead of the main thread. + // If the current matrix (when drawing) is a scaling one + // then min/max can be easily computed in using those values. + // Only rectangle, lineTo and moveTo are handled here since + // Bezier stuff requires to have the starting point. + switch (fn) { + case OPS.rectangle: + const x = args[0] + args[2]; + const y = args[1] + args[3]; + minMax[0] = Math.min(minMax[0], args[0], x); + minMax[1] = Math.max(minMax[1], args[0], x); + minMax[2] = Math.min(minMax[2], args[1], y); + minMax[3] = Math.max(minMax[3], args[1], y); + break; + case OPS.moveTo: + case OPS.lineTo: + minMax[0] = Math.min(minMax[0], args[0]); + minMax[1] = Math.max(minMax[1], args[0]); + minMax[2] = Math.min(minMax[2], args[1]); + minMax[3] = Math.max(minMax[3], args[1]); + break; + } } } diff --git a/test/pdfs/bug1791583.pdf.link b/test/pdfs/bug1791583.pdf.link new file mode 100644 index 000000000..472678df2 --- /dev/null +++ b/test/pdfs/bug1791583.pdf.link @@ -0,0 +1,2 @@ +https://web.archive.org/web/20220830051811/https://www.tisseo.fr/sites/default/files/plan_general_reseau.pdf + diff --git a/test/test_manifest.json b/test/test_manifest.json index 490aa38c4..83936caa2 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -6896,5 +6896,12 @@ "firstPage": 1, "lastPage": 1, "type": "eq" + }, + { "id": "bug1791583", + "file": "pdfs/bug1791583.pdf", + "md5": "1ff6badc865c9a5e9a0dc0b7131ffe28", + "link": true, + "rounds": 1, + "type": "eq" } ]