Avoid all rendering breaking completely when CanvasPattern.setTransform()
is unsupported
*Please note:* This patch doesn't fix rendering of (various) patterns in browsers/environments without full `CanvasPattern.setTransform()` support, but it at least prevents outright failures and thus allows the rest of the page to render. This patch provides a temporary work-around for Firefox 78 ESR[1], and for Node.js environments (see issue 13724), where rendering is currently completely broken. --- [1] Please note that the `createMatrix` helper function doesn't actually work as intended. The reason is that it's not `DOMMatrix` itself which is unsupported in older Firefox versions, but rather calling `CanvasPattern.setTransform(...)` with a `DOMMatrix`-argument. Furthermore, the `createSVGMatrix` fallback won't actually help either since that method doesn't accept any parameters and would thus require *manually* specifying the matrix-state; see e.g. https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern/setTransform#examples Finally, given that it's less than a month to the [Firefox 91 ESR release](https://wiki.mozilla.org/RapidRelease/Calendar) and that as-is all patterns are completely broken e.g. when using the latest viewer in Firefox 78 ESR, I'm just not convinced that it's worth the "hassle" of providing a more proper work-around.
This commit is contained in:
parent
a17bd13023
commit
b6c6a0cb7c
@ -19,22 +19,8 @@ import {
|
|||||||
shadow,
|
shadow,
|
||||||
unreachable,
|
unreachable,
|
||||||
Util,
|
Util,
|
||||||
|
warn,
|
||||||
} from "../shared/util.js";
|
} from "../shared/util.js";
|
||||||
import { DOMSVGFactory } from "./display_utils.js";
|
|
||||||
|
|
||||||
let svgElement;
|
|
||||||
|
|
||||||
// TODO: remove this when Firefox ESR supports DOMMatrix.
|
|
||||||
function createMatrix(matrix) {
|
|
||||||
if (typeof DOMMatrix !== "undefined") {
|
|
||||||
return new DOMMatrix(matrix);
|
|
||||||
}
|
|
||||||
if (!svgElement) {
|
|
||||||
const svgFactory = new DOMSVGFactory();
|
|
||||||
svgElement = svgFactory.createElement("svg");
|
|
||||||
}
|
|
||||||
return svgElement.createSVGMatrix(matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyBoundingBox(ctx, bbox) {
|
function applyBoundingBox(ctx, bbox) {
|
||||||
if (!bbox || typeof Path2D === "undefined") {
|
if (!bbox || typeof Path2D === "undefined") {
|
||||||
@ -120,8 +106,16 @@ class RadialAxialShadingPattern extends BaseShadingPattern {
|
|||||||
tmpCtx.fillStyle = grad;
|
tmpCtx.fillStyle = grad;
|
||||||
tmpCtx.fill();
|
tmpCtx.fill();
|
||||||
|
|
||||||
|
const domMatrix = new DOMMatrix(inverse);
|
||||||
|
|
||||||
const pattern = ctx.createPattern(tmpCanvas.canvas, "repeat");
|
const pattern = ctx.createPattern(tmpCanvas.canvas, "repeat");
|
||||||
pattern.setTransform(createMatrix(inverse));
|
try {
|
||||||
|
pattern.setTransform(domMatrix);
|
||||||
|
} catch (ex) {
|
||||||
|
// Avoid rendering breaking completely in Firefox 78 ESR,
|
||||||
|
// and in Node.js (see issue 13724).
|
||||||
|
warn(`RadialAxialShadingPattern.getPattern: "${ex?.message}".`);
|
||||||
|
}
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -627,7 +621,7 @@ class TilingPattern {
|
|||||||
|
|
||||||
const temporaryPatternCanvas = this.createPatternCanvas(owner);
|
const temporaryPatternCanvas = this.createPatternCanvas(owner);
|
||||||
|
|
||||||
let domMatrix = createMatrix(matrix);
|
let domMatrix = new DOMMatrix(matrix);
|
||||||
// Rescale and so that the ctx.createPattern call generates a pattern with
|
// Rescale and so that the ctx.createPattern call generates a pattern with
|
||||||
// the desired size.
|
// the desired size.
|
||||||
domMatrix = domMatrix.translate(
|
domMatrix = domMatrix.translate(
|
||||||
@ -640,10 +634,15 @@ class TilingPattern {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const pattern = ctx.createPattern(temporaryPatternCanvas.canvas, "repeat");
|
const pattern = ctx.createPattern(temporaryPatternCanvas.canvas, "repeat");
|
||||||
pattern.setTransform(domMatrix);
|
try {
|
||||||
|
pattern.setTransform(domMatrix);
|
||||||
|
} catch (ex) {
|
||||||
|
// Avoid rendering breaking completely in Firefox 78 ESR,
|
||||||
|
// and in Node.js (see issue 13724).
|
||||||
|
warn(`TilingPattern.getPattern: "${ex?.message}".`);
|
||||||
|
}
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { createMatrix, getShadingPattern, TilingPattern };
|
export { getShadingPattern, TilingPattern };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user