mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-08-02 20:37:21 +02:00
Compare commits
6 Commits
c1a398d932
...
b8de9a372f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b8de9a372f | ||
|
|
0922aa9e9d | ||
|
|
262a1f9895 | ||
|
|
f5faf86180 | ||
|
|
7a251b206e | ||
|
|
ecc56a61e6 |
@ -2248,7 +2248,11 @@ class WidgetAnnotation extends Annotation {
|
|||||||
const appearanceDict = (appearanceStream.dict = new Dict(xref));
|
const appearanceDict = (appearanceStream.dict = new Dict(xref));
|
||||||
appearanceDict.set("Subtype", Name.get("Form"));
|
appearanceDict.set("Subtype", Name.get("Form"));
|
||||||
appearanceDict.set("Resources", resources);
|
appearanceDict.set("Resources", resources);
|
||||||
appearanceDict.set("BBox", [0, 0, this.width, this.height]);
|
const bbox =
|
||||||
|
rotation % 180 === 0
|
||||||
|
? [0, 0, this.width, this.height]
|
||||||
|
: [0, 0, this.height, this.width];
|
||||||
|
appearanceDict.set("BBox", bbox);
|
||||||
|
|
||||||
const rotationMatrix = this.getRotationMatrix(annotationStorage);
|
const rotationMatrix = this.getRotationMatrix(annotationStorage);
|
||||||
if (rotationMatrix !== IDENTITY_MATRIX) {
|
if (rotationMatrix !== IDENTITY_MATRIX) {
|
||||||
|
|||||||
@ -632,6 +632,13 @@ function recoverJsURL(str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function numberToString(value) {
|
function numberToString(value) {
|
||||||
|
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
|
||||||
|
assert(
|
||||||
|
typeof value === "number",
|
||||||
|
`numberToString - the value (${value}) should be a number.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (Number.isInteger(value)) {
|
if (Number.isInteger(value)) {
|
||||||
return value.toString();
|
return value.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -723,3 +723,4 @@
|
|||||||
!issue18529.pdf
|
!issue18529.pdf
|
||||||
!issue16742.pdf
|
!issue16742.pdf
|
||||||
!chrome-text-selection-markedContent.pdf
|
!chrome-text-selection-markedContent.pdf
|
||||||
|
!bug1963407.pdf
|
||||||
|
|||||||
BIN
test/pdfs/bug1963407.pdf
Executable file
BIN
test/pdfs/bug1963407.pdf
Executable file
Binary file not shown.
@ -12093,5 +12093,19 @@
|
|||||||
"md5": "98b19e944339c01c10c503685eee3ad2",
|
"md5": "98b19e944339c01c10c503685eee3ad2",
|
||||||
"rounds": 1,
|
"rounds": 1,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "bug1963407",
|
||||||
|
"file": "pdfs/bug1963407.pdf",
|
||||||
|
"md5": "49d3d2dd42014d978af6e6ad814e5e64",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "eq",
|
||||||
|
"save": true,
|
||||||
|
"print": true,
|
||||||
|
"annotationStorage": {
|
||||||
|
"24R": {
|
||||||
|
"value": "Hello World"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -2257,7 +2257,7 @@ describe("annotation", function () {
|
|||||||
);
|
);
|
||||||
expect(newData.data).toEqual(
|
expect(newData.data).toEqual(
|
||||||
"2 0 obj\n<< /Subtype /Form /Resources " +
|
"2 0 obj\n<< /Subtype /Form /Resources " +
|
||||||
"<< /Font << /Helv 314 0 R>>>> /BBox [0 0 32 10] /Matrix [0 1 -1 0 32 0] /Length 74>> stream\n" +
|
"<< /Font << /Helv 314 0 R>>>> /BBox [0 0 10 32] /Matrix [0 1 -1 0 32 0] /Length 74>> stream\n" +
|
||||||
"/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 0 Tm 2 2.94 Td (hello world) Tj " +
|
"/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 0 Tm 2 2.94 Td (hello world) Tj " +
|
||||||
"ET Q EMC\nendstream\nendobj\n"
|
"ET Q EMC\nendstream\nendobj\n"
|
||||||
);
|
);
|
||||||
@ -3808,7 +3808,7 @@ describe("annotation", function () {
|
|||||||
[
|
[
|
||||||
"2 0 obj",
|
"2 0 obj",
|
||||||
"<< /Subtype /Form /Resources << /Font << /Helv 314 0 R>>>> " +
|
"<< /Subtype /Form /Resources << /Font << /Helv 314 0 R>>>> " +
|
||||||
"/BBox [0 0 32 10] /Matrix [0 -1 1 0 0 10] /Length 170>> stream",
|
"/BBox [0 0 10 32] /Matrix [0 -1 1 0 0 10] /Length 170>> stream",
|
||||||
"/Tx BMC q",
|
"/Tx BMC q",
|
||||||
"1 1 10 32 re W n",
|
"1 1 10 32 re W n",
|
||||||
"0.600006 0.756866 0.854904 rg",
|
"0.600006 0.756866 0.854904 rg",
|
||||||
|
|||||||
@ -326,8 +326,6 @@ const PDFViewerApplication = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (params.has("pdfbug")) {
|
if (params.has("pdfbug")) {
|
||||||
AppOptions.setAll({ pdfBug: true, fontExtraProperties: true });
|
|
||||||
|
|
||||||
const enabled = params.get("pdfbug").split(",");
|
const enabled = params.get("pdfbug").split(",");
|
||||||
try {
|
try {
|
||||||
await loadPDFBug();
|
await loadPDFBug();
|
||||||
@ -335,6 +333,12 @@ const PDFViewerApplication = {
|
|||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
console.error("_parseHashParams:", ex);
|
console.error("_parseHashParams:", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const debugOpts = { pdfBug: true, fontExtraProperties: true };
|
||||||
|
if (globalThis.StepperManager?.enabled) {
|
||||||
|
debugOpts.minDurationToUpdateCanvas = 0;
|
||||||
|
}
|
||||||
|
AppOptions.setAll(debugOpts);
|
||||||
}
|
}
|
||||||
// It is not possible to change locale for the (various) extension builds.
|
// It is not possible to change locale for the (various) extension builds.
|
||||||
if (
|
if (
|
||||||
@ -519,6 +523,7 @@ const PDFViewerApplication = {
|
|||||||
enableHWA,
|
enableHWA,
|
||||||
supportsPinchToZoom: this.supportsPinchToZoom,
|
supportsPinchToZoom: this.supportsPinchToZoom,
|
||||||
enableAutoLinking: AppOptions.get("enableAutoLinking"),
|
enableAutoLinking: AppOptions.get("enableAutoLinking"),
|
||||||
|
minDurationToUpdateCanvas: AppOptions.get("minDurationToUpdateCanvas"),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
renderingQueue.setViewer(pdfViewer);
|
renderingQueue.setViewer(pdfViewer);
|
||||||
|
|||||||
@ -302,6 +302,11 @@ const defaultOptions = {
|
|||||||
value: 2 ** 25,
|
value: 2 ** 25,
|
||||||
kind: OptionKind.VIEWER,
|
kind: OptionKind.VIEWER,
|
||||||
},
|
},
|
||||||
|
minDurationToUpdateCanvas: {
|
||||||
|
/** @type {number} */
|
||||||
|
value: 500, // ms
|
||||||
|
kind: OptionKind.VIEWER,
|
||||||
|
},
|
||||||
forcePageColors: {
|
forcePageColors: {
|
||||||
/** @type {boolean} */
|
/** @type {boolean} */
|
||||||
value: false,
|
value: false,
|
||||||
|
|||||||
@ -21,12 +21,18 @@ class BasePDFPageView {
|
|||||||
|
|
||||||
#loadingId = null;
|
#loadingId = null;
|
||||||
|
|
||||||
|
#minDurationToUpdateCanvas = 0;
|
||||||
|
|
||||||
#renderError = null;
|
#renderError = null;
|
||||||
|
|
||||||
#renderingState = RenderingStates.INITIAL;
|
#renderingState = RenderingStates.INITIAL;
|
||||||
|
|
||||||
#showCanvas = null;
|
#showCanvas = null;
|
||||||
|
|
||||||
|
#startTime = 0;
|
||||||
|
|
||||||
|
#tempCanvas = null;
|
||||||
|
|
||||||
canvas = null;
|
canvas = null;
|
||||||
|
|
||||||
/** @type {null | HTMLDivElement} */
|
/** @type {null | HTMLDivElement} */
|
||||||
@ -51,6 +57,7 @@ class BasePDFPageView {
|
|||||||
this.id = options.id;
|
this.id = options.id;
|
||||||
this.pageColors = options.pageColors || null;
|
this.pageColors = options.pageColors || null;
|
||||||
this.renderingQueue = options.renderingQueue;
|
this.renderingQueue = options.renderingQueue;
|
||||||
|
this.#minDurationToUpdateCanvas = options.minDurationToUpdateCanvas ?? 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
get renderingState() {
|
get renderingState() {
|
||||||
@ -71,6 +78,9 @@ class BasePDFPageView {
|
|||||||
switch (state) {
|
switch (state) {
|
||||||
case RenderingStates.PAUSED:
|
case RenderingStates.PAUSED:
|
||||||
this.div.classList.remove("loading");
|
this.div.classList.remove("loading");
|
||||||
|
// Display the canvas as it has been drawn.
|
||||||
|
this.#startTime = 0;
|
||||||
|
this.#showCanvas?.(false);
|
||||||
break;
|
break;
|
||||||
case RenderingStates.RUNNING:
|
case RenderingStates.RUNNING:
|
||||||
this.div.classList.add("loadingIcon");
|
this.div.classList.add("loadingIcon");
|
||||||
@ -82,10 +92,12 @@ class BasePDFPageView {
|
|||||||
this.div.classList.add("loading");
|
this.div.classList.add("loading");
|
||||||
this.#loadingId = null;
|
this.#loadingId = null;
|
||||||
}, 0);
|
}, 0);
|
||||||
|
this.#startTime = Date.now();
|
||||||
break;
|
break;
|
||||||
case RenderingStates.INITIAL:
|
case RenderingStates.INITIAL:
|
||||||
case RenderingStates.FINISHED:
|
case RenderingStates.FINISHED:
|
||||||
this.div.classList.remove("loadingIcon", "loading");
|
this.div.classList.remove("loadingIcon", "loading");
|
||||||
|
this.#startTime = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,10 +112,41 @@ class BasePDFPageView {
|
|||||||
// have a final flash we just display it once all the drawing is done.
|
// have a final flash we just display it once all the drawing is done.
|
||||||
const updateOnFirstShow = !prevCanvas && !hasHCM && !hideUntilComplete;
|
const updateOnFirstShow = !prevCanvas && !hasHCM && !hideUntilComplete;
|
||||||
|
|
||||||
const canvas = (this.canvas = document.createElement("canvas"));
|
let canvas = (this.canvas = document.createElement("canvas"));
|
||||||
|
|
||||||
this.#showCanvas = isLastShow => {
|
this.#showCanvas = isLastShow => {
|
||||||
if (updateOnFirstShow) {
|
if (updateOnFirstShow) {
|
||||||
|
let tempCanvas = this.#tempCanvas;
|
||||||
|
if (!isLastShow && this.#minDurationToUpdateCanvas > 0) {
|
||||||
|
// We draw on the canvas at 60fps (in using `requestAnimationFrame`),
|
||||||
|
// so if the canvas is large, updating it at 60fps can be a way too
|
||||||
|
// much and can cause some serious performance issues.
|
||||||
|
// To avoid that we only update the canvas every
|
||||||
|
// `this.#minDurationToUpdateCanvas` ms.
|
||||||
|
|
||||||
|
if (Date.now() - this.#startTime < this.#minDurationToUpdateCanvas) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!tempCanvas) {
|
||||||
|
tempCanvas = this.#tempCanvas = canvas;
|
||||||
|
canvas = this.canvas = canvas.cloneNode(false);
|
||||||
|
onShow(canvas);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tempCanvas) {
|
||||||
|
const ctx = canvas.getContext("2d", {
|
||||||
|
alpha: false,
|
||||||
|
});
|
||||||
|
ctx.drawImage(tempCanvas, 0, 0);
|
||||||
|
if (isLastShow) {
|
||||||
|
this.#resetTempCanvas();
|
||||||
|
} else {
|
||||||
|
this.#startTime = Date.now();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Don't add the canvas until the first draw callback, or until
|
// Don't add the canvas until the first draw callback, or until
|
||||||
// drawing is complete when `!this.renderingQueue`, to prevent black
|
// drawing is complete when `!this.renderingQueue`, to prevent black
|
||||||
// flickering.
|
// flickering.
|
||||||
@ -152,6 +195,14 @@ class BasePDFPageView {
|
|||||||
canvas.remove();
|
canvas.remove();
|
||||||
canvas.width = canvas.height = 0;
|
canvas.width = canvas.height = 0;
|
||||||
this.canvas = null;
|
this.canvas = null;
|
||||||
|
this.#resetTempCanvas();
|
||||||
|
}
|
||||||
|
|
||||||
|
#resetTempCanvas() {
|
||||||
|
if (this.#tempCanvas) {
|
||||||
|
this.#tempCanvas.width = this.#tempCanvas.height = 0;
|
||||||
|
this.#tempCanvas = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async _drawCanvas(options, onCancel, onFinish) {
|
async _drawCanvas(options, onCancel, onFinish) {
|
||||||
|
|||||||
@ -139,6 +139,8 @@ function isValidAnnotationEditorMode(mode) {
|
|||||||
* The default value is `true`.
|
* The default value is `true`.
|
||||||
* @property {boolean} [enableAutoLinking] - Enable creation of hyperlinks from
|
* @property {boolean} [enableAutoLinking] - Enable creation of hyperlinks from
|
||||||
* text that look like URLs. The default value is `true`.
|
* text that look like URLs. The default value is `true`.
|
||||||
|
* @property {number} [minDurationToUpdateCanvas] - Minimum duration to wait
|
||||||
|
* before updating the canvas. The default value is `500`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PDFPageViewBuffer {
|
class PDFPageViewBuffer {
|
||||||
@ -243,6 +245,8 @@ class PDFViewer {
|
|||||||
|
|
||||||
#eventAbortController = null;
|
#eventAbortController = null;
|
||||||
|
|
||||||
|
#minDurationToUpdateCanvas = 0;
|
||||||
|
|
||||||
#mlManager = null;
|
#mlManager = null;
|
||||||
|
|
||||||
#scrollTimeoutId = null;
|
#scrollTimeoutId = null;
|
||||||
@ -342,6 +346,7 @@ class PDFViewer {
|
|||||||
this.#enableHWA = options.enableHWA || false;
|
this.#enableHWA = options.enableHWA || false;
|
||||||
this.#supportsPinchToZoom = options.supportsPinchToZoom !== false;
|
this.#supportsPinchToZoom = options.supportsPinchToZoom !== false;
|
||||||
this.#enableAutoLinking = options.enableAutoLinking !== false;
|
this.#enableAutoLinking = options.enableAutoLinking !== false;
|
||||||
|
this.#minDurationToUpdateCanvas = options.minDurationToUpdateCanvas ?? 500;
|
||||||
|
|
||||||
this.defaultRenderingQueue = !options.renderingQueue;
|
this.defaultRenderingQueue = !options.renderingQueue;
|
||||||
if (
|
if (
|
||||||
@ -1003,6 +1008,7 @@ class PDFViewer {
|
|||||||
layerProperties: this._layerProperties,
|
layerProperties: this._layerProperties,
|
||||||
enableHWA: this.#enableHWA,
|
enableHWA: this.#enableHWA,
|
||||||
enableAutoLinking: this.#enableAutoLinking,
|
enableAutoLinking: this.#enableAutoLinking,
|
||||||
|
minDurationToUpdateCanvas: this.#minDurationToUpdateCanvas,
|
||||||
});
|
});
|
||||||
this._pages.push(pageView);
|
this._pages.push(pageView);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user