Merge pull request #20525 from calixteman/simplify_gradient

Avoid pattern creation with some basic gradients
This commit is contained in:
Tim van der Meij 2025-12-23 15:44:54 +01:00 committed by GitHub
commit dd6459c3d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -71,23 +71,51 @@ class RadialAxialShadingPattern extends BaseShadingPattern {
this.matrix = null;
}
_createGradient(ctx) {
isOriginBased() {
return (
this._p0[0] === 0 &&
this._p0[1] === 0 &&
(!this.isRadial() || (this._p1[0] === 0 && this._p1[1] === 0))
);
}
isRadial() {
return this._type === "radial";
}
_createGradient(ctx, transform = null) {
let grad;
let firstPoint = this._p0;
let secondPoint = this._p1;
if (transform) {
firstPoint = firstPoint.slice();
secondPoint = secondPoint.slice();
Util.applyTransform(firstPoint, transform);
Util.applyTransform(secondPoint, transform);
}
if (this._type === "axial") {
grad = ctx.createLinearGradient(
this._p0[0],
this._p0[1],
this._p1[0],
this._p1[1]
firstPoint[0],
firstPoint[1],
secondPoint[0],
secondPoint[1]
);
} else if (this._type === "radial") {
let r0 = this._r0;
let r1 = this._r1;
if (transform) {
const scale = new Float32Array(2);
Util.singularValueDecompose2dScale(transform, scale);
r0 *= scale[0];
r1 *= scale[0];
}
grad = ctx.createRadialGradient(
this._p0[0],
this._p0[1],
this._r0,
this._p1[0],
this._p1[1],
this._r1
firstPoint[0],
firstPoint[1],
r0,
secondPoint[0],
secondPoint[1],
r1
);
}
@ -100,6 +128,32 @@ class RadialAxialShadingPattern extends BaseShadingPattern {
getPattern(ctx, owner, inverse, pathType) {
let pattern;
if (pathType === PathType.STROKE || pathType === PathType.FILL) {
if (this.isOriginBased()) {
let transf = Util.transform(inverse, owner.baseTransform);
if (this.matrix) {
transf = Util.transform(transf, this.matrix);
}
const precision = 1e-3;
const n1 = Math.hypot(transf[0], transf[1]);
const n2 = Math.hypot(transf[2], transf[3]);
const ps = (transf[0] * transf[2] + transf[1] * transf[3]) / (n1 * n2);
if (Math.abs(ps) < precision) {
// The images of the basis vectors are orthogonal.
if (this.isRadial()) {
// If the images of the basis vectors are a square then the
// circles are transformed to circles and we can use a gradient
// directly.
if (Math.abs(n1 - n2) < precision) {
return this._createGradient(ctx, transf);
}
} else {
// The rectangles are transformed to rectangles and we can use a
// gradient directly.
return this._createGradient(ctx, transf);
}
}
}
const ownerBBox = owner.current.getClippedPathBoundingBox(
pathType,
getCurrentTransform(ctx)