Merge pull request #21283 from Snuffleupagus/mv-getXfaPageViewport

[api-minor] Move the `getXfaPageViewport` helper into the `XfaLayer` class
This commit is contained in:
Jonas Jenwald 2026-05-16 14:18:22 +02:00 committed by GitHub
commit d27b9ab5fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 263 additions and 254 deletions

View File

@ -14,7 +14,7 @@
*/
/** @typedef {import("./api").PDFPageProxy} PDFPageProxy */
/** @typedef {import("./display_utils").PageViewport} PageViewport */
/** @typedef {import("./page_viewport").PageViewport} PageViewport */
// eslint-disable-next-line max-len
/** @typedef {import("../../web/text_accessibility.js").TextAccessibilityManager} TextAccessibilityManager */
// eslint-disable-next-line max-len

View File

@ -57,7 +57,6 @@ import {
import {
isDataScheme,
isValidFetchUrl,
PageViewport,
RenderingCancelledException,
StatTimer,
} from "./display_utils.js";
@ -78,6 +77,7 @@ import { MathClamp } from "../shared/math_clamp.js";
import { Metadata } from "./metadata.js";
import { OptionalContentConfig } from "./optional_content_config.js";
import { PagesMapper } from "./pages_mapper.js";
import { PageViewport } from "./page_viewport.js";
import { PDFDataTransportStream } from "./transport_stream.js";
import { PDFObjects } from "./pdf_objects.js";
import { TextLayer } from "./text_layer.js";

View File

@ -22,6 +22,7 @@ import {
warn,
} from "../shared/util.js";
import { MathClamp } from "../shared/math_clamp.js";
import { PageViewport } from "./page_viewport.js";
import { XfaLayer } from "./xfa_layer.js";
const SVG_NS = "http://www.w3.org/2000/svg";
@ -84,220 +85,6 @@ async function fetchData(url, type = "text") {
});
}
/**
* @typedef {Object} PageViewportParameters
* @property {Array<number>} viewBox - The xMin, yMin, xMax and
* yMax coordinates.
* @property {number} userUnit - The size of units.
* @property {number} scale - The scale of the viewport.
* @property {number} rotation - The rotation, in degrees, of the viewport.
* @property {number} [offsetX] - The horizontal, i.e. x-axis, offset. The
* default value is `0`.
* @property {number} [offsetY] - The vertical, i.e. y-axis, offset. The
* default value is `0`.
* @property {boolean} [dontFlip] - If true, the y-axis will not be flipped.
* The default value is `false`.
*/
/**
* @typedef {Object} PageViewportCloneParameters
* @property {number} [scale] - The scale, overriding the one in the cloned
* viewport. The default value is `this.scale`.
* @property {number} [rotation] - The rotation, in degrees, overriding the one
* in the cloned viewport. The default value is `this.rotation`.
* @property {number} [offsetX] - The horizontal, i.e. x-axis, offset.
* The default value is `this.offsetX`.
* @property {number} [offsetY] - The vertical, i.e. y-axis, offset.
* The default value is `this.offsetY`.
* @property {boolean} [dontFlip] - If true, the x-axis will not be flipped.
* The default value is `false`.
*/
/**
* PDF page viewport created based on scale, rotation and offset.
*/
class PageViewport {
/**
* @param {PageViewportParameters}
*/
constructor({
viewBox,
userUnit,
scale,
rotation,
offsetX = 0,
offsetY = 0,
dontFlip = false,
}) {
this.viewBox = viewBox;
this.userUnit = userUnit;
this.scale = scale;
this.rotation = rotation;
this.offsetX = offsetX;
this.offsetY = offsetY;
scale *= userUnit; // Take the userUnit into account.
// creating transform to convert pdf coordinate system to the normal
// canvas like coordinates taking in account scale and rotation
const centerX = (viewBox[2] + viewBox[0]) / 2;
const centerY = (viewBox[3] + viewBox[1]) / 2;
let rotateA, rotateB, rotateC, rotateD;
// Normalize the rotation, by clamping it to the [0, 360) range.
rotation %= 360;
if (rotation < 0) {
rotation += 360;
}
switch (rotation) {
case 180:
rotateA = -1;
rotateB = 0;
rotateC = 0;
rotateD = 1;
break;
case 90:
rotateA = 0;
rotateB = 1;
rotateC = 1;
rotateD = 0;
break;
case 270:
rotateA = 0;
rotateB = -1;
rotateC = -1;
rotateD = 0;
break;
case 0:
rotateA = 1;
rotateB = 0;
rotateC = 0;
rotateD = -1;
break;
default:
throw new Error(
"PageViewport: Invalid rotation, must be a multiple of 90 degrees."
);
}
if (dontFlip) {
rotateC = -rotateC;
rotateD = -rotateD;
}
let offsetCanvasX, offsetCanvasY;
let width, height;
if (rotateA === 0) {
offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX;
offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY;
width = (viewBox[3] - viewBox[1]) * scale;
height = (viewBox[2] - viewBox[0]) * scale;
} else {
offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX;
offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY;
width = (viewBox[2] - viewBox[0]) * scale;
height = (viewBox[3] - viewBox[1]) * scale;
}
// creating transform for the following operations:
// translate(-centerX, -centerY), rotate and flip vertically,
// scale, and translate(offsetCanvasX, offsetCanvasY)
this.transform = [
rotateA * scale,
rotateB * scale,
rotateC * scale,
rotateD * scale,
offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY,
offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY,
];
this.width = width;
this.height = height;
}
/**
* The original, un-scaled, viewport dimensions.
* @type {Object}
*/
get rawDims() {
const dims = this.viewBox;
return shadow(this, "rawDims", {
pageWidth: dims[2] - dims[0],
pageHeight: dims[3] - dims[1],
pageX: dims[0],
pageY: dims[1],
});
}
/**
* Clones viewport, with optional additional properties.
* @param {PageViewportCloneParameters} [params]
* @returns {PageViewport} Cloned viewport.
*/
clone({
scale = this.scale,
rotation = this.rotation,
offsetX = this.offsetX,
offsetY = this.offsetY,
dontFlip = false,
} = {}) {
return new PageViewport({
viewBox: this.viewBox.slice(),
userUnit: this.userUnit,
scale,
rotation,
offsetX,
offsetY,
dontFlip,
});
}
/**
* Converts PDF point to the viewport coordinates. For examples, useful for
* converting PDF location into canvas pixel coordinates.
* @param {number} x - The x-coordinate.
* @param {number} y - The y-coordinate.
* @returns {Array} Array containing `x`- and `y`-coordinates of the
* point in the viewport coordinate space.
* @see {@link convertToPdfPoint}
* @see {@link convertToViewportRectangle}
*/
convertToViewportPoint(x, y) {
const p = [x, y];
Util.applyTransform(p, this.transform);
return p;
}
/**
* Converts PDF rectangle to the viewport coordinates.
* @param {Array} rect - The xMin, yMin, xMax and yMax coordinates.
* @returns {Array} Array containing corresponding coordinates of the
* rectangle in the viewport coordinate space.
* @see {@link convertToViewportPoint}
*/
convertToViewportRectangle(rect) {
const topLeft = [rect[0], rect[1]];
Util.applyTransform(topLeft, this.transform);
const bottomRight = [rect[2], rect[3]];
Util.applyTransform(bottomRight, this.transform);
return [topLeft[0], topLeft[1], bottomRight[0], bottomRight[1]];
}
/**
* Converts viewport coordinates to the PDF location. For examples, useful
* for converting canvas pixel location into PDF one.
* @param {number} x - The x-coordinate.
* @param {number} y - The y-coordinate.
* @returns {Array} Array containing `x`- and `y`-coordinates of the
* point in the PDF coordinate space.
* @see {@link convertToViewportPoint}
*/
convertToPdfPoint(x, y) {
const p = [x, y];
Util.applyInverseTransform(p, this.transform);
return p;
}
}
class RenderingCancelledException extends BaseException {
constructor(msg, extraDelay = 0) {
super(msg, "RenderingCancelledException");
@ -561,21 +348,6 @@ class PDFDateString {
}
}
/**
* NOTE: This is (mostly) intended to support printing of XFA forms.
*/
function getXfaPageViewport(xfaPage, { scale = 1, rotation = 0 }) {
const { width, height } = xfaPage.attributes.style;
const viewBox = [0, 0, parseInt(width, 10), parseInt(height, 10)];
return new PageViewport({
viewBox,
userUnit: 1,
scale,
rotation,
});
}
function getRGBA(color) {
if (color.startsWith("#")) {
// #RRGGBB or #RRGGBBAA
@ -1058,14 +830,12 @@ export {
getPdfFilenameFromUrl,
getRGB,
getRGBA,
getXfaPageViewport,
isDataScheme,
isPdfFile,
isValidFetchUrl,
makePathFromDrawOPS,
noContextMenu,
OutputScale,
PageViewport,
PDFDateString,
PixelsPerInch,
RenderingCancelledException,

View File

@ -15,7 +15,7 @@
// eslint-disable-next-line max-len
/** @typedef {import("./tools.js").AnnotationEditorUIManager} AnnotationEditorUIManager */
/** @typedef {import("../display_utils.js").PageViewport} PageViewport */
/** @typedef {import("../page_viewport.js").PageViewport} PageViewport */
// eslint-disable-next-line max-len
/** @typedef {import("../../../web/text_accessibility.js").TextAccessibilityManager} TextAccessibilityManager */
// eslint-disable-next-line max-len

View File

@ -0,0 +1,232 @@
/* Copyright 2015 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { shadow, Util } from "../shared/util.js";
/**
* @typedef {Object} PageViewportParameters
* @property {Array<number>} viewBox - The xMin, yMin, xMax and
* yMax coordinates.
* @property {number} userUnit - The size of units.
* @property {number} scale - The scale of the viewport.
* @property {number} rotation - The rotation, in degrees, of the viewport.
* @property {number} [offsetX] - The horizontal, i.e. x-axis, offset. The
* default value is `0`.
* @property {number} [offsetY] - The vertical, i.e. y-axis, offset. The
* default value is `0`.
* @property {boolean} [dontFlip] - If true, the y-axis will not be flipped.
* The default value is `false`.
*/
/**
* @typedef {Object} PageViewportCloneParameters
* @property {number} [scale] - The scale, overriding the one in the cloned
* viewport. The default value is `this.scale`.
* @property {number} [rotation] - The rotation, in degrees, overriding the one
* in the cloned viewport. The default value is `this.rotation`.
* @property {number} [offsetX] - The horizontal, i.e. x-axis, offset.
* The default value is `this.offsetX`.
* @property {number} [offsetY] - The vertical, i.e. y-axis, offset.
* The default value is `this.offsetY`.
* @property {boolean} [dontFlip] - If true, the x-axis will not be flipped.
* The default value is `false`.
*/
/**
* PDF page viewport created based on scale, rotation and offset.
*/
class PageViewport {
/**
* @param {PageViewportParameters}
*/
constructor({
viewBox,
userUnit,
scale,
rotation,
offsetX = 0,
offsetY = 0,
dontFlip = false,
}) {
this.viewBox = viewBox;
this.userUnit = userUnit;
this.scale = scale;
this.rotation = rotation;
this.offsetX = offsetX;
this.offsetY = offsetY;
scale *= userUnit; // Take the userUnit into account.
// creating transform to convert pdf coordinate system to the normal
// canvas like coordinates taking in account scale and rotation
const centerX = (viewBox[2] + viewBox[0]) / 2;
const centerY = (viewBox[3] + viewBox[1]) / 2;
let rotateA, rotateB, rotateC, rotateD;
// Normalize the rotation, by clamping it to the [0, 360) range.
rotation %= 360;
if (rotation < 0) {
rotation += 360;
}
switch (rotation) {
case 180:
rotateA = -1;
rotateB = 0;
rotateC = 0;
rotateD = 1;
break;
case 90:
rotateA = 0;
rotateB = 1;
rotateC = 1;
rotateD = 0;
break;
case 270:
rotateA = 0;
rotateB = -1;
rotateC = -1;
rotateD = 0;
break;
case 0:
rotateA = 1;
rotateB = 0;
rotateC = 0;
rotateD = -1;
break;
default:
throw new Error(
"PageViewport: Invalid rotation, must be a multiple of 90 degrees."
);
}
if (dontFlip) {
rotateC = -rotateC;
rotateD = -rotateD;
}
let offsetCanvasX, offsetCanvasY;
let width, height;
if (rotateA === 0) {
offsetCanvasX = Math.abs(centerY - viewBox[1]) * scale + offsetX;
offsetCanvasY = Math.abs(centerX - viewBox[0]) * scale + offsetY;
width = (viewBox[3] - viewBox[1]) * scale;
height = (viewBox[2] - viewBox[0]) * scale;
} else {
offsetCanvasX = Math.abs(centerX - viewBox[0]) * scale + offsetX;
offsetCanvasY = Math.abs(centerY - viewBox[1]) * scale + offsetY;
width = (viewBox[2] - viewBox[0]) * scale;
height = (viewBox[3] - viewBox[1]) * scale;
}
// creating transform for the following operations:
// translate(-centerX, -centerY), rotate and flip vertically,
// scale, and translate(offsetCanvasX, offsetCanvasY)
this.transform = [
rotateA * scale,
rotateB * scale,
rotateC * scale,
rotateD * scale,
offsetCanvasX - rotateA * scale * centerX - rotateC * scale * centerY,
offsetCanvasY - rotateB * scale * centerX - rotateD * scale * centerY,
];
this.width = width;
this.height = height;
}
/**
* The original, un-scaled, viewport dimensions.
* @type {Object}
*/
get rawDims() {
const dims = this.viewBox;
return shadow(this, "rawDims", {
pageWidth: dims[2] - dims[0],
pageHeight: dims[3] - dims[1],
pageX: dims[0],
pageY: dims[1],
});
}
/**
* Clones viewport, with optional additional properties.
* @param {PageViewportCloneParameters} [params]
* @returns {PageViewport} Cloned viewport.
*/
clone({
scale = this.scale,
rotation = this.rotation,
offsetX = this.offsetX,
offsetY = this.offsetY,
dontFlip = false,
} = {}) {
return new PageViewport({
viewBox: this.viewBox.slice(),
userUnit: this.userUnit,
scale,
rotation,
offsetX,
offsetY,
dontFlip,
});
}
/**
* Converts PDF point to the viewport coordinates. For examples, useful for
* converting PDF location into canvas pixel coordinates.
* @param {number} x - The x-coordinate.
* @param {number} y - The y-coordinate.
* @returns {Array} Array containing `x`- and `y`-coordinates of the
* point in the viewport coordinate space.
* @see {@link convertToPdfPoint}
* @see {@link convertToViewportRectangle}
*/
convertToViewportPoint(x, y) {
const p = [x, y];
Util.applyTransform(p, this.transform);
return p;
}
/**
* Converts PDF rectangle to the viewport coordinates.
* @param {Array} rect - The xMin, yMin, xMax and yMax coordinates.
* @returns {Array} Array containing corresponding coordinates of the
* rectangle in the viewport coordinate space.
* @see {@link convertToViewportPoint}
*/
convertToViewportRectangle(rect) {
const topLeft = [rect[0], rect[1]];
Util.applyTransform(topLeft, this.transform);
const bottomRight = [rect[2], rect[3]];
Util.applyTransform(bottomRight, this.transform);
return [topLeft[0], topLeft[1], bottomRight[0], bottomRight[1]];
}
/**
* Converts viewport coordinates to the PDF location. For examples, useful
* for converting canvas pixel location into PDF one.
* @param {number} x - The x-coordinate.
* @param {number} y - The y-coordinate.
* @returns {Array} Array containing `x`- and `y`-coordinates of the
* point in the PDF coordinate space.
* @see {@link convertToViewportPoint}
*/
convertToPdfPoint(x, y) {
const p = [x, y];
Util.applyInverseTransform(p, this.transform);
return p;
}
}
export { PageViewport };

View File

@ -13,7 +13,7 @@
* limitations under the License.
*/
/** @typedef {import("./display_utils").PageViewport} PageViewport */
/** @typedef {import("./page_viewport").PageViewport} PageViewport */
/** @typedef {import("./api").TextContent} TextContent */
/** @typedef {import("./text_layer_images").TextLayerImages} TextLayerImages */

View File

@ -15,10 +15,10 @@
// eslint-disable-next-line max-len
/** @typedef {import("./annotation_storage").AnnotationStorage} AnnotationStorage */
/** @typedef {import("./display_utils").PageViewport} PageViewport */
// eslint-disable-next-line max-len
/** @typedef {import("../../web/pdf_link_service.js").PDFLinkService} PDFLinkService */
import { PageViewport } from "./page_viewport.js";
import { XfaText } from "./xfa_text.js";
/**
@ -293,6 +293,20 @@ class XfaLayer {
parameters.div.style.transform = transform;
parameters.div.hidden = false;
}
/**
* NOTE: This is (mostly) intended to support printing of XFA forms.
*/
static getPageViewport(xfaPage, { scale = 1, rotation = 0 }) {
const { width, height } = xfaPage.attributes.style;
return new PageViewport({
viewBox: [0, 0, parseInt(width, 10), parseInt(height, 10)],
userUnit: 1,
scale,
rotation,
});
}
}
export { XfaLayer };

View File

@ -20,7 +20,7 @@
/** @typedef {import("./display/api").PDFDocumentProxy} PDFDocumentProxy */
/** @typedef {import("./display/api").PDFPageProxy} PDFPageProxy */
/** @typedef {import("./display/api").RenderTask} RenderTask */
/** @typedef {import("./display/display_utils").PageViewport} PageViewport */
/** @typedef {import("./display/page_viewport").PageViewport} PageViewport */
import {
AbortException,
@ -55,7 +55,6 @@ import {
getPdfFilenameFromUrl,
getRGB,
getRGBA,
getXfaPageViewport,
isDataScheme,
isPdfFile,
noContextMenu,
@ -122,7 +121,6 @@ globalThis.pdfjsLib = {
getRGB,
getRGBA,
getUuid,
getXfaPageViewport,
GlobalWorkerOptions,
ImageKind,
InvalidPDFException,
@ -186,7 +184,6 @@ export {
getRGB,
getRGBA,
getUuid,
getXfaPageViewport,
GlobalWorkerOptions,
ImageKind,
InvalidPDFException,

View File

@ -39,7 +39,6 @@ import {
} from "./test_utils.js";
import {
fetchData as fetchDataDOM,
PageViewport,
RenderingCancelledException,
StatTimer,
} from "../../src/display/display_utils.js";
@ -56,6 +55,7 @@ import { AutoPrintRegExp } from "../../web/ui_utils.js";
import { GlobalImageCache } from "../../src/core/image_utils.js";
import { GlobalWorkerOptions } from "../../src/display/worker_options.js";
import { Metadata } from "../../src/display/metadata.js";
import { PageViewport } from "../../src/display/page_viewport.js";
const WORKER_SRC = "../../build/generic/build/pdf.worker.mjs";

View File

@ -46,7 +46,6 @@ import {
getPdfFilenameFromUrl,
getRGB,
getRGBA,
getXfaPageViewport,
isDataScheme,
isPdfFile,
noContextMenu,
@ -106,7 +105,6 @@ const expectedAPI = Object.freeze({
getRGB,
getRGBA,
getUuid,
getXfaPageViewport,
GlobalWorkerOptions,
ImageKind,
InvalidPDFException,

View File

@ -15,7 +15,7 @@
/** @typedef {import("../src/display/api").PDFPageProxy} PDFPageProxy */
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/display_utils").PageViewport} PageViewport */
/** @typedef {import("../src/display/page_viewport").PageViewport} PageViewport */
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/editor/tools.js").AnnotationEditorUIManager} AnnotationEditorUIManager */
// eslint-disable-next-line max-len

View File

@ -15,7 +15,7 @@
/** @typedef {import("../src/display/api").PDFPageProxy} PDFPageProxy */
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/display_utils").PageViewport} PageViewport */
/** @typedef {import("../src/display/page_viewport").PageViewport} PageViewport */
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/annotation_storage").AnnotationStorage} AnnotationStorage */
// eslint-disable-next-line max-len

View File

@ -14,7 +14,7 @@
*/
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/display_utils").PageViewport} PageViewport */
/** @typedef {import("../src/display/page_viewport").PageViewport} PageViewport */
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/optional_content_config").OptionalContentConfig} OptionalContentConfig */
/** @typedef {import("./event_utils").EventBus} EventBus */

View File

@ -16,7 +16,7 @@
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/optional_content_config").OptionalContentConfig} OptionalContentConfig */
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/display_utils").PageViewport} PageViewport */
/** @typedef {import("../src/display/page_viewport").PageViewport} PageViewport */
/** @typedef {import("./event_utils").EventBus} EventBus */
// eslint-disable-next-line max-len
/** @typedef {import("./pdf_rendering_queue").PDFRenderingQueue} PDFRenderingQueue */

View File

@ -16,7 +16,7 @@
/** @typedef {import("../src/display/api").PDFDocumentProxy} PDFDocumentProxy */
/** @typedef {import("../src/display/api").PDFPageProxy} PDFPageProxy */
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/display_utils").PageViewport} PageViewport */
/** @typedef {import("../src/display/page_viewport").PageViewport} PageViewport */
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/optional_content_config").OptionalContentConfig} OptionalContentConfig */
/** @typedef {import("./event_utils").EventBus} EventBus */

View File

@ -38,7 +38,6 @@ const {
getRGB,
getRGBA,
getUuid,
getXfaPageViewport,
GlobalWorkerOptions,
ImageKind,
InvalidPDFException,
@ -102,7 +101,6 @@ export {
getRGB,
getRGBA,
getUuid,
getXfaPageViewport,
GlobalWorkerOptions,
ImageKind,
InvalidPDFException,

View File

@ -13,7 +13,7 @@
* limitations under the License.
*/
import { getXfaPageViewport, PixelsPerInch } from "pdfjs-lib";
import { PixelsPerInch, XfaLayer } from "pdfjs-lib";
import { SimpleLinkService } from "./pdf_link_service.js";
import { XfaLayerBuilder } from "./xfa_layer_builder.js";
@ -51,7 +51,7 @@ function getXfaHtmlForPrinting(printContainer, pdfDocument) {
linkService,
xfaHtml: xfaPage,
});
const viewport = getXfaPageViewport(xfaPage, { scale });
const viewport = XfaLayer.getPageViewport(xfaPage, { scale });
builder.render({ viewport, intent: "print" });
page.append(builder.div);

View File

@ -15,7 +15,7 @@
/** @typedef {import("../src/display/api").PDFPageProxy} PDFPageProxy */
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/display_utils").PageViewport} PageViewport */
/** @typedef {import("../src/display/page_viewport").PageViewport} PageViewport */
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/text_layer_images.js").TextLayerImages} TextLayerImages */
/** @typedef {import("./text_highlighter").TextHighlighter} TextHighlighter */

View File

@ -17,7 +17,7 @@
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/annotation_storage").AnnotationStorage} AnnotationStorage */
// eslint-disable-next-line max-len
/** @typedef {import("../src/display/display_utils").PageViewport} PageViewport */
/** @typedef {import("../src/display/page_viewport").PageViewport} PageViewport */
/** @typedef {import("./pdf_link_service.js").PDFLinkService} PDFLinkService */
import { XfaLayer } from "pdfjs-lib";