From fa643bb22fff6bb489602da461221e0cc04cc2c3 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 1 Apr 2025 23:03:36 +0200 Subject: [PATCH 1/3] Change `Util.applyTransform` to use the point-argument as an in/out parameter This will help reduce the total number of Array allocations, which cannot hurt, and also allows us to remove the `Util.applyTransformInPlace` method. --- src/core/annotation.js | 6 ++++-- src/core/operator_list.js | 2 +- src/display/canvas.js | 22 ++++++++++++++-------- src/display/display_utils.js | 10 +++++++--- src/shared/util.js | 18 ++++++++---------- 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/core/annotation.js b/src/core/annotation.js index 14bbc392a..55762a939 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -1320,8 +1320,10 @@ class Annotation { const transform = getTransformMatrix(rect, bbox, matrix); transform[4] -= rect[0]; transform[5] -= rect[1]; - coords = Util.applyTransform(coords, transform); - return Util.applyTransform(coords, matrix); + const p = coords.slice(); + Util.applyTransform(p, transform); + Util.applyTransform(p, matrix); + return p; } /** diff --git a/src/core/operator_list.js b/src/core/operator_list.js index a061d5f45..b3e52c299 100644 --- a/src/core/operator_list.js +++ b/src/core/operator_list.js @@ -524,7 +524,7 @@ addState( switch (buffer[k++]) { case DrawOPS.moveTo: case DrawOPS.lineTo: - Util.applyTransformInPlace(buffer.subarray(k), transform); + Util.applyTransform(buffer.subarray(k), transform); k += 2; break; case DrawOPS.curveTo: diff --git a/src/display/canvas.js b/src/display/canvas.js index 70b632b31..13e5d66ad 100644 --- a/src/display/canvas.js +++ b/src/display/canvas.js @@ -340,10 +340,14 @@ class CanvasExtraState { } updateRectMinMax(transform, rect) { - const p1 = Util.applyTransform(rect, transform); - const p2 = Util.applyTransform(rect.slice(2), transform); - const p3 = Util.applyTransform([rect[0], rect[3]], transform); - const p4 = Util.applyTransform([rect[2], rect[1]], transform); + const p1 = [rect[0], rect[1]]; + Util.applyTransform(p1, transform); + const p2 = [rect[2], rect[3]]; + Util.applyTransform(p2, transform); + const p3 = [rect[0], rect[3]]; + Util.applyTransform(p3, transform); + const p4 = [rect[2], rect[1]]; + Util.applyTransform(p4, transform); this.minX = Math.min(this.minX, p1[0], p2[0], p3[0], p4[0]); this.minY = Math.min(this.minY, p1[1], p2[1], p3[1], p4[1]); @@ -2111,8 +2115,9 @@ class CanvasGraphics { this.restore(); } - const transformed = Util.applyTransform([glyph.width, 0], fontMatrix); - width = transformed[0] * fontSize + spacing; + const p = [glyph.width, 0]; + Util.applyTransform(p, fontMatrix); + width = p[0] * fontSize + spacing; ctx.translate(width, 0); current.x += width * textHScale; @@ -2588,8 +2593,9 @@ class CanvasGraphics { positions[i + 1], ]); - const [x, y] = Util.applyTransform([0, 0], trans); - ctx.drawImage(mask.canvas, x, y); + // Here we want to apply the transform at the origin, + // hence no additional computation is necessary. + ctx.drawImage(mask.canvas, trans[4], trans[5]); } ctx.restore(); this.compose(); diff --git a/src/display/display_utils.js b/src/display/display_utils.js index 83ebbd87f..fb1beb4d6 100644 --- a/src/display/display_utils.js +++ b/src/display/display_utils.js @@ -257,7 +257,9 @@ class PageViewport { * @see {@link convertToViewportRectangle} */ convertToViewportPoint(x, y) { - return Util.applyTransform([x, y], this.transform); + const p = [x, y]; + Util.applyTransform(p, this.transform); + return p; } /** @@ -268,8 +270,10 @@ class PageViewport { * @see {@link convertToViewportPoint} */ convertToViewportRectangle(rect) { - const topLeft = Util.applyTransform([rect[0], rect[1]], this.transform); - const bottomRight = Util.applyTransform([rect[2], rect[3]], this.transform); + const topLeft = [rect[0], rect[1]]; + Util.applyTransform(topLeft, this.transform); + const bottomRight = [rect[2], rect[3]]; + Util.applyTransform(bottomRight, this.transform); return [topLeft[0], topLeft[1], bottomRight[0], bottomRight[1]]; } diff --git a/src/shared/util.js b/src/shared/util.js index ad74675fd..267816a8b 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -742,12 +742,6 @@ class Util { // For 2d affine transforms static applyTransform(p, m) { - const xt = p[0] * m[0] + p[1] * m[2] + m[4]; - const yt = p[0] * m[1] + p[1] * m[3] + m[5]; - return [xt, yt]; - } - - static applyTransformInPlace(p, m) { const [p0, p1] = p; p[0] = p0 * m[0] + p1 * m[2] + m[4]; p[1] = p0 * m[1] + p1 * m[3] + m[5]; @@ -773,10 +767,14 @@ class Util { // Applies the transform to the rectangle and finds the minimum axially // aligned bounding box. static getAxialAlignedBoundingBox(r, m) { - const p1 = this.applyTransform(r, m); - const p2 = this.applyTransform(r.slice(2, 4), m); - const p3 = this.applyTransform([r[0], r[3]], m); - const p4 = this.applyTransform([r[2], r[1]], m); + const p1 = [r[0], r[1]]; + Util.applyTransform(p1, m); + const p2 = [r[2], r[3]]; + Util.applyTransform(p2, m); + const p3 = [r[0], r[3]]; + Util.applyTransform(p3, m); + const p4 = [r[2], r[1]]; + Util.applyTransform(p4, m); return [ Math.min(p1[0], p2[0], p3[0], p4[0]), Math.min(p1[1], p2[1], p3[1], p4[1]), From c852e877d8c5ac2bcff6d5b900cc2d0458643321 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 1 Apr 2025 23:03:44 +0200 Subject: [PATCH 2/3] Change `Util.applyInverseTransform` to use the point-argument as an in/out parameter This will help reduce the total number of Array allocations, which cannot hurt. --- src/display/display_utils.js | 4 +++- src/shared/util.js | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/display/display_utils.js b/src/display/display_utils.js index fb1beb4d6..c554f0661 100644 --- a/src/display/display_utils.js +++ b/src/display/display_utils.js @@ -287,7 +287,9 @@ class PageViewport { * @see {@link convertToViewportPoint} */ convertToPdfPoint(x, y) { - return Util.applyInverseTransform([x, y], this.transform); + const p = [x, y]; + Util.applyInverseTransform(p, this.transform); + return p; } } diff --git a/src/shared/util.js b/src/shared/util.js index 267816a8b..56a4feda7 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -758,10 +758,10 @@ class Util { } static applyInverseTransform(p, m) { + const [p0, p1] = p; const d = m[0] * m[3] - m[1] * m[2]; - const xt = (p[0] * m[3] - p[1] * m[2] + m[2] * m[5] - m[4] * m[3]) / d; - const yt = (-p[0] * m[1] + p[1] * m[0] + m[4] * m[1] - m[5] * m[0]) / d; - return [xt, yt]; + p[0] = (p0 * m[3] - p1 * m[2] + m[2] * m[5] - m[4] * m[3]) / d; + p[1] = (-p0 * m[1] + p1 * m[0] + m[4] * m[1] - m[5] * m[0]) / d; } // Applies the transform to the rectangle and finds the minimum axially From 4262603b0683aff5174c0ccd9ab8035d6c1f6d00 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 1 Apr 2025 23:03:50 +0200 Subject: [PATCH 3/3] Re-name the `Util.applyTransformToBezierInPlace` method Given that all `Util.apply...` methods are now using in/out parameters, we can slightly shorten the name of this one. --- src/core/operator_list.js | 2 +- src/shared/util.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/operator_list.js b/src/core/operator_list.js index b3e52c299..661c6f4fe 100644 --- a/src/core/operator_list.js +++ b/src/core/operator_list.js @@ -528,7 +528,7 @@ addState( k += 2; break; case DrawOPS.curveTo: - Util.applyTransformToBezierInPlace(buffer.subarray(k), transform); + Util.applyTransformToBezier(buffer.subarray(k), transform); k += 6; break; } diff --git a/src/shared/util.js b/src/shared/util.js index 56a4feda7..3e3c66409 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -748,7 +748,7 @@ class Util { } // For 2d affine transforms - static applyTransformToBezierInPlace(p, [m0, m1, m2, m3, m4, m5]) { + static applyTransformToBezier(p, [m0, m1, m2, m3, m4, m5]) { for (let i = 0; i < 6; i += 2) { const pI = p[i]; const pI1 = p[i + 1];