Fix the group bbox when the numbers are too big

It fixes #20872.
This commit is contained in:
calixteman 2026-03-21 16:42:49 +01:00
parent 918a319de6
commit 5992d0f097
No known key found for this signature in database
GPG Key ID: 0C5442631EE0691F
4 changed files with 42 additions and 24 deletions

View File

@ -483,6 +483,10 @@ class PartialEvaluator {
const { dict } = xobj;
const matrix = lookupMatrix(dict.getArray("Matrix"), null);
const bbox = lookupNormalRect(dict.getArray("BBox"), null);
let f32bbox = bbox && new Float32Array(bbox);
if (f32bbox?.some(x => !isFinite(x))) {
f32bbox = null;
}
let optionalContent, groupOptions;
if (dict.has("OC")) {
@ -498,7 +502,7 @@ class PartialEvaluator {
if (group) {
groupOptions = {
matrix,
bbox,
bbox: f32bbox,
smask,
isolated: false,
knockout: false,
@ -532,8 +536,7 @@ class PartialEvaluator {
// bounding box and translated to the correct position so we don't need to
// apply the bounding box to it.
const f32matrix = matrix && new Float32Array(matrix);
const f32bbox = (!group && bbox && new Float32Array(bbox)) || null;
const args = [f32matrix, f32bbox];
const args = [f32matrix, (!group && f32bbox) || null];
operatorList.addOp(OPS.paintFormXObjectBegin, args);
const localResources = dict.get("Resources");

View File

@ -2576,18 +2576,6 @@ class CanvasGraphics {
if (group.matrix) {
currentCtx.transform(...group.matrix);
}
if (!group.bbox) {
throw new Error("Bounding box is required.");
}
// Based on the current transform figure out how big the bounding box
// will actually be.
let bounds = MIN_MAX_INIT.slice();
Util.axialAlignedBoundingBox(
group.bbox,
getCurrentTransform(currentCtx),
bounds
);
// Clip the bounding box to the current canvas.
const canvasBounds = [
@ -2596,7 +2584,23 @@ class CanvasGraphics {
currentCtx.canvas.width,
currentCtx.canvas.height,
];
let bounds;
if (group.bbox) {
bounds = MIN_MAX_INIT.slice();
Util.axialAlignedBoundingBox(
group.bbox,
getCurrentTransform(currentCtx),
bounds
);
bounds = Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0];
} else {
bounds = canvasBounds;
}
// Based on the current transform figure out how big the bounding box
// will actually be.
// Use ceil in case we're between sizes so we don't create canvas that is
// too small and make the canvas at least 1x1 pixels.
const offsetX = Math.floor(bounds[0]);
@ -2624,6 +2628,7 @@ class CanvasGraphics {
groupCtx.transform(...currentTransform);
// Apply the bbox to the group context.
if (group.bbox) {
let clip = new Path2D();
const [x0, y0, x1, y1] = group.bbox;
clip.rect(x0, y0, x1 - x0, y1 - y0);
@ -2633,6 +2638,7 @@ class CanvasGraphics {
clip = path;
}
groupCtx.clip(clip);
}
if (group.smask) {
// Saving state and cached mask to be used in setGState.

View File

@ -0,0 +1 @@
https://github.com/user-attachments/files/26001581/issue20872.pdf

View File

@ -14012,5 +14012,13 @@
"md5": "321f0901af604a6052baa7b2855a7e3e",
"rounds": 1,
"type": "text"
},
{
"id": "issue20872",
"file": "pdfs/issue20872.pdf",
"md5": "2394eea595990d0148b209fe49f035e5",
"rounds": 1,
"link": true,
"type": "eq"
}
]