From 31098c404d1bd3a934359a1a755e20e4e1db57ed Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Wed, 10 Feb 2021 12:28:49 +0100 Subject: [PATCH] Use `Math.hypot`, instead of `Math.sqrt` with manual squaring (#12973) When the PDF.js project started `Math.hypot` didn't exist yet, and until recently we still supported browsers (IE 11) without a native `Math.hypot` implementation; please see this compatibility information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot#browser_compatibility Furthermore, somewhat recently there were performance improvements of `Math.hypot` in Firefox; see https://bugzilla.mozilla.org/show_bug.cgi?id=1648820 Finally, this patch also replaces a couple of multiplications with the exponentiation operator. --- src/core/colorspace.js | 2 +- src/core/evaluator.js | 15 +++++++-------- src/core/pattern.js | 9 ++------- src/display/canvas.js | 16 +++++++++------- src/display/svg.js | 2 +- src/display/text_layer.js | 2 +- src/shared/util.js | 2 +- web/ui_utils.js | 2 +- 8 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/core/colorspace.js b/src/core/colorspace.js index 219584ddd..5f3fe01b0 100644 --- a/src/core/colorspace.js +++ b/src/core/colorspace.js @@ -1364,7 +1364,7 @@ const LabCS = (function LabCSClosure() { function fn_g(x) { let result; if (x >= 6 / 29) { - result = x * x * x; + result = x ** 3; } else { result = (108 / 841) * (x - 4 / 29); } diff --git a/src/core/evaluator.js b/src/core/evaluator.js index cbc2e94d5..c18ccab19 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -2077,20 +2077,19 @@ class PartialEvaluator { textContentItem.transform = trm; if (!font.vertical) { textContentItem.width = 0; - textContentItem.height = Math.sqrt(trm[2] * trm[2] + trm[3] * trm[3]); + textContentItem.height = Math.hypot(trm[2], trm[3]); textContentItem.vertical = false; } else { - textContentItem.width = Math.sqrt(trm[0] * trm[0] + trm[1] * trm[1]); + textContentItem.width = Math.hypot(trm[0], trm[1]); textContentItem.height = 0; textContentItem.vertical = true; } - var a = textState.textLineMatrix[0]; - var b = textState.textLineMatrix[1]; - var scaleLineX = Math.sqrt(a * a + b * b); - a = textState.ctm[0]; - b = textState.ctm[1]; - var scaleCtmX = Math.sqrt(a * a + b * b); + const scaleLineX = Math.hypot( + textState.textLineMatrix[0], + textState.textLineMatrix[1] + ); + const scaleCtmX = Math.hypot(textState.ctm[0], textState.ctm[1]); textContentItem.textAdvanceScale = scaleCtmX * scaleLineX; textContentItem.lastAdvanceWidth = 0; textContentItem.lastAdvanceHeight = 0; diff --git a/src/core/pattern.js b/src/core/pattern.js index 9e1a6fb75..9c83b5ad1 100644 --- a/src/core/pattern.js +++ b/src/core/pattern.js @@ -164,13 +164,8 @@ Shadings.RadialAxial = (function RadialAxialClosure() { ) { // Radial gradient only currently works if either circle is fully within // the other circle. - var x1 = this.coordsArr[0]; - var y1 = this.coordsArr[1]; - var r1 = this.coordsArr[2]; - var x2 = this.coordsArr[3]; - var y2 = this.coordsArr[4]; - var r2 = this.coordsArr[5]; - var distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); + const [x1, y1, r1, x2, y2, r2] = this.coordsArr; + const distance = Math.hypot(x1 - x2, y1 - y2); if (r1 <= r2 + distance && r2 <= r1 + distance) { warn("Unsupported radial gradient."); } diff --git a/src/display/canvas.js b/src/display/canvas.js index d63cb6a00..d6bbf4f86 100644 --- a/src/display/canvas.js +++ b/src/display/canvas.js @@ -1576,7 +1576,7 @@ const CanvasGraphics = (function CanvasGraphicsClosure() { }, setTextMatrix: function CanvasGraphics_setTextMatrix(a, b, c, d, e, f) { this.current.textMatrix = [a, b, c, d, e, f]; - this.current.textMatrixScale = Math.sqrt(a * a + b * b); + this.current.textMatrixScale = Math.hypot(a, b); this.current.x = this.current.lineX = 0; this.current.y = this.current.lineY = 0; @@ -2455,12 +2455,14 @@ const CanvasGraphics = (function CanvasGraphicsClosure() { ctx.scale(1 / width, -1 / height); const currentTransform = ctx.mozCurrentTransformInverse; - const a = currentTransform[0], - b = currentTransform[1]; - let widthScale = Math.max(Math.sqrt(a * a + b * b), 1); - const c = currentTransform[2], - d = currentTransform[3]; - let heightScale = Math.max(Math.sqrt(c * c + d * d), 1); + let widthScale = Math.max( + Math.hypot(currentTransform[0], currentTransform[1]), + 1 + ); + let heightScale = Math.max( + Math.hypot(currentTransform[2], currentTransform[3]), + 1 + ); let imgToPaint, tmpCanvas, tmpCtx; // typeof check is needed due to node.js support, see issue #8489 diff --git a/src/display/svg.js b/src/display/svg.js index 003b72392..56019e1e9 100644 --- a/src/display/svg.js +++ b/src/display/svg.js @@ -735,7 +735,7 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { setTextMatrix(a, b, c, d, e, f) { const current = this.current; current.textMatrix = current.lineMatrix = [a, b, c, d, e, f]; - current.textMatrixScale = Math.sqrt(a * a + b * b); + current.textMatrixScale = Math.hypot(a, b); current.x = current.lineX = 0; current.y = current.lineY = 0; diff --git a/src/display/text_layer.js b/src/display/text_layer.js index d84db3087..19e750729 100644 --- a/src/display/text_layer.js +++ b/src/display/text_layer.js @@ -89,7 +89,7 @@ const renderTextLayer = (function renderTextLayerClosure() { if (style.vertical) { angle += Math.PI / 2; } - const fontHeight = Math.sqrt(tx[2] * tx[2] + tx[3] * tx[3]); + const fontHeight = Math.hypot(tx[2], tx[3]); let fontAscent = fontHeight; if (style.ascent) { fontAscent = style.ascent * fontAscent; diff --git a/src/shared/util.js b/src/shared/util.js index 84fcb0bce..391072709 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -720,7 +720,7 @@ class Util { // Solve the second degree polynomial to get roots. const first = (a + d) / 2; - const second = Math.sqrt((a + d) * (a + d) - 4 * (a * d - c * b)) / 2; + const second = Math.sqrt((a + d) ** 2 - 4 * (a * d - c * b)) / 2; const sx = first + second || 1; const sy = first - second || 1; diff --git a/web/ui_utils.js b/web/ui_utils.js index bfb9100ea..0c5eda291 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -655,7 +655,7 @@ function getPDFFileNameFromURL(url, defaultFilename = "document.pdf") { } function normalizeWheelEventDirection(evt) { - let delta = Math.sqrt(evt.deltaX * evt.deltaX + evt.deltaY * evt.deltaY); + let delta = Math.hypot(evt.deltaX, evt.deltaY); const angle = Math.atan2(evt.deltaY, evt.deltaX); if (-0.25 * Math.PI < angle && angle < 0.75 * Math.PI) { // All that is left-up oriented has to change the sign.