Skip to content

Commit b85f090

Browse files
committed
Add new bounding-box helpers in Util to reduce code duplication
Currently we have a `Util`-helper for computing the bounding-box of a Bézier curve, however for simple points and rectangles we repeat virtually identical code in many spots throughout the code-base. - Introduce new `Util.pointBoundingBox` and `Util.rectBoundingBox` helpers. - Remove the "fallback" from `Util.bezierBoundingBox` and only support passing in a `minMax`-array, since there's only a single call-site using the other format and it could be easily updated.
1 parent 19b4ada commit b85f090

7 files changed

Lines changed: 71 additions & 95 deletions

File tree

src/core/annotation.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4325,10 +4325,13 @@ class PolylineAnnotation extends MarkupAnnotation {
43254325
// we get similar rendering/highlighting behaviour as in Adobe Reader.
43264326
const bbox = [Infinity, Infinity, -Infinity, -Infinity];
43274327
for (let i = 0, ii = vertices.length; i < ii; i += 2) {
4328-
bbox[0] = Math.min(bbox[0], vertices[i] - borderAdjust);
4329-
bbox[1] = Math.min(bbox[1], vertices[i + 1] - borderAdjust);
4330-
bbox[2] = Math.max(bbox[2], vertices[i] + borderAdjust);
4331-
bbox[3] = Math.max(bbox[3], vertices[i + 1] + borderAdjust);
4328+
Util.rectBoundingBox(
4329+
vertices[i] - borderAdjust,
4330+
vertices[i + 1] - borderAdjust,
4331+
vertices[i] + borderAdjust,
4332+
vertices[i + 1] + borderAdjust,
4333+
bbox
4334+
);
43324335
}
43334336
if (!Util.intersect(this.rectangle, bbox)) {
43344337
this.rectangle = bbox;
@@ -4422,10 +4425,13 @@ class InkAnnotation extends MarkupAnnotation {
44224425
const bbox = [Infinity, Infinity, -Infinity, -Infinity];
44234426
for (const inkList of this.data.inkLists) {
44244427
for (let i = 0, ii = inkList.length; i < ii; i += 2) {
4425-
bbox[0] = Math.min(bbox[0], inkList[i] - borderAdjust);
4426-
bbox[1] = Math.min(bbox[1], inkList[i + 1] - borderAdjust);
4427-
bbox[2] = Math.max(bbox[2], inkList[i] + borderAdjust);
4428-
bbox[3] = Math.max(bbox[3], inkList[i + 1] + borderAdjust);
4428+
Util.rectBoundingBox(
4429+
inkList[i] - borderAdjust,
4430+
inkList[i + 1] - borderAdjust,
4431+
inkList[i] + borderAdjust,
4432+
inkList[i + 1] + borderAdjust,
4433+
bbox
4434+
);
44294435
}
44304436
}
44314437
if (!Util.intersect(this.rectangle, bbox)) {

src/core/evaluator.js

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,30 +1421,21 @@ class PartialEvaluator {
14211421
DrawOPS.closePath
14221422
);
14231423
}
1424-
minMax[0] = Math.min(minMax[0], x, xw);
1425-
minMax[1] = Math.min(minMax[1], y, yh);
1426-
minMax[2] = Math.max(minMax[2], x, xw);
1427-
minMax[3] = Math.max(minMax[3], y, yh);
1424+
Util.rectBoundingBox(x, y, xw, yh, minMax);
14281425
break;
14291426
}
14301427
case OPS.moveTo: {
14311428
const x = (state.currentPointX = args[0]);
14321429
const y = (state.currentPointY = args[1]);
14331430
pathBuffer.push(DrawOPS.moveTo, x, y);
1434-
minMax[0] = Math.min(minMax[0], x);
1435-
minMax[1] = Math.min(minMax[1], y);
1436-
minMax[2] = Math.max(minMax[2], x);
1437-
minMax[3] = Math.max(minMax[3], y);
1431+
Util.pointBoundingBox(x, y, minMax);
14381432
break;
14391433
}
14401434
case OPS.lineTo: {
14411435
const x = (state.currentPointX = args[0]);
14421436
const y = (state.currentPointY = args[1]);
14431437
pathBuffer.push(DrawOPS.lineTo, x, y);
1444-
minMax[0] = Math.min(minMax[0], x);
1445-
minMax[1] = Math.min(minMax[1], y);
1446-
minMax[2] = Math.max(minMax[2], x);
1447-
minMax[3] = Math.max(minMax[3], y);
1438+
Util.pointBoundingBox(x, y, minMax);
14481439
break;
14491440
}
14501441
case OPS.curveTo: {
@@ -4812,7 +4803,8 @@ class TranslatedFont {
48124803
// Override the fontBBox when it's undefined/empty, or when it's at least
48134804
// (approximately) one order of magnitude smaller than the charBBox
48144805
// (fixes issue14999_reduced.pdf).
4815-
this.#computeCharBBox(charBBox);
4806+
this._bbox ??= [Infinity, Infinity, -Infinity, -Infinity];
4807+
Util.rectBoundingBox(...charBBox, this._bbox);
48164808
}
48174809

48184810
let i = 0,
@@ -4881,21 +4873,13 @@ class TranslatedFont {
48814873
case OPS.constructPath:
48824874
const minMax = operatorList.argsArray[i][2];
48834875
// Override the fontBBox when it's undefined/empty (fixes 19624.pdf).
4884-
this.#computeCharBBox(minMax);
4876+
this._bbox ??= [Infinity, Infinity, -Infinity, -Infinity];
4877+
Util.rectBoundingBox(...minMax, this._bbox);
48854878
break;
48864879
}
48874880
i++;
48884881
}
48894882
}
4890-
4891-
#computeCharBBox(bbox) {
4892-
this._bbox ||= [Infinity, Infinity, -Infinity, -Infinity];
4893-
4894-
this._bbox[0] = Math.min(this._bbox[0], bbox[0]);
4895-
this._bbox[1] = Math.min(this._bbox[1], bbox[1]);
4896-
this._bbox[2] = Math.max(this._bbox[2], bbox[2]);
4897-
this._bbox[3] = Math.max(this._bbox[3], bbox[3]);
4898-
}
48994883
}
49004884

49014885
class StateManager {

src/display/editor/drawers/freedraw.js

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -559,52 +559,46 @@ class FreeDrawOutline extends Outline {
559559
const outline = this.#outline;
560560
let lastX = outline[4];
561561
let lastY = outline[5];
562-
let minX = lastX;
563-
let minY = lastY;
564-
let maxX = lastX;
565-
let maxY = lastY;
562+
const minMax = [lastX, lastY, lastX, lastY];
566563
let lastPointX = lastX;
567564
let lastPointY = lastY;
568565
const ltrCallback = isLTR ? Math.max : Math.min;
569566

570567
for (let i = 6, ii = outline.length; i < ii; i += 6) {
568+
const x = outline[i + 4],
569+
y = outline[i + 5];
570+
571571
if (isNaN(outline[i])) {
572-
minX = Math.min(minX, outline[i + 4]);
573-
minY = Math.min(minY, outline[i + 5]);
574-
maxX = Math.max(maxX, outline[i + 4]);
575-
maxY = Math.max(maxY, outline[i + 5]);
576-
if (lastPointY < outline[i + 5]) {
577-
lastPointX = outline[i + 4];
578-
lastPointY = outline[i + 5];
579-
} else if (lastPointY === outline[i + 5]) {
580-
lastPointX = ltrCallback(lastPointX, outline[i + 4]);
572+
Util.pointBoundingBox(x, y, minMax);
573+
574+
if (lastPointY < y) {
575+
lastPointX = x;
576+
lastPointY = y;
577+
} else if (lastPointY === y) {
578+
lastPointX = ltrCallback(lastPointX, x);
581579
}
582580
} else {
583-
const bbox = Util.bezierBoundingBox(
584-
lastX,
585-
lastY,
586-
...outline.slice(i, i + 6)
587-
);
588-
minX = Math.min(minX, bbox[0]);
589-
minY = Math.min(minY, bbox[1]);
590-
maxX = Math.max(maxX, bbox[2]);
591-
maxY = Math.max(maxY, bbox[3]);
581+
const bbox = [Infinity, Infinity, -Infinity, -Infinity];
582+
Util.bezierBoundingBox(lastX, lastY, ...outline.slice(i, i + 6), bbox);
583+
584+
Util.rectBoundingBox(...bbox, minMax);
585+
592586
if (lastPointY < bbox[3]) {
593587
lastPointX = bbox[2];
594588
lastPointY = bbox[3];
595589
} else if (lastPointY === bbox[3]) {
596590
lastPointX = ltrCallback(lastPointX, bbox[2]);
597591
}
598592
}
599-
lastX = outline[i + 4];
600-
lastY = outline[i + 5];
593+
lastX = x;
594+
lastY = y;
601595
}
602596

603597
const bbox = this.#bbox;
604-
bbox[0] = minX - this.#innerMargin;
605-
bbox[1] = minY - this.#innerMargin;
606-
bbox[2] = maxX - minX + 2 * this.#innerMargin;
607-
bbox[3] = maxY - minY + 2 * this.#innerMargin;
598+
bbox[0] = minMax[0] - this.#innerMargin;
599+
bbox[1] = minMax[1] - this.#innerMargin;
600+
bbox[2] = minMax[2] - minMax[0] + 2 * this.#innerMargin;
601+
bbox[3] = minMax[3] - minMax[1] + 2 * this.#innerMargin;
608602
this.lastPoint = [lastPointX, lastPointY];
609603
}
610604

src/display/editor/drawers/highlight.js

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import { FreeDrawOutline, FreeDrawOutliner } from "./freedraw.js";
1717
import { Outline } from "./outline.js";
18+
import { Util } from "../../../shared/util.js";
1819

1920
class HighlightOutliner {
2021
#box;
@@ -38,10 +39,7 @@ class HighlightOutliner {
3839
* the last point of the boxes.
3940
*/
4041
constructor(boxes, borderWidth = 0, innerMargin = 0, isLTR = true) {
41-
let minX = Infinity;
42-
let maxX = -Infinity;
43-
let minY = Infinity;
44-
let maxY = -Infinity;
42+
const minMax = [Infinity, Infinity, -Infinity, -Infinity];
4543

4644
// We round the coordinates to slightly reduce the number of edges in the
4745
// final outlines.
@@ -58,16 +56,13 @@ class HighlightOutliner {
5856
const right = [x2, y1, y2, false];
5957
this.#verticalEdges.push(left, right);
6058

61-
minX = Math.min(minX, x1);
62-
maxX = Math.max(maxX, x2);
63-
minY = Math.min(minY, y1);
64-
maxY = Math.max(maxY, y2);
59+
Util.rectBoundingBox(x1, y1, x2, y2, minMax);
6560
}
6661

67-
const bboxWidth = maxX - minX + 2 * innerMargin;
68-
const bboxHeight = maxY - minY + 2 * innerMargin;
69-
const shiftedMinX = minX - innerMargin;
70-
const shiftedMinY = minY - innerMargin;
62+
const bboxWidth = minMax[2] - minMax[0] + 2 * innerMargin;
63+
const bboxHeight = minMax[3] - minMax[1] + 2 * innerMargin;
64+
const shiftedMinX = minMax[0] - innerMargin;
65+
const shiftedMinY = minMax[1] - innerMargin;
7166
const lastEdge = this.#verticalEdges.at(isLTR ? -1 : -2);
7267
const lastPoint = [lastEdge[0], lastEdge[2]];
7368

src/display/editor/drawers/inkdraw.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -597,11 +597,7 @@ class InkDrawOutline extends Outline {
597597
if (line.length <= 12) {
598598
// We've only one or two points => no bezier curve.
599599
for (let i = 4, ii = line.length; i < ii; i += 6) {
600-
const [x, y] = line.subarray(i, i + 2);
601-
bbox[0] = Math.min(bbox[0], x);
602-
bbox[1] = Math.min(bbox[1], y);
603-
bbox[2] = Math.max(bbox[2], x);
604-
bbox[3] = Math.max(bbox[3], y);
600+
Util.pointBoundingBox(line[i], line[i + 1], bbox);
605601
}
606602
continue;
607603
}

src/shared/util.js

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,20 @@ class Util {
798798
return [xLow, yLow, xHigh, yHigh];
799799
}
800800

801+
static pointBoundingBox(x, y, minMax) {
802+
minMax[0] = Math.min(minMax[0], x);
803+
minMax[1] = Math.min(minMax[1], y);
804+
minMax[2] = Math.max(minMax[2], x);
805+
minMax[3] = Math.max(minMax[3], y);
806+
}
807+
808+
static rectBoundingBox(x0, y0, x1, y1, minMax) {
809+
minMax[0] = Math.min(minMax[0], x0, x1);
810+
minMax[1] = Math.min(minMax[1], y0, y1);
811+
minMax[2] = Math.max(minMax[2], x0, x1);
812+
minMax[3] = Math.max(minMax[3], y0, y1);
813+
}
814+
801815
static #getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, t, minMax) {
802816
if (t <= 0 || t >= 1) {
803817
return;
@@ -866,19 +880,11 @@ class Util {
866880

867881
// From https://github.com/adobe-webplatform/Snap.svg/blob/b365287722a72526000ac4bfcf0ce4cac2faa015/src/path.js#L852
868882
static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3, minMax) {
869-
if (minMax) {
870-
minMax[0] = Math.min(minMax[0], x0, x3);
871-
minMax[1] = Math.min(minMax[1], y0, y3);
872-
minMax[2] = Math.max(minMax[2], x0, x3);
873-
minMax[3] = Math.max(minMax[3], y0, y3);
874-
} else {
875-
minMax = [
876-
Math.min(x0, x3),
877-
Math.min(y0, y3),
878-
Math.max(x0, x3),
879-
Math.max(y0, y3),
880-
];
881-
}
883+
minMax[0] = Math.min(minMax[0], x0, x3);
884+
minMax[1] = Math.min(minMax[1], y0, y3);
885+
minMax[2] = Math.max(minMax[2], x0, x3);
886+
minMax[3] = Math.max(minMax[3], y0, y3);
887+
882888
this.#getExtremum(
883889
x0,
884890
x1,
@@ -907,7 +913,6 @@ class Util {
907913
3 * (y1 - y0),
908914
minMax
909915
);
910-
return minMax;
911916
}
912917
}
913918

web/autolinker.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,7 @@ function calculateLinkPosition(range, pdfPageView) {
5959
quadPoints[i + 2] = quadPoints[i + 6] = normalized[2];
6060
quadPoints[i + 5] = quadPoints[i + 7] = normalized[1];
6161

62-
rect[0] = Math.min(rect[0], normalized[0]);
63-
rect[1] = Math.min(rect[1], normalized[1]);
64-
rect[2] = Math.max(rect[2], normalized[2]);
65-
rect[3] = Math.max(rect[3], normalized[3]);
66-
62+
Util.rectBoundingBox(...normalized, rect);
6763
i += 8;
6864
}
6965
return { quadPoints, rect };

0 commit comments

Comments
 (0)