Skip to content

Commit

Permalink
Respect maxCanvasPixels when computing canvas dimensions
Browse files Browse the repository at this point in the history
Ensure that we never round the canvas dimensions above `maxCanvasPixels`
by rounding them to the preceeding multiple of the display ratio rather
than the succeeding one.
  • Loading branch information
nicolo-ribaudo committed Jun 19, 2024
1 parent 12692d2 commit de23bb9
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 15 deletions.
13 changes: 7 additions & 6 deletions test/integration/viewer_spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -279,12 +279,13 @@ describe("PDF viewer", () => {
.withContext(`In ${browserName}`)
.toBeLessThan(originalCanvasSize * factor ** 2);

// Disabled because `canvasSize` is `4_012_800`, which is
// close to the limit but somehow a bit more.
//
// expect(canvasSize)
// .withContext(`In ${browserName}, MAX_CANVAS_PIXELS`)
// .toBeLessThan(MAX_CANVAS_PIXELS.get(browserName));
expect(canvasSize)
.withContext(`In ${browserName}, <= MAX_CANVAS_PIXELS`)
.toBeLessThanOrEqual(MAX_CANVAS_PIXELS.get(browserName));

expect(canvasSize)
.withContext(`In ${browserName}, > MAX_CANVAS_PIXELS * 0.99`)
.toBeGreaterThan(MAX_CANVAS_PIXELS.get(browserName) * 0.99);
})
);
});
Expand Down
10 changes: 5 additions & 5 deletions web/pdf_page_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ import {
import {
approximateFraction,
DEFAULT_SCALE,
floorToDivide,
OutputScale,
RenderingStates,
roundToDivide,
TextLayerMode,
} from "./ui_utils.js";
import { AnnotationEditorLayerBuilder } from "./annotation_editor_layer_builder.js";
Expand Down Expand Up @@ -1025,11 +1025,11 @@ class PDFPageView {
const sfx = approximateFraction(outputScale.sx);
const sfy = approximateFraction(outputScale.sy);

canvas.width = roundToDivide(width * outputScale.sx, sfx[0]);
canvas.height = roundToDivide(height * outputScale.sy, sfy[0]);
canvas.width = floorToDivide(width * outputScale.sx, sfx[0]);
canvas.height = floorToDivide(height * outputScale.sy, sfy[0]);
const { style } = canvas;
style.width = roundToDivide(width, sfx[1]) + "px";
style.height = roundToDivide(height, sfy[1]) + "px";
style.width = floorToDivide(width, sfx[1]) + "px";
style.height = floorToDivide(height, sfy[1]) + "px";

// Add the viewport so it's known what it was originally drawn with.
this.#viewportMap.set(canvas, viewport);
Expand Down
12 changes: 8 additions & 4 deletions web/ui_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ function binarySearchFirstItem(items, condition, start = 0) {
* @param {number} x - Positive float number.
* @returns {Array} Estimated fraction: the first array item is a numerator,
* the second one is a denominator.
* They are both natural numbers.
*/
function approximateFraction(x) {
// Fast paths for int numbers or their inversions.
Expand Down Expand Up @@ -306,9 +307,12 @@ function approximateFraction(x) {
return result;
}

function roundToDivide(x, div) {
const r = x % div;
return r === 0 ? x : Math.round(x - r + div);
/**
* @param {number} x - A positive number to round to a multiple of `div`.
* @param {number} div - A natural number.
*/
function floorToDivide(x, div) {
return x - (x % div);
}

/**
Expand Down Expand Up @@ -863,6 +867,7 @@ export {
DEFAULT_SCALE_DELTA,
DEFAULT_SCALE_VALUE,
docStyle,
floorToDivide,
getActiveOrFocusedElement,
getPageSizeInches,
getVisibleElements,
Expand All @@ -881,7 +886,6 @@ export {
ProgressBar,
removeNullCharacters,
RenderingStates,
roundToDivide,
SCROLLBAR_PADDING,
scrollIntoView,
ScrollMode,
Expand Down

0 comments on commit de23bb9

Please sign in to comment.