Merge pull request #13565 from brendandahl/fix-pattern-mask
Fix how patterns are applied to image mask objects.
This commit is contained in:
commit
d6deb95f11
@ -13,6 +13,11 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
createMatrix,
|
||||||
|
getShadingPattern,
|
||||||
|
TilingPattern,
|
||||||
|
} from "./pattern_helper.js";
|
||||||
import {
|
import {
|
||||||
FONT_IDENTITY_MATRIX,
|
FONT_IDENTITY_MATRIX,
|
||||||
IDENTITY_MATRIX,
|
IDENTITY_MATRIX,
|
||||||
@ -27,7 +32,6 @@ import {
|
|||||||
Util,
|
Util,
|
||||||
warn,
|
warn,
|
||||||
} from "../shared/util.js";
|
} from "../shared/util.js";
|
||||||
import { getShadingPattern, TilingPattern } from "./pattern_helper.js";
|
|
||||||
|
|
||||||
// <canvas> contexts store most of the state we need natively.
|
// <canvas> contexts store most of the state we need natively.
|
||||||
// However, PDF needs a bit more state, which we store here.
|
// However, PDF needs a bit more state, which we store here.
|
||||||
@ -193,6 +197,17 @@ function addContextCurrentTransform(ctx) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAdjustmentTransformation(transform, width, height) {
|
||||||
|
// The pattern will be created at the size of the current page or form object,
|
||||||
|
// but the mask is usually scaled differently and offset, so we must account
|
||||||
|
// for these to shift and rescale the pattern to the correctly location.
|
||||||
|
let patternTransform = createMatrix(transform);
|
||||||
|
patternTransform = patternTransform.scale(1 / width, -1 / height);
|
||||||
|
patternTransform = patternTransform.translate(0, -height);
|
||||||
|
patternTransform = patternTransform.inverse();
|
||||||
|
return patternTransform;
|
||||||
|
}
|
||||||
|
|
||||||
class CachedCanvases {
|
class CachedCanvases {
|
||||||
constructor(canvasFactory) {
|
constructor(canvasFactory) {
|
||||||
this.canvasFactory = canvasFactory;
|
this.canvasFactory = canvasFactory;
|
||||||
@ -2294,8 +2309,16 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
|
|
||||||
maskCtx.globalCompositeOperation = "source-in";
|
maskCtx.globalCompositeOperation = "source-in";
|
||||||
|
|
||||||
|
let patternTransform = null;
|
||||||
|
if (isPatternFill) {
|
||||||
|
patternTransform = getAdjustmentTransformation(
|
||||||
|
ctx.mozCurrentTransform,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
);
|
||||||
|
}
|
||||||
maskCtx.fillStyle = isPatternFill
|
maskCtx.fillStyle = isPatternFill
|
||||||
? fillColor.getPattern(maskCtx, this)
|
? fillColor.getPattern(maskCtx, this, false, patternTransform)
|
||||||
: fillColor;
|
: fillColor;
|
||||||
maskCtx.fillRect(0, 0, width, height);
|
maskCtx.fillRect(0, 0, width, height);
|
||||||
|
|
||||||
@ -2332,14 +2355,23 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
|
|
||||||
maskCtx.globalCompositeOperation = "source-in";
|
maskCtx.globalCompositeOperation = "source-in";
|
||||||
|
|
||||||
|
const ctx = this.ctx;
|
||||||
|
let patternTransform = null;
|
||||||
|
if (isPatternFill) {
|
||||||
|
patternTransform = getAdjustmentTransformation(
|
||||||
|
ctx.mozCurrentTransform,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
maskCtx.fillStyle = isPatternFill
|
maskCtx.fillStyle = isPatternFill
|
||||||
? fillColor.getPattern(maskCtx, this)
|
? fillColor.getPattern(maskCtx, this, false, patternTransform)
|
||||||
: fillColor;
|
: fillColor;
|
||||||
maskCtx.fillRect(0, 0, width, height);
|
maskCtx.fillRect(0, 0, width, height);
|
||||||
|
|
||||||
maskCtx.restore();
|
maskCtx.restore();
|
||||||
|
|
||||||
const ctx = this.ctx;
|
|
||||||
for (let i = 0, ii = positions.length; i < ii; i += 2) {
|
for (let i = 0, ii = positions.length; i < ii; i += 2) {
|
||||||
ctx.save();
|
ctx.save();
|
||||||
ctx.transform(
|
ctx.transform(
|
||||||
@ -2381,8 +2413,17 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
|
|
||||||
maskCtx.globalCompositeOperation = "source-in";
|
maskCtx.globalCompositeOperation = "source-in";
|
||||||
|
|
||||||
|
let patternTransform = null;
|
||||||
|
if (isPatternFill) {
|
||||||
|
patternTransform = getAdjustmentTransformation(
|
||||||
|
ctx.mozCurrentTransform,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
maskCtx.fillStyle = isPatternFill
|
maskCtx.fillStyle = isPatternFill
|
||||||
? fillColor.getPattern(maskCtx, this)
|
? fillColor.getPattern(maskCtx, this, false, patternTransform)
|
||||||
: fillColor;
|
: fillColor;
|
||||||
maskCtx.fillRect(0, 0, width, height);
|
maskCtx.fillRect(0, 0, width, height);
|
||||||
|
|
||||||
|
@ -72,11 +72,11 @@ class RadialAxialShadingPattern extends BaseShadingPattern {
|
|||||||
this._matrix = IR[8];
|
this._matrix = IR[8];
|
||||||
}
|
}
|
||||||
|
|
||||||
getPattern(ctx, owner, shadingFill) {
|
getPattern(ctx, owner, shadingFill = false, patternTransform = null) {
|
||||||
const tmpCanvas = owner.cachedCanvases.getCanvas(
|
const tmpCanvas = owner.cachedCanvases.getCanvas(
|
||||||
"pattern",
|
"pattern",
|
||||||
ctx.canvas.width,
|
owner.ctx.canvas.width,
|
||||||
ctx.canvas.height,
|
owner.ctx.canvas.height,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -121,7 +121,11 @@ class RadialAxialShadingPattern extends BaseShadingPattern {
|
|||||||
tmpCtx.fill();
|
tmpCtx.fill();
|
||||||
|
|
||||||
const pattern = ctx.createPattern(tmpCanvas.canvas, "repeat");
|
const pattern = ctx.createPattern(tmpCanvas.canvas, "repeat");
|
||||||
pattern.setTransform(createMatrix(ctx.mozCurrentTransformInverse));
|
if (patternTransform) {
|
||||||
|
pattern.setTransform(patternTransform);
|
||||||
|
} else {
|
||||||
|
pattern.setTransform(createMatrix(ctx.mozCurrentTransformInverse));
|
||||||
|
}
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -376,7 +380,7 @@ class MeshShadingPattern extends BaseShadingPattern {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getPattern(ctx, owner, shadingFill) {
|
getPattern(ctx, owner, shadingFill = false, patternTransform = null) {
|
||||||
applyBoundingBox(ctx, this._bbox);
|
applyBoundingBox(ctx, this._bbox);
|
||||||
let scale;
|
let scale;
|
||||||
if (shadingFill) {
|
if (shadingFill) {
|
||||||
@ -599,7 +603,7 @@ class TilingPattern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getPattern(ctx, owner, shadingFill) {
|
getPattern(ctx, owner, shadingFill = false, patternTransform = null) {
|
||||||
ctx = this.ctx;
|
ctx = this.ctx;
|
||||||
// PDF spec 8.7.2 NOTE 1: pattern's matrix is relative to initial matrix.
|
// PDF spec 8.7.2 NOTE 1: pattern's matrix is relative to initial matrix.
|
||||||
let matrix = ctx.mozCurrentTransformInverse;
|
let matrix = ctx.mozCurrentTransformInverse;
|
||||||
@ -627,4 +631,4 @@ class TilingPattern {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { getShadingPattern, TilingPattern };
|
export { createMatrix, getShadingPattern, TilingPattern };
|
||||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -406,6 +406,7 @@
|
|||||||
!issue13193.pdf
|
!issue13193.pdf
|
||||||
!annotation-underline-without-appearance.pdf
|
!annotation-underline-without-appearance.pdf
|
||||||
!issue269_2.pdf
|
!issue269_2.pdf
|
||||||
|
!issue13372.pdf
|
||||||
!annotation-strikeout.pdf
|
!annotation-strikeout.pdf
|
||||||
!annotation-strikeout-without-appearance.pdf
|
!annotation-strikeout-without-appearance.pdf
|
||||||
!annotation-squiggly.pdf
|
!annotation-squiggly.pdf
|
||||||
|
BIN
test/pdfs/issue13372.pdf
Normal file
BIN
test/pdfs/issue13372.pdf
Normal file
Binary file not shown.
@ -1566,6 +1566,12 @@
|
|||||||
"rounds": 1,
|
"rounds": 1,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "issue13372",
|
||||||
|
"file": "pdfs/issue13372.pdf",
|
||||||
|
"md5": "0bc5329623fd554174c5e7653f904e28",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "simpletype3font-text",
|
{ "id": "simpletype3font-text",
|
||||||
"file": "pdfs/simpletype3font.pdf",
|
"file": "pdfs/simpletype3font.pdf",
|
||||||
"md5": "b374c7543920840c61999e9e86939f99",
|
"md5": "b374c7543920840c61999e9e86939f99",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user