Merge pull request #15281 from Snuffleupagus/getTransform
Remove `mozCurrentTransform`/`mozCurrentTransformInverse` usage
This commit is contained in:
commit
d55903764e
@ -26,7 +26,12 @@ import {
|
|||||||
Util,
|
Util,
|
||||||
warn,
|
warn,
|
||||||
} from "../shared/util.js";
|
} from "../shared/util.js";
|
||||||
import { getRGB, PixelsPerInch } from "./display_utils.js";
|
import {
|
||||||
|
getCurrentTransform,
|
||||||
|
getCurrentTransformInverse,
|
||||||
|
getRGB,
|
||||||
|
PixelsPerInch,
|
||||||
|
} from "./display_utils.js";
|
||||||
import {
|
import {
|
||||||
getShadingPattern,
|
getShadingPattern,
|
||||||
PathType,
|
PathType,
|
||||||
@ -54,13 +59,6 @@ const MAX_SIZE_TO_COMPILE = 1000;
|
|||||||
|
|
||||||
const FULL_CHUNK_HEIGHT = 16;
|
const FULL_CHUNK_HEIGHT = 16;
|
||||||
|
|
||||||
// Because of https://bugs.chromium.org/p/chromium/issues/detail?id=1170396
|
|
||||||
// some curves aren't rendered correctly.
|
|
||||||
// Multiplying lineWidth by this factor should help to have "correct"
|
|
||||||
// rendering with no artifacts.
|
|
||||||
// Once the bug is fixed upstream, we can remove this constant and its use.
|
|
||||||
const LINEWIDTH_SCALE_FACTOR = 1.000001;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides certain methods on a 2d ctx so that when they are called they
|
* Overrides certain methods on a 2d ctx so that when they are called they
|
||||||
* will also call the same method on the destCtx. The methods that are
|
* will also call the same method on the destCtx. The methods that are
|
||||||
@ -191,177 +189,21 @@ function mirrorContextOperations(ctx, destCtx) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function addContextCurrentTransform(ctx) {
|
|
||||||
if (ctx._transformStack) {
|
|
||||||
// Reset the transform stack.
|
|
||||||
ctx._transformStack = [];
|
|
||||||
}
|
|
||||||
// If the context doesn't expose a `mozCurrentTransform`, add a JS based one.
|
|
||||||
if (ctx.mozCurrentTransform) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ctx._originalSave = ctx.save;
|
|
||||||
ctx._originalRestore = ctx.restore;
|
|
||||||
ctx._originalRotate = ctx.rotate;
|
|
||||||
ctx._originalScale = ctx.scale;
|
|
||||||
ctx._originalTranslate = ctx.translate;
|
|
||||||
ctx._originalTransform = ctx.transform;
|
|
||||||
ctx._originalSetTransform = ctx.setTransform;
|
|
||||||
ctx._originalResetTransform = ctx.resetTransform;
|
|
||||||
|
|
||||||
ctx._transformMatrix = ctx._transformMatrix || [1, 0, 0, 1, 0, 0];
|
|
||||||
ctx._transformStack = [];
|
|
||||||
|
|
||||||
try {
|
|
||||||
// The call to getOwnPropertyDescriptor throws an exception in Node.js:
|
|
||||||
// "TypeError: Method lineWidth called on incompatible receiver
|
|
||||||
// #<CanvasRenderingContext2D>".
|
|
||||||
const desc = Object.getOwnPropertyDescriptor(
|
|
||||||
Object.getPrototypeOf(ctx),
|
|
||||||
"lineWidth"
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx._setLineWidth = desc.set;
|
|
||||||
ctx._getLineWidth = desc.get;
|
|
||||||
|
|
||||||
Object.defineProperty(ctx, "lineWidth", {
|
|
||||||
set: function setLineWidth(width) {
|
|
||||||
this._setLineWidth(width * LINEWIDTH_SCALE_FACTOR);
|
|
||||||
},
|
|
||||||
get: function getLineWidth() {
|
|
||||||
return this._getLineWidth();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (_) {}
|
|
||||||
|
|
||||||
Object.defineProperty(ctx, "mozCurrentTransform", {
|
|
||||||
get: function getCurrentTransform() {
|
|
||||||
return this._transformMatrix;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.defineProperty(ctx, "mozCurrentTransformInverse", {
|
|
||||||
get: function getCurrentTransformInverse() {
|
|
||||||
// Calculation done using WolframAlpha:
|
|
||||||
// http://www.wolframalpha.com/input/?
|
|
||||||
// i=Inverse+{{a%2C+c%2C+e}%2C+{b%2C+d%2C+f}%2C+{0%2C+0%2C+1}}
|
|
||||||
|
|
||||||
const [a, b, c, d, e, f] = this._transformMatrix;
|
|
||||||
const ad_bc = a * d - b * c;
|
|
||||||
const bc_ad = b * c - a * d;
|
|
||||||
|
|
||||||
return [
|
|
||||||
d / ad_bc,
|
|
||||||
b / bc_ad,
|
|
||||||
c / bc_ad,
|
|
||||||
a / ad_bc,
|
|
||||||
(d * e - c * f) / bc_ad,
|
|
||||||
(b * e - a * f) / ad_bc,
|
|
||||||
];
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
ctx.save = function ctxSave() {
|
|
||||||
const old = this._transformMatrix;
|
|
||||||
this._transformStack.push(old);
|
|
||||||
this._transformMatrix = old.slice(0, 6);
|
|
||||||
|
|
||||||
this._originalSave();
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.restore = function ctxRestore() {
|
|
||||||
if (this._transformStack.length === 0) {
|
|
||||||
warn("Tried to restore a ctx when the stack was already empty.");
|
|
||||||
}
|
|
||||||
const prev = this._transformStack.pop();
|
|
||||||
if (prev) {
|
|
||||||
this._transformMatrix = prev;
|
|
||||||
this._originalRestore();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.translate = function ctxTranslate(x, y) {
|
|
||||||
const m = this._transformMatrix;
|
|
||||||
m[4] = m[0] * x + m[2] * y + m[4];
|
|
||||||
m[5] = m[1] * x + m[3] * y + m[5];
|
|
||||||
|
|
||||||
this._originalTranslate(x, y);
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.scale = function ctxScale(x, y) {
|
|
||||||
const m = this._transformMatrix;
|
|
||||||
m[0] *= x;
|
|
||||||
m[1] *= x;
|
|
||||||
m[2] *= y;
|
|
||||||
m[3] *= y;
|
|
||||||
|
|
||||||
this._originalScale(x, y);
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.transform = function ctxTransform(a, b, c, d, e, f) {
|
|
||||||
const m = this._transformMatrix;
|
|
||||||
this._transformMatrix = [
|
|
||||||
m[0] * a + m[2] * b,
|
|
||||||
m[1] * a + m[3] * b,
|
|
||||||
m[0] * c + m[2] * d,
|
|
||||||
m[1] * c + m[3] * d,
|
|
||||||
m[0] * e + m[2] * f + m[4],
|
|
||||||
m[1] * e + m[3] * f + m[5],
|
|
||||||
];
|
|
||||||
|
|
||||||
ctx._originalTransform(a, b, c, d, e, f);
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) {
|
|
||||||
this._transformMatrix = [a, b, c, d, e, f];
|
|
||||||
|
|
||||||
ctx._originalSetTransform(a, b, c, d, e, f);
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.resetTransform = function ctxResetTransform() {
|
|
||||||
this._transformMatrix = [1, 0, 0, 1, 0, 0];
|
|
||||||
|
|
||||||
ctx._originalResetTransform();
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.rotate = function ctxRotate(angle) {
|
|
||||||
const cosValue = Math.cos(angle);
|
|
||||||
const sinValue = Math.sin(angle);
|
|
||||||
|
|
||||||
const m = this._transformMatrix;
|
|
||||||
this._transformMatrix = [
|
|
||||||
m[0] * cosValue + m[2] * sinValue,
|
|
||||||
m[1] * cosValue + m[3] * sinValue,
|
|
||||||
m[0] * -sinValue + m[2] * cosValue,
|
|
||||||
m[1] * -sinValue + m[3] * cosValue,
|
|
||||||
m[4],
|
|
||||||
m[5],
|
|
||||||
];
|
|
||||||
|
|
||||||
this._originalRotate(angle);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class CachedCanvases {
|
class CachedCanvases {
|
||||||
constructor(canvasFactory) {
|
constructor(canvasFactory) {
|
||||||
this.canvasFactory = canvasFactory;
|
this.canvasFactory = canvasFactory;
|
||||||
this.cache = Object.create(null);
|
this.cache = Object.create(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCanvas(id, width, height, trackTransform) {
|
getCanvas(id, width, height) {
|
||||||
let canvasEntry;
|
let canvasEntry;
|
||||||
if (this.cache[id] !== undefined) {
|
if (this.cache[id] !== undefined) {
|
||||||
canvasEntry = this.cache[id];
|
canvasEntry = this.cache[id];
|
||||||
this.canvasFactory.reset(canvasEntry, width, height);
|
this.canvasFactory.reset(canvasEntry, width, height);
|
||||||
// reset canvas transform for emulated mozCurrentTransform, if needed
|
|
||||||
canvasEntry.context.setTransform(1, 0, 0, 1, 0, 0);
|
|
||||||
} else {
|
} else {
|
||||||
canvasEntry = this.canvasFactory.create(width, height);
|
canvasEntry = this.canvasFactory.create(width, height);
|
||||||
this.cache[id] = canvasEntry;
|
this.cache[id] = canvasEntry;
|
||||||
}
|
}
|
||||||
if (trackTransform) {
|
|
||||||
addContextCurrentTransform(canvasEntry.context);
|
|
||||||
}
|
|
||||||
return canvasEntry;
|
return canvasEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,7 +232,7 @@ function drawImageAtIntegerCoords(
|
|||||||
destW,
|
destW,
|
||||||
destH
|
destH
|
||||||
) {
|
) {
|
||||||
const [a, b, c, d, tx, ty] = ctx.mozCurrentTransform;
|
const [a, b, c, d, tx, ty] = getCurrentTransform(ctx);
|
||||||
if (b === 0 && c === 0) {
|
if (b === 0 && c === 0) {
|
||||||
// top-left corner is at (X, Y) and
|
// top-left corner is at (X, Y) and
|
||||||
// bottom-right one is at (X + width, Y + height).
|
// bottom-right one is at (X + width, Y + height).
|
||||||
@ -1250,11 +1092,7 @@ class CanvasGraphics {
|
|||||||
this.outputScaleY = 1;
|
this.outputScaleY = 1;
|
||||||
this.backgroundColor = pageColors?.background || null;
|
this.backgroundColor = pageColors?.background || null;
|
||||||
this.foregroundColor = pageColors?.foreground || null;
|
this.foregroundColor = pageColors?.foreground || null;
|
||||||
if (canvasCtx) {
|
|
||||||
// NOTE: if mozCurrentTransform is polyfilled, then the current state of
|
|
||||||
// the transformation must already be set in canvasCtx._transformMatrix.
|
|
||||||
addContextCurrentTransform(canvasCtx);
|
|
||||||
}
|
|
||||||
this._cachedScaleForStroking = null;
|
this._cachedScaleForStroking = null;
|
||||||
this._cachedGetSinglePixelWidth = null;
|
this._cachedGetSinglePixelWidth = null;
|
||||||
this._cachedBitmapsMap = new Map();
|
this._cachedBitmapsMap = new Map();
|
||||||
@ -1350,8 +1188,7 @@ class CanvasGraphics {
|
|||||||
const transparentCanvas = this.cachedCanvases.getCanvas(
|
const transparentCanvas = this.cachedCanvases.getCanvas(
|
||||||
"transparent",
|
"transparent",
|
||||||
width,
|
width,
|
||||||
height,
|
height
|
||||||
/* trackTransform */ true
|
|
||||||
);
|
);
|
||||||
this.compositeCtx = this.ctx;
|
this.compositeCtx = this.ctx;
|
||||||
this.transparentCanvas = transparentCanvas.canvas;
|
this.transparentCanvas = transparentCanvas.canvas;
|
||||||
@ -1359,7 +1196,7 @@ class CanvasGraphics {
|
|||||||
this.ctx.save();
|
this.ctx.save();
|
||||||
// The transform can be applied before rendering, transferring it to
|
// The transform can be applied before rendering, transferring it to
|
||||||
// the new canvas.
|
// the new canvas.
|
||||||
this.ctx.transform(...this.compositeCtx.mozCurrentTransform);
|
this.ctx.transform(...getCurrentTransform(this.compositeCtx));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ctx.save();
|
this.ctx.save();
|
||||||
@ -1372,7 +1209,7 @@ class CanvasGraphics {
|
|||||||
this.ctx.transform(...viewport.transform);
|
this.ctx.transform(...viewport.transform);
|
||||||
this.viewportScale = viewport.scale;
|
this.viewportScale = viewport.scale;
|
||||||
|
|
||||||
this.baseTransform = this.ctx.mozCurrentTransform.slice();
|
this.baseTransform = getCurrentTransform(this.ctx);
|
||||||
|
|
||||||
if (this.imageLayer) {
|
if (this.imageLayer) {
|
||||||
this.imageLayer.beginLayout();
|
this.imageLayer.beginLayout();
|
||||||
@ -1529,8 +1366,7 @@ class CanvasGraphics {
|
|||||||
tmpCanvas = this.cachedCanvases.getCanvas(
|
tmpCanvas = this.cachedCanvases.getCanvas(
|
||||||
tmpCanvasId,
|
tmpCanvasId,
|
||||||
newWidth,
|
newWidth,
|
||||||
newHeight,
|
newHeight
|
||||||
/* trackTransform */ false
|
|
||||||
);
|
);
|
||||||
tmpCtx = tmpCanvas.context;
|
tmpCtx = tmpCanvas.context;
|
||||||
tmpCtx.clearRect(0, 0, newWidth, newHeight);
|
tmpCtx.clearRect(0, 0, newWidth, newHeight);
|
||||||
@ -1562,7 +1398,7 @@ class CanvasGraphics {
|
|||||||
const { width, height } = img;
|
const { width, height } = img;
|
||||||
const fillColor = this.current.fillColor;
|
const fillColor = this.current.fillColor;
|
||||||
const isPatternFill = this.current.patternFill;
|
const isPatternFill = this.current.patternFill;
|
||||||
const currentTransform = ctx.mozCurrentTransform;
|
const currentTransform = getCurrentTransform(ctx);
|
||||||
|
|
||||||
let cache, cacheKey, scaled, maskCanvas;
|
let cache, cacheKey, scaled, maskCanvas;
|
||||||
if ((img.bitmap || img.data) && img.count > 1) {
|
if ((img.bitmap || img.data) && img.count > 1) {
|
||||||
@ -1603,12 +1439,7 @@ class CanvasGraphics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!scaled) {
|
if (!scaled) {
|
||||||
maskCanvas = this.cachedCanvases.getCanvas(
|
maskCanvas = this.cachedCanvases.getCanvas("maskCanvas", width, height);
|
||||||
"maskCanvas",
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
/* trackTransform */ false
|
|
||||||
);
|
|
||||||
putBinaryImageMask(maskCanvas.context, img);
|
putBinaryImageMask(maskCanvas.context, img);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1634,8 +1465,7 @@ class CanvasGraphics {
|
|||||||
const fillCanvas = this.cachedCanvases.getCanvas(
|
const fillCanvas = this.cachedCanvases.getCanvas(
|
||||||
"fillCanvas",
|
"fillCanvas",
|
||||||
drawnWidth,
|
drawnWidth,
|
||||||
drawnHeight,
|
drawnHeight
|
||||||
/* trackTransform */ true
|
|
||||||
);
|
);
|
||||||
const fillCtx = fillCanvas.context;
|
const fillCtx = fillCanvas.context;
|
||||||
|
|
||||||
@ -1652,7 +1482,7 @@ class CanvasGraphics {
|
|||||||
// Pre-scale if needed to improve image smoothing.
|
// Pre-scale if needed to improve image smoothing.
|
||||||
scaled = this._scaleImage(
|
scaled = this._scaleImage(
|
||||||
maskCanvas.canvas,
|
maskCanvas.canvas,
|
||||||
fillCtx.mozCurrentTransformInverse
|
getCurrentTransformInverse(fillCtx)
|
||||||
);
|
);
|
||||||
scaled = scaled.img;
|
scaled = scaled.img;
|
||||||
if (cache && isPatternFill) {
|
if (cache && isPatternFill) {
|
||||||
@ -1661,7 +1491,7 @@ class CanvasGraphics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fillCtx.imageSmoothingEnabled = getImageSmoothingEnabled(
|
fillCtx.imageSmoothingEnabled = getImageSmoothingEnabled(
|
||||||
fillCtx.mozCurrentTransform,
|
getCurrentTransform(fillCtx),
|
||||||
img.interpolate
|
img.interpolate
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -1679,7 +1509,7 @@ class CanvasGraphics {
|
|||||||
);
|
);
|
||||||
fillCtx.globalCompositeOperation = "source-in";
|
fillCtx.globalCompositeOperation = "source-in";
|
||||||
|
|
||||||
const inverse = Util.transform(fillCtx.mozCurrentTransformInverse, [
|
const inverse = Util.transform(getCurrentTransformInverse(fillCtx), [
|
||||||
1,
|
1,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@ -1830,13 +1660,12 @@ class CanvasGraphics {
|
|||||||
const scratchCanvas = this.cachedCanvases.getCanvas(
|
const scratchCanvas = this.cachedCanvases.getCanvas(
|
||||||
cacheId,
|
cacheId,
|
||||||
drawnWidth,
|
drawnWidth,
|
||||||
drawnHeight,
|
drawnHeight
|
||||||
/* trackTransform */ true
|
|
||||||
);
|
);
|
||||||
this.suspendedCtx = this.ctx;
|
this.suspendedCtx = this.ctx;
|
||||||
this.ctx = scratchCanvas.context;
|
this.ctx = scratchCanvas.context;
|
||||||
const ctx = this.ctx;
|
const ctx = this.ctx;
|
||||||
ctx.setTransform(...this.suspendedCtx.mozCurrentTransform);
|
ctx.setTransform(...getCurrentTransform(this.suspendedCtx));
|
||||||
copyCtxState(this.suspendedCtx, ctx);
|
copyCtxState(this.suspendedCtx, ctx);
|
||||||
mirrorContextOperations(ctx, this.suspendedCtx);
|
mirrorContextOperations(ctx, this.suspendedCtx);
|
||||||
|
|
||||||
@ -1940,7 +1769,7 @@ class CanvasGraphics {
|
|||||||
let x = current.x,
|
let x = current.x,
|
||||||
y = current.y;
|
y = current.y;
|
||||||
let startX, startY;
|
let startX, startY;
|
||||||
const currentTransform = ctx.mozCurrentTransform;
|
const currentTransform = getCurrentTransform(ctx);
|
||||||
|
|
||||||
// Most of the time the current transform is a scaling matrix
|
// Most of the time the current transform is a scaling matrix
|
||||||
// so we don't need to transform points before computing min/max:
|
// so we don't need to transform points before computing min/max:
|
||||||
@ -2096,7 +1925,7 @@ class CanvasGraphics {
|
|||||||
ctx.strokeStyle = strokeColor.getPattern(
|
ctx.strokeStyle = strokeColor.getPattern(
|
||||||
ctx,
|
ctx,
|
||||||
this,
|
this,
|
||||||
ctx.mozCurrentTransformInverse,
|
getCurrentTransformInverse(ctx),
|
||||||
PathType.STROKE
|
PathType.STROKE
|
||||||
);
|
);
|
||||||
this.rescaleAndStroke(/* saveRestore */ false);
|
this.rescaleAndStroke(/* saveRestore */ false);
|
||||||
@ -2129,7 +1958,7 @@ class CanvasGraphics {
|
|||||||
ctx.fillStyle = fillColor.getPattern(
|
ctx.fillStyle = fillColor.getPattern(
|
||||||
ctx,
|
ctx,
|
||||||
this,
|
this,
|
||||||
ctx.mozCurrentTransformInverse,
|
getCurrentTransformInverse(ctx),
|
||||||
PathType.FILL
|
PathType.FILL
|
||||||
);
|
);
|
||||||
needRestore = true;
|
needRestore = true;
|
||||||
@ -2383,7 +2212,7 @@ class CanvasGraphics {
|
|||||||
if (isAddToPathSet) {
|
if (isAddToPathSet) {
|
||||||
const paths = this.pendingTextPaths || (this.pendingTextPaths = []);
|
const paths = this.pendingTextPaths || (this.pendingTextPaths = []);
|
||||||
paths.push({
|
paths.push({
|
||||||
transform: ctx.mozCurrentTransform,
|
transform: getCurrentTransform(ctx),
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
fontSize,
|
fontSize,
|
||||||
@ -2398,8 +2227,7 @@ class CanvasGraphics {
|
|||||||
const { context: ctx } = this.cachedCanvases.getCanvas(
|
const { context: ctx } = this.cachedCanvases.getCanvas(
|
||||||
"isFontSubpixelAAEnabled",
|
"isFontSubpixelAAEnabled",
|
||||||
10,
|
10,
|
||||||
10,
|
10
|
||||||
/* trackTransform */ false
|
|
||||||
);
|
);
|
||||||
ctx.scale(1.5, 1);
|
ctx.scale(1.5, 1);
|
||||||
ctx.fillText("I", 0, 10);
|
ctx.fillText("I", 0, 10);
|
||||||
@ -2459,10 +2287,10 @@ class CanvasGraphics {
|
|||||||
const pattern = current.fillColor.getPattern(
|
const pattern = current.fillColor.getPattern(
|
||||||
ctx,
|
ctx,
|
||||||
this,
|
this,
|
||||||
ctx.mozCurrentTransformInverse,
|
getCurrentTransformInverse(ctx),
|
||||||
PathType.FILL
|
PathType.FILL
|
||||||
);
|
);
|
||||||
patternTransform = ctx.mozCurrentTransform;
|
patternTransform = getCurrentTransform(ctx);
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
ctx.fillStyle = pattern;
|
ctx.fillStyle = pattern;
|
||||||
}
|
}
|
||||||
@ -2663,8 +2491,7 @@ class CanvasGraphics {
|
|||||||
let pattern;
|
let pattern;
|
||||||
if (IR[0] === "TilingPattern") {
|
if (IR[0] === "TilingPattern") {
|
||||||
const color = IR[1];
|
const color = IR[1];
|
||||||
const baseTransform =
|
const baseTransform = this.baseTransform || getCurrentTransform(this.ctx);
|
||||||
this.baseTransform || this.ctx.mozCurrentTransform.slice();
|
|
||||||
const canvasGraphicsFactory = {
|
const canvasGraphicsFactory = {
|
||||||
createCanvasGraphics: ctx => {
|
createCanvasGraphics: ctx => {
|
||||||
return new CanvasGraphics(
|
return new CanvasGraphics(
|
||||||
@ -2735,11 +2562,11 @@ class CanvasGraphics {
|
|||||||
ctx.fillStyle = pattern.getPattern(
|
ctx.fillStyle = pattern.getPattern(
|
||||||
ctx,
|
ctx,
|
||||||
this,
|
this,
|
||||||
ctx.mozCurrentTransformInverse,
|
getCurrentTransformInverse(ctx),
|
||||||
PathType.SHADING
|
PathType.SHADING
|
||||||
);
|
);
|
||||||
|
|
||||||
const inv = ctx.mozCurrentTransformInverse;
|
const inv = getCurrentTransformInverse(ctx);
|
||||||
if (inv) {
|
if (inv) {
|
||||||
const canvas = ctx.canvas;
|
const canvas = ctx.canvas;
|
||||||
const width = canvas.width;
|
const width = canvas.width;
|
||||||
@ -2790,13 +2617,13 @@ class CanvasGraphics {
|
|||||||
this.transform(...matrix);
|
this.transform(...matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.baseTransform = this.ctx.mozCurrentTransform;
|
this.baseTransform = getCurrentTransform(this.ctx);
|
||||||
|
|
||||||
if (bbox) {
|
if (bbox) {
|
||||||
const width = bbox[2] - bbox[0];
|
const width = bbox[2] - bbox[0];
|
||||||
const height = bbox[3] - bbox[1];
|
const height = bbox[3] - bbox[1];
|
||||||
this.ctx.rect(bbox[0], bbox[1], width, height);
|
this.ctx.rect(bbox[0], bbox[1], width, height);
|
||||||
this.current.updateRectMinMax(this.ctx.mozCurrentTransform, bbox);
|
this.current.updateRectMinMax(getCurrentTransform(this.ctx), bbox);
|
||||||
this.clip();
|
this.clip();
|
||||||
this.endPath();
|
this.endPath();
|
||||||
}
|
}
|
||||||
@ -2847,7 +2674,7 @@ class CanvasGraphics {
|
|||||||
warn("Knockout groups not supported.");
|
warn("Knockout groups not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentTransform = currentCtx.mozCurrentTransform;
|
const currentTransform = getCurrentTransform(currentCtx);
|
||||||
if (group.matrix) {
|
if (group.matrix) {
|
||||||
currentCtx.transform(...group.matrix);
|
currentCtx.transform(...group.matrix);
|
||||||
}
|
}
|
||||||
@ -2859,7 +2686,7 @@ class CanvasGraphics {
|
|||||||
// will actually be.
|
// will actually be.
|
||||||
let bounds = Util.getAxialAlignedBoundingBox(
|
let bounds = Util.getAxialAlignedBoundingBox(
|
||||||
group.bbox,
|
group.bbox,
|
||||||
currentCtx.mozCurrentTransform
|
getCurrentTransform(currentCtx)
|
||||||
);
|
);
|
||||||
// Clip the bounding box to the current canvas.
|
// Clip the bounding box to the current canvas.
|
||||||
const canvasBounds = [
|
const canvasBounds = [
|
||||||
@ -2896,8 +2723,7 @@ class CanvasGraphics {
|
|||||||
const scratchCanvas = this.cachedCanvases.getCanvas(
|
const scratchCanvas = this.cachedCanvases.getCanvas(
|
||||||
cacheId,
|
cacheId,
|
||||||
drawnWidth,
|
drawnWidth,
|
||||||
drawnHeight,
|
drawnHeight
|
||||||
/* trackTransform */ true
|
|
||||||
);
|
);
|
||||||
const groupCtx = scratchCanvas.context;
|
const groupCtx = scratchCanvas.context;
|
||||||
|
|
||||||
@ -2959,7 +2785,7 @@ class CanvasGraphics {
|
|||||||
this.restore();
|
this.restore();
|
||||||
} else {
|
} else {
|
||||||
this.ctx.restore();
|
this.ctx.restore();
|
||||||
const currentMtx = this.ctx.mozCurrentTransform;
|
const currentMtx = getCurrentTransform(this.ctx);
|
||||||
this.restore();
|
this.restore();
|
||||||
this.ctx.save();
|
this.ctx.save();
|
||||||
this.ctx.setTransform(...currentMtx);
|
this.ctx.setTransform(...currentMtx);
|
||||||
@ -3003,7 +2829,7 @@ class CanvasGraphics {
|
|||||||
rect[3] = height;
|
rect[3] = height;
|
||||||
|
|
||||||
const [scaleX, scaleY] = Util.singularValueDecompose2dScale(
|
const [scaleX, scaleY] = Util.singularValueDecompose2dScale(
|
||||||
this.ctx.mozCurrentTransform
|
getCurrentTransform(this.ctx)
|
||||||
);
|
);
|
||||||
const { viewportScale } = this;
|
const { viewportScale } = this;
|
||||||
const canvasWidth = Math.ceil(
|
const canvasWidth = Math.ceil(
|
||||||
@ -3021,7 +2847,6 @@ class CanvasGraphics {
|
|||||||
this.annotationCanvasMap.set(id, canvas);
|
this.annotationCanvasMap.set(id, canvas);
|
||||||
this.annotationCanvas.savedCtx = this.ctx;
|
this.annotationCanvas.savedCtx = this.ctx;
|
||||||
this.ctx = context;
|
this.ctx = context;
|
||||||
addContextCurrentTransform(this.ctx);
|
|
||||||
this.ctx.setTransform(scaleX, 0, 0, -scaleY, 0, height * scaleY);
|
this.ctx.setTransform(scaleX, 0, 0, -scaleY, 0, height * scaleY);
|
||||||
|
|
||||||
resetCtxToDefault(this.ctx, this.foregroundColor);
|
resetCtxToDefault(this.ctx, this.foregroundColor);
|
||||||
@ -3100,7 +2925,7 @@ class CanvasGraphics {
|
|||||||
|
|
||||||
const ctx = this.ctx;
|
const ctx = this.ctx;
|
||||||
ctx.save();
|
ctx.save();
|
||||||
const currentTransform = ctx.mozCurrentTransform;
|
const currentTransform = getCurrentTransform(ctx);
|
||||||
ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0);
|
ctx.transform(scaleX, skewX, skewY, scaleY, 0, 0);
|
||||||
const mask = this._createMaskCanvas(img);
|
const mask = this._createMaskCanvas(img);
|
||||||
|
|
||||||
@ -3137,8 +2962,7 @@ class CanvasGraphics {
|
|||||||
const maskCanvas = this.cachedCanvases.getCanvas(
|
const maskCanvas = this.cachedCanvases.getCanvas(
|
||||||
"maskCanvas",
|
"maskCanvas",
|
||||||
width,
|
width,
|
||||||
height,
|
height
|
||||||
/* trackTransform */ false
|
|
||||||
);
|
);
|
||||||
const maskCtx = maskCanvas.context;
|
const maskCtx = maskCanvas.context;
|
||||||
maskCtx.save();
|
maskCtx.save();
|
||||||
@ -3152,7 +2976,7 @@ class CanvasGraphics {
|
|||||||
? fillColor.getPattern(
|
? fillColor.getPattern(
|
||||||
maskCtx,
|
maskCtx,
|
||||||
this,
|
this,
|
||||||
ctx.mozCurrentTransformInverse,
|
getCurrentTransformInverse(ctx),
|
||||||
PathType.FILL
|
PathType.FILL
|
||||||
)
|
)
|
||||||
: fillColor;
|
: fillColor;
|
||||||
@ -3241,17 +3065,19 @@ class CanvasGraphics {
|
|||||||
const tmpCanvas = this.cachedCanvases.getCanvas(
|
const tmpCanvas = this.cachedCanvases.getCanvas(
|
||||||
"inlineImage",
|
"inlineImage",
|
||||||
width,
|
width,
|
||||||
height,
|
height
|
||||||
/* trackTransform */ false
|
|
||||||
);
|
);
|
||||||
const tmpCtx = tmpCanvas.context;
|
const tmpCtx = tmpCanvas.context;
|
||||||
putBinaryImageData(tmpCtx, imgData, this.current.transferMaps);
|
putBinaryImageData(tmpCtx, imgData, this.current.transferMaps);
|
||||||
imgToPaint = tmpCanvas.canvas;
|
imgToPaint = tmpCanvas.canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
const scaled = this._scaleImage(imgToPaint, ctx.mozCurrentTransformInverse);
|
const scaled = this._scaleImage(
|
||||||
|
imgToPaint,
|
||||||
|
getCurrentTransformInverse(ctx)
|
||||||
|
);
|
||||||
ctx.imageSmoothingEnabled = getImageSmoothingEnabled(
|
ctx.imageSmoothingEnabled = getImageSmoothingEnabled(
|
||||||
ctx.mozCurrentTransform,
|
getCurrentTransform(ctx),
|
||||||
imgData.interpolate
|
imgData.interpolate
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -3290,12 +3116,7 @@ class CanvasGraphics {
|
|||||||
const w = imgData.width;
|
const w = imgData.width;
|
||||||
const h = imgData.height;
|
const h = imgData.height;
|
||||||
|
|
||||||
const tmpCanvas = this.cachedCanvases.getCanvas(
|
const tmpCanvas = this.cachedCanvases.getCanvas("inlineImage", w, h);
|
||||||
"inlineImage",
|
|
||||||
w,
|
|
||||||
h,
|
|
||||||
/* trackTransform */ false
|
|
||||||
);
|
|
||||||
const tmpCtx = tmpCanvas.context;
|
const tmpCtx = tmpCanvas.context;
|
||||||
putBinaryImageData(tmpCtx, imgData, this.current.transferMaps);
|
putBinaryImageData(tmpCtx, imgData, this.current.transferMaps);
|
||||||
|
|
||||||
@ -3409,7 +3230,7 @@ class CanvasGraphics {
|
|||||||
|
|
||||||
getSinglePixelWidth() {
|
getSinglePixelWidth() {
|
||||||
if (!this._cachedGetSinglePixelWidth) {
|
if (!this._cachedGetSinglePixelWidth) {
|
||||||
const m = this.ctx.mozCurrentTransform;
|
const m = getCurrentTransform(this.ctx);
|
||||||
if (m[1] === 0 && m[2] === 0) {
|
if (m[1] === 0 && m[2] === 0) {
|
||||||
// Fast path
|
// Fast path
|
||||||
this._cachedGetSinglePixelWidth =
|
this._cachedGetSinglePixelWidth =
|
||||||
@ -3433,7 +3254,7 @@ class CanvasGraphics {
|
|||||||
// to 1 after transform.
|
// to 1 after transform.
|
||||||
if (!this._cachedScaleForStroking) {
|
if (!this._cachedScaleForStroking) {
|
||||||
const { lineWidth } = this.current;
|
const { lineWidth } = this.current;
|
||||||
const m = this.ctx.mozCurrentTransform;
|
const m = getCurrentTransform(this.ctx);
|
||||||
let scaleX, scaleY;
|
let scaleX, scaleY;
|
||||||
|
|
||||||
if (m[1] === 0 && m[2] === 0) {
|
if (m[1] === 0 && m[2] === 0) {
|
||||||
@ -3489,7 +3310,7 @@ class CanvasGraphics {
|
|||||||
|
|
||||||
let savedMatrix, savedDashes, savedDashOffset;
|
let savedMatrix, savedDashes, savedDashOffset;
|
||||||
if (saveRestore) {
|
if (saveRestore) {
|
||||||
savedMatrix = ctx.mozCurrentTransform.slice();
|
savedMatrix = getCurrentTransform(ctx);
|
||||||
savedDashes = ctx.getLineDash().slice();
|
savedDashes = ctx.getLineDash().slice();
|
||||||
savedDashOffset = ctx.lineDashOffset;
|
savedDashOffset = ctx.lineDashOffset;
|
||||||
}
|
}
|
||||||
@ -3517,7 +3338,7 @@ class CanvasGraphics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCanvasPosition(x, y) {
|
getCanvasPosition(x, y) {
|
||||||
const transform = this.ctx.mozCurrentTransform;
|
const transform = getCurrentTransform(this.ctx);
|
||||||
return [
|
return [
|
||||||
transform[0] * x + transform[2] * y + transform[4],
|
transform[0] * x + transform[2] * y + transform[4],
|
||||||
transform[1] * x + transform[3] * y + transform[5],
|
transform[1] * x + transform[3] * y + transform[5],
|
||||||
|
@ -641,6 +641,16 @@ function binarySearchFirstItem(items, condition, start = 0) {
|
|||||||
return minIndex; /* === maxIndex */
|
return minIndex; /* === maxIndex */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCurrentTransform(ctx) {
|
||||||
|
const { a, b, c, d, e, f } = ctx.getTransform();
|
||||||
|
return [a, b, c, d, e, f];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentTransformInverse(ctx) {
|
||||||
|
const { a, b, c, d, e, f } = ctx.getTransform().invertSelf();
|
||||||
|
return [a, b, c, d, e, f];
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
binarySearchFirstItem,
|
binarySearchFirstItem,
|
||||||
deprecated,
|
deprecated,
|
||||||
@ -649,6 +659,8 @@ export {
|
|||||||
DOMStandardFontDataFactory,
|
DOMStandardFontDataFactory,
|
||||||
DOMSVGFactory,
|
DOMSVGFactory,
|
||||||
getColorValues,
|
getColorValues,
|
||||||
|
getCurrentTransform,
|
||||||
|
getCurrentTransformInverse,
|
||||||
getFilenameFromUrl,
|
getFilenameFromUrl,
|
||||||
getPdfFilenameFromUrl,
|
getPdfFilenameFromUrl,
|
||||||
getRGB,
|
getRGB,
|
||||||
|
@ -21,6 +21,7 @@ import {
|
|||||||
Util,
|
Util,
|
||||||
warn,
|
warn,
|
||||||
} from "../shared/util.js";
|
} from "../shared/util.js";
|
||||||
|
import { getCurrentTransform } from "./display_utils.js";
|
||||||
import { isNodeJS } from "../shared/is_node.js";
|
import { isNodeJS } from "../shared/is_node.js";
|
||||||
|
|
||||||
const PathType = {
|
const PathType = {
|
||||||
@ -96,7 +97,7 @@ class RadialAxialShadingPattern extends BaseShadingPattern {
|
|||||||
if (pathType === PathType.STROKE || pathType === PathType.FILL) {
|
if (pathType === PathType.STROKE || pathType === PathType.FILL) {
|
||||||
const ownerBBox = owner.current.getClippedPathBoundingBox(
|
const ownerBBox = owner.current.getClippedPathBoundingBox(
|
||||||
pathType,
|
pathType,
|
||||||
ctx.mozCurrentTransform
|
getCurrentTransform(ctx)
|
||||||
) || [0, 0, 0, 0];
|
) || [0, 0, 0, 0];
|
||||||
// Create a canvas that is only as big as the current path. This doesn't
|
// Create a canvas that is only as big as the current path. This doesn't
|
||||||
// allow us to cache the pattern, but it generally creates much smaller
|
// allow us to cache the pattern, but it generally creates much smaller
|
||||||
@ -409,7 +410,7 @@ class MeshShadingPattern extends BaseShadingPattern {
|
|||||||
applyBoundingBox(ctx, this._bbox);
|
applyBoundingBox(ctx, this._bbox);
|
||||||
let scale;
|
let scale;
|
||||||
if (pathType === PathType.SHADING) {
|
if (pathType === PathType.SHADING) {
|
||||||
scale = Util.singularValueDecompose2dScale(ctx.mozCurrentTransform);
|
scale = Util.singularValueDecompose2dScale(getCurrentTransform(ctx));
|
||||||
} else {
|
} else {
|
||||||
// Obtain scale from matrix and current transformation matrix.
|
// Obtain scale from matrix and current transformation matrix.
|
||||||
scale = Util.singularValueDecompose2dScale(owner.baseTransform);
|
scale = Util.singularValueDecompose2dScale(owner.baseTransform);
|
||||||
@ -584,7 +585,7 @@ class TilingPattern {
|
|||||||
|
|
||||||
this.clipBbox(graphics, adjustedX0, adjustedY0, adjustedX1, adjustedY1);
|
this.clipBbox(graphics, adjustedX0, adjustedY0, adjustedX1, adjustedY1);
|
||||||
|
|
||||||
graphics.baseTransform = graphics.ctx.mozCurrentTransform.slice();
|
graphics.baseTransform = getCurrentTransform(graphics.ctx);
|
||||||
|
|
||||||
graphics.executeOperatorList(operatorList);
|
graphics.executeOperatorList(operatorList);
|
||||||
|
|
||||||
@ -620,7 +621,7 @@ class TilingPattern {
|
|||||||
const bboxWidth = x1 - x0;
|
const bboxWidth = x1 - x0;
|
||||||
const bboxHeight = y1 - y0;
|
const bboxHeight = y1 - y0;
|
||||||
graphics.ctx.rect(x0, y0, bboxWidth, bboxHeight);
|
graphics.ctx.rect(x0, y0, bboxWidth, bboxHeight);
|
||||||
graphics.current.updateRectMinMax(graphics.ctx.mozCurrentTransform, [
|
graphics.current.updateRectMinMax(getCurrentTransform(graphics.ctx), [
|
||||||
x0,
|
x0,
|
||||||
y0,
|
y0,
|
||||||
x1,
|
x1,
|
||||||
|
Loading…
Reference in New Issue
Block a user