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
@ -4325,10 +4325,13 @@ class PolylineAnnotation extends MarkupAnnotation {
|
|||||||
// we get similar rendering/highlighting behaviour as in Adobe Reader.
|
// we get similar rendering/highlighting behaviour as in Adobe Reader.
|
||||||
const bbox = [Infinity, Infinity, -Infinity, -Infinity];
|
const bbox = [Infinity, Infinity, -Infinity, -Infinity];
|
||||||
for (let i = 0, ii = vertices.length; i < ii; i += 2) {
|
for (let i = 0, ii = vertices.length; i < ii; i += 2) {
|
||||||
bbox[0] = Math.min(bbox[0], vertices[i] - borderAdjust);
|
Util.rectBoundingBox(
|
||||||
bbox[1] = Math.min(bbox[1], vertices[i + 1] - borderAdjust);
|
vertices[i] - borderAdjust,
|
||||||
bbox[2] = Math.max(bbox[2], vertices[i] + borderAdjust);
|
vertices[i + 1] - borderAdjust,
|
||||||
bbox[3] = Math.max(bbox[3], vertices[i + 1] + borderAdjust);
|
vertices[i] + borderAdjust,
|
||||||
|
vertices[i + 1] + borderAdjust,
|
||||||
|
bbox
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (!Util.intersect(this.rectangle, bbox)) {
|
if (!Util.intersect(this.rectangle, bbox)) {
|
||||||
this.rectangle = bbox;
|
this.rectangle = bbox;
|
||||||
@ -4422,10 +4425,13 @@ class InkAnnotation extends MarkupAnnotation {
|
|||||||
const bbox = [Infinity, Infinity, -Infinity, -Infinity];
|
const bbox = [Infinity, Infinity, -Infinity, -Infinity];
|
||||||
for (const inkList of this.data.inkLists) {
|
for (const inkList of this.data.inkLists) {
|
||||||
for (let i = 0, ii = inkList.length; i < ii; i += 2) {
|
for (let i = 0, ii = inkList.length; i < ii; i += 2) {
|
||||||
bbox[0] = Math.min(bbox[0], inkList[i] - borderAdjust);
|
Util.rectBoundingBox(
|
||||||
bbox[1] = Math.min(bbox[1], inkList[i + 1] - borderAdjust);
|
inkList[i] - borderAdjust,
|
||||||
bbox[2] = Math.max(bbox[2], inkList[i] + borderAdjust);
|
inkList[i + 1] - borderAdjust,
|
||||||
bbox[3] = Math.max(bbox[3], inkList[i + 1] + borderAdjust);
|
inkList[i] + borderAdjust,
|
||||||
|
inkList[i + 1] + borderAdjust,
|
||||||
|
bbox
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!Util.intersect(this.rectangle, bbox)) {
|
if (!Util.intersect(this.rectangle, bbox)) {
|
||||||
|
|||||||
@ -1421,30 +1421,21 @@ class PartialEvaluator {
|
|||||||
DrawOPS.closePath
|
DrawOPS.closePath
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
minMax[0] = Math.min(minMax[0], x, xw);
|
Util.rectBoundingBox(x, y, xw, yh, minMax);
|
||||||
minMax[1] = Math.min(minMax[1], y, yh);
|
|
||||||
minMax[2] = Math.max(minMax[2], x, xw);
|
|
||||||
minMax[3] = Math.max(minMax[3], y, yh);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPS.moveTo: {
|
case OPS.moveTo: {
|
||||||
const x = (state.currentPointX = args[0]);
|
const x = (state.currentPointX = args[0]);
|
||||||
const y = (state.currentPointY = args[1]);
|
const y = (state.currentPointY = args[1]);
|
||||||
pathBuffer.push(DrawOPS.moveTo, x, y);
|
pathBuffer.push(DrawOPS.moveTo, x, y);
|
||||||
minMax[0] = Math.min(minMax[0], x);
|
Util.pointBoundingBox(x, y, minMax);
|
||||||
minMax[1] = Math.min(minMax[1], y);
|
|
||||||
minMax[2] = Math.max(minMax[2], x);
|
|
||||||
minMax[3] = Math.max(minMax[3], y);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPS.lineTo: {
|
case OPS.lineTo: {
|
||||||
const x = (state.currentPointX = args[0]);
|
const x = (state.currentPointX = args[0]);
|
||||||
const y = (state.currentPointY = args[1]);
|
const y = (state.currentPointY = args[1]);
|
||||||
pathBuffer.push(DrawOPS.lineTo, x, y);
|
pathBuffer.push(DrawOPS.lineTo, x, y);
|
||||||
minMax[0] = Math.min(minMax[0], x);
|
Util.pointBoundingBox(x, y, minMax);
|
||||||
minMax[1] = Math.min(minMax[1], y);
|
|
||||||
minMax[2] = Math.max(minMax[2], x);
|
|
||||||
minMax[3] = Math.max(minMax[3], y);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OPS.curveTo: {
|
case OPS.curveTo: {
|
||||||
@ -4812,7 +4803,8 @@ class TranslatedFont {
|
|||||||
// Override the fontBBox when it's undefined/empty, or when it's at least
|
// Override the fontBBox when it's undefined/empty, or when it's at least
|
||||||
// (approximately) one order of magnitude smaller than the charBBox
|
// (approximately) one order of magnitude smaller than the charBBox
|
||||||
// (fixes issue14999_reduced.pdf).
|
// (fixes issue14999_reduced.pdf).
|
||||||
this.#computeCharBBox(charBBox);
|
this._bbox ??= [Infinity, Infinity, -Infinity, -Infinity];
|
||||||
|
Util.rectBoundingBox(...charBBox, this._bbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
let i = 0,
|
let i = 0,
|
||||||
@ -4881,21 +4873,13 @@ class TranslatedFont {
|
|||||||
case OPS.constructPath:
|
case OPS.constructPath:
|
||||||
const minMax = operatorList.argsArray[i][2];
|
const minMax = operatorList.argsArray[i][2];
|
||||||
// Override the fontBBox when it's undefined/empty (fixes 19624.pdf).
|
// 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;
|
break;
|
||||||
}
|
}
|
||||||
i++;
|
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 {
|
class StateManager {
|
||||||
|
|||||||
@ -559,36 +559,30 @@ class FreeDrawOutline extends Outline {
|
|||||||
const outline = this.#outline;
|
const outline = this.#outline;
|
||||||
let lastX = outline[4];
|
let lastX = outline[4];
|
||||||
let lastY = outline[5];
|
let lastY = outline[5];
|
||||||
let minX = lastX;
|
const minMax = [lastX, lastY, lastX, lastY];
|
||||||
let minY = lastY;
|
|
||||||
let maxX = lastX;
|
|
||||||
let maxY = lastY;
|
|
||||||
let lastPointX = lastX;
|
let lastPointX = lastX;
|
||||||
let lastPointY = lastY;
|
let lastPointY = lastY;
|
||||||
const ltrCallback = isLTR ? Math.max : Math.min;
|
const ltrCallback = isLTR ? Math.max : Math.min;
|
||||||
|
|
||||||
for (let i = 6, ii = outline.length; i < ii; i += 6) {
|
for (let i = 6, ii = outline.length; i < ii; i += 6) {
|
||||||
|
const x = outline[i + 4],
|
||||||
|
y = outline[i + 5];
|
||||||
|
|
||||||
if (isNaN(outline[i])) {
|
if (isNaN(outline[i])) {
|
||||||
minX = Math.min(minX, outline[i + 4]);
|
Util.pointBoundingBox(x, y, minMax);
|
||||||
minY = Math.min(minY, outline[i + 5]);
|
|
||||||
maxX = Math.max(maxX, outline[i + 4]);
|
if (lastPointY < y) {
|
||||||
maxY = Math.max(maxY, outline[i + 5]);
|
lastPointX = x;
|
||||||
if (lastPointY < outline[i + 5]) {
|
lastPointY = y;
|
||||||
lastPointX = outline[i + 4];
|
} else if (lastPointY === y) {
|
||||||
lastPointY = outline[i + 5];
|
lastPointX = ltrCallback(lastPointX, x);
|
||||||
} else if (lastPointY === outline[i + 5]) {
|
|
||||||
lastPointX = ltrCallback(lastPointX, outline[i + 4]);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const bbox = Util.bezierBoundingBox(
|
const bbox = [Infinity, Infinity, -Infinity, -Infinity];
|
||||||
lastX,
|
Util.bezierBoundingBox(lastX, lastY, ...outline.slice(i, i + 6), bbox);
|
||||||
lastY,
|
|
||||||
...outline.slice(i, i + 6)
|
Util.rectBoundingBox(...bbox, minMax);
|
||||||
);
|
|
||||||
minX = Math.min(minX, bbox[0]);
|
|
||||||
minY = Math.min(minY, bbox[1]);
|
|
||||||
maxX = Math.max(maxX, bbox[2]);
|
|
||||||
maxY = Math.max(maxY, bbox[3]);
|
|
||||||
if (lastPointY < bbox[3]) {
|
if (lastPointY < bbox[3]) {
|
||||||
lastPointX = bbox[2];
|
lastPointX = bbox[2];
|
||||||
lastPointY = bbox[3];
|
lastPointY = bbox[3];
|
||||||
@ -596,15 +590,15 @@ class FreeDrawOutline extends Outline {
|
|||||||
lastPointX = ltrCallback(lastPointX, bbox[2]);
|
lastPointX = ltrCallback(lastPointX, bbox[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastX = outline[i + 4];
|
lastX = x;
|
||||||
lastY = outline[i + 5];
|
lastY = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bbox = this.#bbox;
|
const bbox = this.#bbox;
|
||||||
bbox[0] = minX - this.#innerMargin;
|
bbox[0] = minMax[0] - this.#innerMargin;
|
||||||
bbox[1] = minY - this.#innerMargin;
|
bbox[1] = minMax[1] - this.#innerMargin;
|
||||||
bbox[2] = maxX - minX + 2 * this.#innerMargin;
|
bbox[2] = minMax[2] - minMax[0] + 2 * this.#innerMargin;
|
||||||
bbox[3] = maxY - minY + 2 * this.#innerMargin;
|
bbox[3] = minMax[3] - minMax[1] + 2 * this.#innerMargin;
|
||||||
this.lastPoint = [lastPointX, lastPointY];
|
this.lastPoint = [lastPointX, lastPointY];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
import { FreeDrawOutline, FreeDrawOutliner } from "./freedraw.js";
|
import { FreeDrawOutline, FreeDrawOutliner } from "./freedraw.js";
|
||||||
import { Outline } from "./outline.js";
|
import { Outline } from "./outline.js";
|
||||||
|
import { Util } from "../../../shared/util.js";
|
||||||
|
|
||||||
class HighlightOutliner {
|
class HighlightOutliner {
|
||||||
#box;
|
#box;
|
||||||
@ -38,10 +39,7 @@ class HighlightOutliner {
|
|||||||
* the last point of the boxes.
|
* the last point of the boxes.
|
||||||
*/
|
*/
|
||||||
constructor(boxes, borderWidth = 0, innerMargin = 0, isLTR = true) {
|
constructor(boxes, borderWidth = 0, innerMargin = 0, isLTR = true) {
|
||||||
let minX = Infinity;
|
const minMax = [Infinity, Infinity, -Infinity, -Infinity];
|
||||||
let maxX = -Infinity;
|
|
||||||
let minY = Infinity;
|
|
||||||
let maxY = -Infinity;
|
|
||||||
|
|
||||||
// We round the coordinates to slightly reduce the number of edges in the
|
// We round the coordinates to slightly reduce the number of edges in the
|
||||||
// final outlines.
|
// final outlines.
|
||||||
@ -58,16 +56,13 @@ class HighlightOutliner {
|
|||||||
const right = [x2, y1, y2, false];
|
const right = [x2, y1, y2, false];
|
||||||
this.#verticalEdges.push(left, right);
|
this.#verticalEdges.push(left, right);
|
||||||
|
|
||||||
minX = Math.min(minX, x1);
|
Util.rectBoundingBox(x1, y1, x2, y2, minMax);
|
||||||
maxX = Math.max(maxX, x2);
|
|
||||||
minY = Math.min(minY, y1);
|
|
||||||
maxY = Math.max(maxY, y2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const bboxWidth = maxX - minX + 2 * innerMargin;
|
const bboxWidth = minMax[2] - minMax[0] + 2 * innerMargin;
|
||||||
const bboxHeight = maxY - minY + 2 * innerMargin;
|
const bboxHeight = minMax[3] - minMax[1] + 2 * innerMargin;
|
||||||
const shiftedMinX = minX - innerMargin;
|
const shiftedMinX = minMax[0] - innerMargin;
|
||||||
const shiftedMinY = minY - innerMargin;
|
const shiftedMinY = minMax[1] - innerMargin;
|
||||||
const lastEdge = this.#verticalEdges.at(isLTR ? -1 : -2);
|
const lastEdge = this.#verticalEdges.at(isLTR ? -1 : -2);
|
||||||
const lastPoint = [lastEdge[0], lastEdge[2]];
|
const lastPoint = [lastEdge[0], lastEdge[2]];
|
||||||
|
|
||||||
|
|||||||
@ -597,11 +597,7 @@ class InkDrawOutline extends Outline {
|
|||||||
if (line.length <= 12) {
|
if (line.length <= 12) {
|
||||||
// We've only one or two points => no bezier curve.
|
// We've only one or two points => no bezier curve.
|
||||||
for (let i = 4, ii = line.length; i < ii; i += 6) {
|
for (let i = 4, ii = line.length; i < ii; i += 6) {
|
||||||
const [x, y] = line.subarray(i, i + 2);
|
Util.pointBoundingBox(line[i], line[i + 1], bbox);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -798,6 +798,20 @@ class Util {
|
|||||||
return [xLow, yLow, xHigh, yHigh];
|
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) {
|
static #getExtremumOnCurve(x0, x1, x2, x3, y0, y1, y2, y3, t, minMax) {
|
||||||
if (t <= 0 || t >= 1) {
|
if (t <= 0 || t >= 1) {
|
||||||
return;
|
return;
|
||||||
@ -866,19 +880,11 @@ class Util {
|
|||||||
|
|
||||||
// From https://github.com/adobe-webplatform/Snap.svg/blob/b365287722a72526000ac4bfcf0ce4cac2faa015/src/path.js#L852
|
// 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) {
|
static bezierBoundingBox(x0, y0, x1, y1, x2, y2, x3, y3, minMax) {
|
||||||
if (minMax) {
|
minMax[0] = Math.min(minMax[0], x0, x3);
|
||||||
minMax[0] = Math.min(minMax[0], x0, x3);
|
minMax[1] = Math.min(minMax[1], y0, y3);
|
||||||
minMax[1] = Math.min(minMax[1], y0, y3);
|
minMax[2] = Math.max(minMax[2], x0, x3);
|
||||||
minMax[2] = Math.max(minMax[2], x0, x3);
|
minMax[3] = Math.max(minMax[3], y0, y3);
|
||||||
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),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
this.#getExtremum(
|
this.#getExtremum(
|
||||||
x0,
|
x0,
|
||||||
x1,
|
x1,
|
||||||
@ -907,7 +913,6 @@ class Util {
|
|||||||
3 * (y1 - y0),
|
3 * (y1 - y0),
|
||||||
minMax
|
minMax
|
||||||
);
|
);
|
||||||
return minMax;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -59,11 +59,7 @@ function calculateLinkPosition(range, pdfPageView) {
|
|||||||
quadPoints[i + 2] = quadPoints[i + 6] = normalized[2];
|
quadPoints[i + 2] = quadPoints[i + 6] = normalized[2];
|
||||||
quadPoints[i + 5] = quadPoints[i + 7] = normalized[1];
|
quadPoints[i + 5] = quadPoints[i + 7] = normalized[1];
|
||||||
|
|
||||||
rect[0] = Math.min(rect[0], normalized[0]);
|
Util.rectBoundingBox(...normalized, rect);
|
||||||
rect[1] = Math.min(rect[1], normalized[1]);
|
|
||||||
rect[2] = Math.max(rect[2], normalized[2]);
|
|
||||||
rect[3] = Math.max(rect[3], normalized[3]);
|
|
||||||
|
|
||||||
i += 8;
|
i += 8;
|
||||||
}
|
}
|
||||||
return { quadPoints, rect };
|
return { quadPoints, rect };
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user