1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-20 07:08:08 +02:00

Merge pull request #19713 from Snuffleupagus/Util-minMax-methods

Add new bounding-box helpers in `Util` to reduce code duplication
This commit is contained in:
Jonas Jenwald 2025-03-24 16:39:05 +01:00 committed by GitHub
commit fceaab8864
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 71 additions and 95 deletions

View file

@ -4325,10 +4325,13 @@ class PolylineAnnotation extends MarkupAnnotation {
// we get similar rendering/highlighting behaviour as in Adobe Reader.
const bbox = [Infinity, Infinity, -Infinity, -Infinity];
for (let i = 0, ii = vertices.length; i < ii; i += 2) {
bbox[0] = Math.min(bbox[0], vertices[i] - borderAdjust);
bbox[1] = Math.min(bbox[1], vertices[i + 1] - borderAdjust);
bbox[2] = Math.max(bbox[2], vertices[i] + borderAdjust);
bbox[3] = Math.max(bbox[3], vertices[i + 1] + borderAdjust);
Util.rectBoundingBox(
vertices[i] - borderAdjust,
vertices[i + 1] - borderAdjust,
vertices[i] + borderAdjust,
vertices[i + 1] + borderAdjust,
bbox
);
}
if (!Util.intersect(this.rectangle, bbox)) {
this.rectangle = bbox;
@ -4422,10 +4425,13 @@ class InkAnnotation extends MarkupAnnotation {
const bbox = [Infinity, Infinity, -Infinity, -Infinity];
for (const inkList of this.data.inkLists) {
for (let i = 0, ii = inkList.length; i < ii; i += 2) {
bbox[0] = Math.min(bbox[0], inkList[i] - borderAdjust);
bbox[1] = Math.min(bbox[1], inkList[i + 1] - borderAdjust);
bbox[2] = Math.max(bbox[2], inkList[i] + borderAdjust);
bbox[3] = Math.max(bbox[3], inkList[i + 1] + borderAdjust);
Util.rectBoundingBox(
inkList[i] - borderAdjust,
inkList[i + 1] - borderAdjust,
inkList[i] + borderAdjust,
inkList[i + 1] + borderAdjust,
bbox
);
}
}
if (!Util.intersect(this.rectangle, bbox)) {

View file

@ -1421,30 +1421,21 @@ class PartialEvaluator {
DrawOPS.closePath
);
}
minMax[0] = Math.min(minMax[0], x, xw);
minMax[1] = Math.min(minMax[1], y, yh);
minMax[2] = Math.max(minMax[2], x, xw);
minMax[3] = Math.max(minMax[3], y, yh);
Util.rectBoundingBox(x, y, xw, yh, minMax);
break;
}
case OPS.moveTo: {
const x = (state.currentPointX = args[0]);
const y = (state.currentPointY = args[1]);
pathBuffer.push(DrawOPS.moveTo, x, y);
minMax[0] = Math.min(minMax[0], x);
minMax[1] = Math.min(minMax[1], y);
minMax[2] = Math.max(minMax[2], x);
minMax[3] = Math.max(minMax[3], y);
Util.pointBoundingBox(x, y, minMax);
break;
}
case OPS.lineTo: {
const x = (state.currentPointX = args[0]);
const y = (state.currentPointY = args[1]);
pathBuffer.push(DrawOPS.lineTo, x, y);
minMax[0] = Math.min(minMax[0], x);
minMax[1] = Math.min(minMax[1], y);
minMax[2] = Math.max(minMax[2], x);
minMax[3] = Math.max(minMax[3], y);
Util.pointBoundingBox(x, y, minMax);
break;
}
case OPS.curveTo: {
@ -4812,7 +4803,8 @@ class TranslatedFont {
// Override the fontBBox when it's undefined/empty, or when it's at least
// (approximately) one order of magnitude smaller than the charBBox
// (fixes issue14999_reduced.pdf).
this.#computeCharBBox(charBBox);
this._bbox ??= [Infinity, Infinity, -Infinity, -Infinity];
Util.rectBoundingBox(...charBBox, this._bbox);
}
let i = 0,
@ -4881,21 +4873,13 @@ class TranslatedFont {
case OPS.constructPath:
const minMax = operatorList.argsArray[i][2];
// Override the fontBBox when it's undefined/empty (fixes 19624.pdf).
this.#computeCharBBox(minMax);
this._bbox ??= [Infinity, Infinity, -Infinity, -Infinity];
Util.rectBoundingBox(...minMax, this._bbox);
break;
}
i++;
}
}
#computeCharBBox(bbox) {
this._bbox ||= [Infinity, Infinity, -Infinity, -Infinity];
this._bbox[0] = Math.min(this._bbox[0], bbox[0]);
this._bbox[1] = Math.min(this._bbox[1], bbox[1]);
this._bbox[2] = Math.max(this._bbox[2], bbox[2]);
this._bbox[3] = Math.max(this._bbox[3], bbox[3]);
}
}
class StateManager {

View file

@ -559,36 +559,30 @@ class FreeDrawOutline extends Outline {
const outline = this.#outline;
let lastX = outline[4];
let lastY = outline[5];
let minX = lastX;
let minY = lastY;
let maxX = lastX;
let maxY = lastY;
const minMax = [lastX, lastY, lastX, lastY];
let lastPointX = lastX;
let lastPointY = lastY;
const ltrCallback = isLTR ? Math.max : Math.min;
for (let i = 6, ii = outline.length; i < ii; i += 6) {
const x = outline[i + 4],
y = outline[i + 5];
if (isNaN(outline[i])) {
minX = Math.min(minX, outline[i + 4]);
minY = Math.min(minY, outline[i + 5]);
maxX = Math.max(maxX, outline[i + 4]);
maxY = Math.max(maxY, outline[i + 5]);
if (lastPointY < outline[i + 5]) {
lastPointX = outline[i + 4];
lastPointY = outline[i + 5];
} else if (lastPointY === outline[i + 5]) {
lastPointX = ltrCallback(lastPointX, outline[i + 4]);
Util.pointBoundingBox(x, y, minMax);
if (lastPointY < y) {
lastPointX = x;
lastPointY = y;
} else if (lastPointY === y) {
lastPointX = ltrCallback(lastPointX, x);
}
} else {
const bbox = Util.bezierBoundingBox(
lastX,
lastY,
...outline.slice(i, i + 6)
);
minX = Math.min(minX, bbox[0]);
minY = Math.min(minY, bbox[1]);
maxX = Math.max(maxX, bbox[2]);
maxY = Math.max(maxY, bbox[3]);
const bbox = [Infinity, Infinity, -Infinity, -Infinity];
Util.bezierBoundingBox(lastX, lastY, ...outline.slice(i, i + 6), bbox);
Util.rectBoundingBox(...bbox, minMax);
if (lastPointY < bbox[3]) {
lastPointX = bbox[2];
lastPointY = bbox[3];
@ -596,15 +590,15 @@ class FreeDrawOutline extends Outline {
lastPointX = ltrCallback(lastPointX, bbox[2]);
}
}
lastX = outline[i + 4];
lastY = outline[i + 5];
lastX = x;
lastY = y;
}
const bbox = this.#bbox;
bbox[0] = minX - this.#innerMargin;
bbox[1] = minY - this.#innerMargin;
bbox[2] = maxX - minX + 2 * this.#innerMargin;
bbox[3] = maxY - minY + 2 * this.#innerMargin;
bbox[0] = minMax[0] - this.#innerMargin;
bbox[1] = minMax[1] - this.#innerMargin;
bbox[2] = minMax[2] - minMax[0] + 2 * this.#innerMargin;
bbox[3] = minMax[3] - minMax[1] + 2 * this.#innerMargin;
this.lastPoint = [lastPointX, lastPointY];
}

View file

@ -15,6 +15,7 @@
import { FreeDrawOutline, FreeDrawOutliner } from "./freedraw.js";
import { Outline } from "./outline.js";
import { Util } from "../../../shared/util.js";
class HighlightOutliner {
#box;
@ -38,10 +39,7 @@ class HighlightOutliner {
* the last point of the boxes.
*/
constructor(boxes, borderWidth = 0, innerMargin = 0, isLTR = true) {
let minX = Infinity;
let maxX = -Infinity;
let minY = Infinity;
let maxY = -Infinity;
const minMax = [Infinity, Infinity, -Infinity, -Infinity];
// We round the coordinates to slightly reduce the number of edges in the
// final outlines.
@ -58,16 +56,13 @@ class HighlightOutliner {
const right = [x2, y1, y2, false];
this.#verticalEdges.push(left, right);
minX = Math.min(minX, x1);
maxX = Math.max(maxX, x2);
minY = Math.min(minY, y1);
maxY = Math.max(maxY, y2);
Util.rectBoundingBox(x1, y1, x2, y2, minMax);
}
const bboxWidth = maxX - minX + 2 * innerMargin;
const bboxHeight = maxY - minY + 2 * innerMargin;
const shiftedMinX = minX - innerMargin;
const shiftedMinY = minY - innerMargin;
const bboxWidth = minMax[2] - minMax[0] + 2 * innerMargin;
const bboxHeight = minMax[3] - minMax[1] + 2 * innerMargin;
const shiftedMinX = minMax[0] - innerMargin;
const shiftedMinY = minMax[1] - innerMargin;
const lastEdge = this.#verticalEdges.at(isLTR ? -1 : -2);
const lastPoint = [lastEdge[0], lastEdge[2]];

View file

@ -597,11 +597,7 @@ class InkDrawOutline extends Outline {
if (line.length <= 12) {
// We've only one or two points => no bezier curve.
for (let i = 4, ii = line.length; i < ii; i += 6) {
const [x, y] = line.subarray(i, i + 2);
bbox[0] = Math.min(bbox[0], x);
bbox[1] = Math.min(bbox[1], y);
bbox[2] = Math.max(bbox[2], x);
bbox[3] = Math.max(bbox[3], y);
Util.pointBoundingBox(line[i], line[i + 1], bbox);
}
continue;
}

View file

@ -798,6 +798,20 @@ class Util {
return [xLow, yLow, xHigh, yHigh];
}
static pointBoundingBox(x, y, minMax) {
minMax[0] = Math.min(minMax[0], x);
minMax[1] = Math.min(minMax[1], y);
minMax[2] = Math.max(minMax[2], x);
minMax[3] = Math.max(minMax[3], y);
}
static rectBoundingBox(x0, y0, x1, y1, minMax) {
minMax[0] = Math.min(minMax[0], x0, x1);
minMax[1] = Math.min(minMax[1], y0, y1);
minMax[2] = Math.max(minMax[2], x0, x1);
minMax[3] = Math.max(minMax[3], y0, y1);
}
static #getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, t, minMax) {
if (t <= 0 || t >= 1) {
return;
@ -866,19 +880,11 @@ class Util {
// From https://github.com/adobe-webplatform/Snap.svg/blob/b365287722a72526000ac4bfcf0ce4cac2faa015/src/path.js#L852
static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3, minMax) {
if (minMax) {
minMax[0] = Math.min(minMax[0], x0, x3);
minMax[1] = Math.min(minMax[1], y0, y3);
minMax[2] = Math.max(minMax[2], x0, x3);
minMax[3] = Math.max(minMax[3], y0, y3);
} else {
minMax = [
Math.min(x0, x3),
Math.min(y0, y3),
Math.max(x0, x3),
Math.max(y0, y3),
];
}
minMax[0] = Math.min(minMax[0], x0, x3);
minMax[1] = Math.min(minMax[1], y0, y3);
minMax[2] = Math.max(minMax[2], x0, x3);
minMax[3] = Math.max(minMax[3], y0, y3);
this.#getExtremum(
x0,
x1,
@ -907,7 +913,6 @@ class Util {
3 * (y1 - y0),
minMax
);
return minMax;
}
}

View file

@ -59,11 +59,7 @@ function calculateLinkPosition(range, pdfPageView) {
quadPoints[i + 2] = quadPoints[i + 6] = normalized[2];
quadPoints[i + 5] = quadPoints[i + 7] = normalized[1];
rect[0] = Math.min(rect[0], normalized[0]);
rect[1] = Math.min(rect[1], normalized[1]);
rect[2] = Math.max(rect[2], normalized[2]);
rect[3] = Math.max(rect[3], normalized[3]);
Util.rectBoundingBox(...normalized, rect);
i += 8;
}
return { quadPoints, rect };