mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-07-28 01:47:22 +02:00
Merge pull request #21096 from calixteman/issue13520
Fix blending issues while compositing
This commit is contained in:
commit
d1ef620541
@ -644,7 +644,6 @@ class CanvasGraphics {
|
|||||||
this.baseTransformStack = [];
|
this.baseTransformStack = [];
|
||||||
this.groupLevel = 0;
|
this.groupLevel = 0;
|
||||||
this.smaskStack = [];
|
this.smaskStack = [];
|
||||||
this.smaskCounter = 0;
|
|
||||||
this.tempSMask = null;
|
this.tempSMask = null;
|
||||||
this.smaskGroupCanvases = [];
|
this.smaskGroupCanvases = [];
|
||||||
this.suspendedCtx = null;
|
this.suspendedCtx = null;
|
||||||
@ -712,7 +711,7 @@ class CanvasGraphics {
|
|||||||
if (transform) {
|
if (transform) {
|
||||||
this.ctx.transform(...transform);
|
this.ctx.transform(...transform);
|
||||||
this.outputScaleX = transform[0];
|
this.outputScaleX = transform[0];
|
||||||
this.outputScaleY = transform[0];
|
this.outputScaleY = transform[3];
|
||||||
}
|
}
|
||||||
this.ctx.transform(...viewport.transform);
|
this.ctx.transform(...viewport.transform);
|
||||||
this.viewportScale = viewport.scale;
|
this.viewportScale = viewport.scale;
|
||||||
@ -1231,8 +1230,14 @@ class CanvasGraphics {
|
|||||||
case "SMask":
|
case "SMask":
|
||||||
this.dependencyTracker?.recordSimpleData("SMask", opIdx);
|
this.dependencyTracker?.recordSimpleData("SMask", opIdx);
|
||||||
this.current.activeSMask = value ? this.tempSMask : null;
|
this.current.activeSMask = value ? this.tempSMask : null;
|
||||||
|
if (this.current.activeSMask) {
|
||||||
|
// Save the current blend mode so that it can be applied when
|
||||||
|
// compositing the SMask result back to the main canvas.
|
||||||
|
this.current.activeSMask.blendMode =
|
||||||
|
this.ctx.globalCompositeOperation;
|
||||||
|
}
|
||||||
this.tempSMask = null;
|
this.tempSMask = null;
|
||||||
this.checkSMaskState();
|
this.checkSMaskState(opIdx);
|
||||||
break;
|
break;
|
||||||
case "TR":
|
case "TR":
|
||||||
this.dependencyTracker?.recordSimpleData("filter", opIdx);
|
this.dependencyTracker?.recordSimpleData("filter", opIdx);
|
||||||
@ -1247,10 +1252,10 @@ class CanvasGraphics {
|
|||||||
return !!this.suspendedCtx;
|
return !!this.suspendedCtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkSMaskState() {
|
checkSMaskState(opIdx) {
|
||||||
const inSMaskMode = this.inSMaskMode;
|
const inSMaskMode = this.inSMaskMode;
|
||||||
if (this.current.activeSMask && !inSMaskMode) {
|
if (this.current.activeSMask && !inSMaskMode) {
|
||||||
this.beginSMaskMode();
|
this.beginSMaskMode(opIdx);
|
||||||
} else if (!this.current.activeSMask && inSMaskMode) {
|
} else if (!this.current.activeSMask && inSMaskMode) {
|
||||||
this.endSMaskMode();
|
this.endSMaskMode();
|
||||||
}
|
}
|
||||||
@ -1346,7 +1351,7 @@ class CanvasGraphics {
|
|||||||
);
|
);
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.globalAlpha = 1;
|
ctx.globalAlpha = 1;
|
||||||
ctx.globalCompositeOperation = "source-over";
|
ctx.globalCompositeOperation = smask.blendMode || "source-over";
|
||||||
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
ctx.drawImage(layerCtx.canvas, 0, 0);
|
ctx.drawImage(layerCtx.canvas, 0, 0);
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
@ -1463,7 +1468,7 @@ class CanvasGraphics {
|
|||||||
// state then copy it over to the temporary canvas.
|
// state then copy it over to the temporary canvas.
|
||||||
copyCtxState(this.suspendedCtx, this.ctx);
|
copyCtxState(this.suspendedCtx, this.ctx);
|
||||||
}
|
}
|
||||||
this.checkSMaskState();
|
this.checkSMaskState(opIdx);
|
||||||
|
|
||||||
// Ensure that the clipping path is reset (fixes issue6413.pdf).
|
// Ensure that the clipping path is reset (fixes issue6413.pdf).
|
||||||
this.pendingClip = null;
|
this.pendingClip = null;
|
||||||
@ -2687,9 +2692,6 @@ class CanvasGraphics {
|
|||||||
|
|
||||||
this.current.startNewPathAndClipBox([0, 0, drawnWidth, drawnHeight]);
|
this.current.startNewPathAndClipBox([0, 0, drawnWidth, drawnHeight]);
|
||||||
|
|
||||||
if (group.smask) {
|
|
||||||
this.smaskCounter++;
|
|
||||||
}
|
|
||||||
const scratchCanvas = this.canvasFactory.create(drawnWidth, drawnHeight);
|
const scratchCanvas = this.canvasFactory.create(drawnWidth, drawnHeight);
|
||||||
if (group.smask) {
|
if (group.smask) {
|
||||||
this.smaskGroupCanvases.push(scratchCanvas);
|
this.smaskGroupCanvases.push(scratchCanvas);
|
||||||
@ -2701,6 +2703,24 @@ class CanvasGraphics {
|
|||||||
groupCtx.translate(-offsetX, -offsetY);
|
groupCtx.translate(-offsetX, -offsetY);
|
||||||
groupCtx.transform(...currentTransform);
|
groupCtx.transform(...currentTransform);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!group.isolated &&
|
||||||
|
!group.smask &&
|
||||||
|
inSMaskMode &&
|
||||||
|
group.needsIsolation
|
||||||
|
) {
|
||||||
|
// For non-isolated groups that need isolation and are entered from SMask
|
||||||
|
// mode, copy the current canvas background so that inner blend modes
|
||||||
|
// (e.g. "screen") interact correctly with the background rather than
|
||||||
|
// compositing onto a transparent canvas.
|
||||||
|
// Groups without needsIsolation have no inner blend modes; their content
|
||||||
|
// is composited correctly via the SMask in endGroup without a copy.
|
||||||
|
groupCtx.save();
|
||||||
|
groupCtx.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
|
groupCtx.drawImage(currentCtx.canvas, -offsetX, -offsetY);
|
||||||
|
groupCtx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
// Apply the bbox to the group context.
|
// Apply the bbox to the group context.
|
||||||
if (group.bbox) {
|
if (group.bbox) {
|
||||||
let clip = new Path2D();
|
let clip = new Path2D();
|
||||||
@ -2724,7 +2744,6 @@ class CanvasGraphics {
|
|||||||
subtype: group.smask.subtype,
|
subtype: group.smask.subtype,
|
||||||
backdrop: group.smask.backdrop,
|
backdrop: group.smask.backdrop,
|
||||||
transferMap: group.smask.transferMap || null,
|
transferMap: group.smask.transferMap || null,
|
||||||
startTransformInverse: null, // used during suspend operation
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
|
|||||||
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -902,3 +902,4 @@
|
|||||||
!recursiveCompositGlyf.pdf
|
!recursiveCompositGlyf.pdf
|
||||||
!issue19634.pdf
|
!issue19634.pdf
|
||||||
!three_pages_with_number.pdf
|
!three_pages_with_number.pdf
|
||||||
|
!issue13520.pdf
|
||||||
|
|||||||
6601
test/pdfs/issue13520.pdf
Normal file
6601
test/pdfs/issue13520.pdf
Normal file
File diff suppressed because one or more lines are too long
@ -14119,5 +14119,12 @@
|
|||||||
"md5": "ae33892db2a2421ec7c9c3e2aee07205",
|
"md5": "ae33892db2a2421ec7c9c3e2aee07205",
|
||||||
"rounds": 1,
|
"rounds": 1,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "issue13520",
|
||||||
|
"file": "pdfs/issue13520.pdf",
|
||||||
|
"md5": "5a690e2303604441308f808b5fc33e22",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "eq"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user