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:
commit
fceaab8864
7 changed files with 71 additions and 95 deletions
|
@ -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)) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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]];
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue