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.
This commit is contained in:
Calixte Denizet 2022-09-20 18:39:20 +02:00
parent ff8f850936
commit 198e9a3db1
3 changed files with 52 additions and 23 deletions

View File

@ -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;
}
}
}

View File

@ -0,0 +1,2 @@
https://web.archive.org/web/20220830051811/https://www.tisseo.fr/sites/default/files/plan_general_reseau.pdf

View File

@ -6896,5 +6896,12 @@
"firstPage": 1,
"lastPage": 1,
"type": "eq"
},
{ "id": "bug1791583",
"file": "pdfs/bug1791583.pdf",
"md5": "1ff6badc865c9a5e9a0dc0b7131ffe28",
"link": true,
"rounds": 1,
"type": "eq"
}
]