Skip to content

Commit c7c08bb

Browse files
Merge pull request #19710 from Snuffleupagus/Math-sumPrecise
Introduce `Math.sumPrecise` usage in the code-base
2 parents 80d4d70 + e73224d commit c7c08bb

File tree

9 files changed

+40
-35
lines changed

9 files changed

+40
-35
lines changed

src/core/annotation.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -2572,11 +2572,7 @@ class WidgetAnnotation extends Annotation {
25722572
}
25732573

25742574
_getTextWidth(text, font) {
2575-
return (
2576-
font
2577-
.charsToGlyphs(text)
2578-
.reduce((width, glyph) => width + glyph.width, 0) / 1000
2579-
);
2575+
return Math.sumPrecise(font.charsToGlyphs(text).map(g => g.width)) / 1000;
25802576
}
25812577

25822578
_computeFontSize(height, width, text, font, lineCount) {

src/core/crypto.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ class PDF20 extends PDFBase {
720720
// The number is e0 + 256 * e1 + 256^2 * e2... and 256 % 3 === 1, hence
721721
// the powers of 256 are === 1 modulo 3 and finally the number modulo 3
722722
// is equal to the remainder modulo 3 of the sum of the e_n.
723-
const remainder = e.slice(0, 16).reduce((a, b) => a + b, 0) % 3;
723+
const remainder = Math.sumPrecise(e.slice(0, 16)) % 3;
724724
if (remainder === 0) {
725725
k = calculateSHA256(e, 0, e.length);
726726
} else if (remainder === 1) {

src/core/glyf.js

+4-5
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,10 @@ class GlyfTable {
8181
}
8282

8383
getSize() {
84-
return this.glyphs.reduce((a, g) => {
85-
const size = g.getSize();
84+
return Math.sumPrecise(
8685
// Round to next multiple of 4 if needed.
87-
return a + ((size + 3) & ~3);
88-
}, 0);
86+
this.glyphs.map(g => (g.getSize() + 3) & ~3)
87+
);
8988
}
9089

9190
write() {
@@ -169,7 +168,7 @@ class Glyph {
169168
}
170169
const size = this.simple
171170
? this.simple.getSize()
172-
: this.composites.reduce((a, c) => a + c.getSize(), 0);
171+
: Math.sumPrecise(this.composites.map(c => c.getSize()));
173172
return this.header.getSize() + size;
174173
}
175174

src/core/writer.js

+4-6
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ function computeMD5(filesize, xrefInfo) {
184184
filesize.toString(),
185185
...Object.values(xrefInfo.info),
186186
];
187-
const md5BufferLen = md5Buffer.reduce((a, str) => a + str.length, 0);
187+
const md5BufferLen = Math.sumPrecise(md5Buffer.map(str => str.length));
188188

189189
const array = new Uint8Array(md5BufferLen);
190190
let offset = 0;
@@ -352,7 +352,7 @@ async function getXRefStreamTable(
352352
newXref.set("W", sizes);
353353
computeIDs(baseOffset, xrefInfo, newXref);
354354

355-
const structSize = sizes.reduce((a, x) => a + x, 0);
355+
const structSize = Math.sumPrecise(sizes);
356356
const data = new Uint8Array(structSize * xrefTableData.length);
357357
const stream = new Stream(data);
358358
stream.dict = newXref;
@@ -467,10 +467,8 @@ async function incrementalUpdate({
467467
? getXRefStreamTable(xrefInfo, baseOffset, newRefs, newXref, buffer)
468468
: getXRefTable(xrefInfo, baseOffset, newRefs, newXref, buffer));
469469

470-
const totalLength = buffer.reduce(
471-
(a, str) => a + str.length,
472-
originalData.length
473-
);
470+
const totalLength =
471+
originalData.length + Math.sumPrecise(buffer.map(str => str.length));
474472
const array = new Uint8Array(totalLength);
475473

476474
// Original data

src/core/xfa/html_utils.js

+15-13
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,15 @@ const converters = {
8686
const colSpan = node.colSpan;
8787
let w;
8888
if (colSpan === -1) {
89-
w = extra.columnWidths
90-
.slice(extra.currentColumn)
91-
.reduce((a, x) => a + x, 0);
89+
w = Math.sumPrecise(extra.columnWidths.slice(extra.currentColumn));
9290
extra.currentColumn = 0;
9391
} else {
94-
w = extra.columnWidths
95-
.slice(extra.currentColumn, extra.currentColumn + colSpan)
96-
.reduce((a, x) => a + x, 0);
92+
w = Math.sumPrecise(
93+
extra.columnWidths.slice(
94+
extra.currentColumn,
95+
extra.currentColumn + colSpan
96+
)
97+
);
9798
extra.currentColumn =
9899
(extra.currentColumn + node.colSpan) % extra.columnWidths.length;
99100
}
@@ -328,13 +329,14 @@ function fixDimensions(node) {
328329
const colSpan = node.colSpan;
329330
let width;
330331
if (colSpan === -1) {
331-
width = extra.columnWidths
332-
.slice(extra.currentColumn)
333-
.reduce((a, w) => a + w, 0);
332+
width = Math.sumPrecise(extra.columnWidths.slice(extra.currentColumn));
334333
} else {
335-
width = extra.columnWidths
336-
.slice(extra.currentColumn, extra.currentColumn + colSpan)
337-
.reduce((a, w) => a + w, 0);
334+
width = Math.sumPrecise(
335+
extra.columnWidths.slice(
336+
extra.currentColumn,
337+
extra.currentColumn + colSpan
338+
)
339+
);
338340
}
339341
if (!isNaN(width)) {
340342
node.w = width;
@@ -348,7 +350,7 @@ function fixDimensions(node) {
348350

349351
if (node.layout === "table") {
350352
if (node.w === "" && Array.isArray(node.columnWidths)) {
351-
node.w = node.columnWidths.reduce((a, x) => a + x, 0);
353+
node.w = Math.sumPrecise(node.columnWidths);
352354
}
353355
}
354356
}

src/core/xfa/layout.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,9 @@ function getAvailableSpace(node) {
183183
};
184184
case "rl-row":
185185
case "row":
186-
const width = node[$extra].columnWidths
187-
.slice(node[$extra].currentColumn)
188-
.reduce((a, x) => a + x);
186+
const width = Math.sumPrecise(
187+
node[$extra].columnWidths.slice(node[$extra].currentColumn)
188+
);
189189
return { width, height: availableSpace.height - marginH };
190190
case "table":
191191
case "tb":

src/display/editor/freetext.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ class FreeTextEditor extends AnnotationEditor {
718718

719719
// Set the caret at the right position.
720720
const newRange = new Range();
721-
let beforeLength = bufferBefore.reduce((acc, line) => acc + line.length, 0);
721+
let beforeLength = Math.sumPrecise(bufferBefore.map(line => line.length));
722722
for (const { firstChild } of this.editorDiv.childNodes) {
723723
// Each child is either a div with a text node or a br element.
724724
if (firstChild.nodeType === Node.TEXT_NODE) {

src/shared/util.js

+10
Original file line numberDiff line numberDiff line change
@@ -1130,6 +1130,16 @@ if (
11301130
};
11311131
}
11321132

1133+
// TODO: Remove this once the `javascript.options.experimental.math_sumprecise`
1134+
// preference is removed from Firefox.
1135+
if (typeof Math.sumPrecise !== "function") {
1136+
// Note that this isn't a "proper" polyfill, but since we're only using it to
1137+
// replace `Array.prototype.reduce()` invocations it should be fine.
1138+
Math.sumPrecise = function (numbers) {
1139+
return numbers.reduce((a, b) => a + b, 0);
1140+
};
1141+
}
1142+
11331143
if (
11341144
typeof PDFJSDev !== "undefined" &&
11351145
!PDFJSDev.test("SKIP_BABEL") &&

test/unit/pdf_find_controller_spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ function testSearch({
128128
}
129129
}
130130

131-
const totalMatches = matchesPerPage.reduce((a, b) => a + b);
131+
const totalMatches = Math.sumPrecise(matchesPerPage);
132132

133133
if (updateFindControlState) {
134134
eventBus.on(

0 commit comments

Comments
 (0)