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.
This commit is contained in:
Jonas Jenwald 2021-02-10 12:28:49 +01:00 committed by GitHub
parent 3a2c259b57
commit 31098c404d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 23 additions and 27 deletions

View File

@ -1364,7 +1364,7 @@ const LabCS = (function LabCSClosure() {
function fn_g(x) { function fn_g(x) {
let result; let result;
if (x >= 6 / 29) { if (x >= 6 / 29) {
result = x * x * x; result = x ** 3;
} else { } else {
result = (108 / 841) * (x - 4 / 29); result = (108 / 841) * (x - 4 / 29);
} }

View File

@ -2077,20 +2077,19 @@ class PartialEvaluator {
textContentItem.transform = trm; textContentItem.transform = trm;
if (!font.vertical) { if (!font.vertical) {
textContentItem.width = 0; 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; textContentItem.vertical = false;
} else { } 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.height = 0;
textContentItem.vertical = true; textContentItem.vertical = true;
} }
var a = textState.textLineMatrix[0]; const scaleLineX = Math.hypot(
var b = textState.textLineMatrix[1]; textState.textLineMatrix[0],
var scaleLineX = Math.sqrt(a * a + b * b); textState.textLineMatrix[1]
a = textState.ctm[0]; );
b = textState.ctm[1]; const scaleCtmX = Math.hypot(textState.ctm[0], textState.ctm[1]);
var scaleCtmX = Math.sqrt(a * a + b * b);
textContentItem.textAdvanceScale = scaleCtmX * scaleLineX; textContentItem.textAdvanceScale = scaleCtmX * scaleLineX;
textContentItem.lastAdvanceWidth = 0; textContentItem.lastAdvanceWidth = 0;
textContentItem.lastAdvanceHeight = 0; textContentItem.lastAdvanceHeight = 0;

View File

@ -164,13 +164,8 @@ Shadings.RadialAxial = (function RadialAxialClosure() {
) { ) {
// Radial gradient only currently works if either circle is fully within // Radial gradient only currently works if either circle is fully within
// the other circle. // the other circle.
var x1 = this.coordsArr[0]; const [x1, y1, r1, x2, y2, r2] = this.coordsArr;
var y1 = this.coordsArr[1]; const distance = Math.hypot(x1 - x2, y1 - y2);
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));
if (r1 <= r2 + distance && r2 <= r1 + distance) { if (r1 <= r2 + distance && r2 <= r1 + distance) {
warn("Unsupported radial gradient."); warn("Unsupported radial gradient.");
} }

View File

@ -1576,7 +1576,7 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
}, },
setTextMatrix: function CanvasGraphics_setTextMatrix(a, b, c, d, e, f) { setTextMatrix: function CanvasGraphics_setTextMatrix(a, b, c, d, e, f) {
this.current.textMatrix = [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.x = this.current.lineX = 0;
this.current.y = this.current.lineY = 0; this.current.y = this.current.lineY = 0;
@ -2455,12 +2455,14 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
ctx.scale(1 / width, -1 / height); ctx.scale(1 / width, -1 / height);
const currentTransform = ctx.mozCurrentTransformInverse; const currentTransform = ctx.mozCurrentTransformInverse;
const a = currentTransform[0], let widthScale = Math.max(
b = currentTransform[1]; Math.hypot(currentTransform[0], currentTransform[1]),
let widthScale = Math.max(Math.sqrt(a * a + b * b), 1); 1
const c = currentTransform[2], );
d = currentTransform[3]; let heightScale = Math.max(
let heightScale = Math.max(Math.sqrt(c * c + d * d), 1); Math.hypot(currentTransform[2], currentTransform[3]),
1
);
let imgToPaint, tmpCanvas, tmpCtx; let imgToPaint, tmpCanvas, tmpCtx;
// typeof check is needed due to node.js support, see issue #8489 // typeof check is needed due to node.js support, see issue #8489

View File

@ -735,7 +735,7 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
setTextMatrix(a, b, c, d, e, f) { setTextMatrix(a, b, c, d, e, f) {
const current = this.current; const current = this.current;
current.textMatrix = current.lineMatrix = [a, b, c, d, e, f]; 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.x = current.lineX = 0;
current.y = current.lineY = 0; current.y = current.lineY = 0;

View File

@ -89,7 +89,7 @@ const renderTextLayer = (function renderTextLayerClosure() {
if (style.vertical) { if (style.vertical) {
angle += Math.PI / 2; 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; let fontAscent = fontHeight;
if (style.ascent) { if (style.ascent) {
fontAscent = style.ascent * fontAscent; fontAscent = style.ascent * fontAscent;

View File

@ -720,7 +720,7 @@ class Util {
// Solve the second degree polynomial to get roots. // Solve the second degree polynomial to get roots.
const first = (a + d) / 2; 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 sx = first + second || 1;
const sy = first - second || 1; const sy = first - second || 1;

View File

@ -655,7 +655,7 @@ function getPDFFileNameFromURL(url, defaultFilename = "document.pdf") {
} }
function normalizeWheelEventDirection(evt) { 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); const angle = Math.atan2(evt.deltaY, evt.deltaX);
if (-0.25 * Math.PI < angle && angle < 0.75 * Math.PI) { if (-0.25 * Math.PI < angle && angle < 0.75 * Math.PI) {
// All that is left-up oriented has to change the sign. // All that is left-up oriented has to change the sign.