Skip to content

Commit

Permalink
Render high-res partial page views when falling back to CSS zoom
Browse files Browse the repository at this point in the history
When rendering big PDF pages at high zoom levels, we currently fall back
to CSS zoom to avoid rendering canvases with too many pixels. This
causes zoomed in PDF to look blurry, and the text to be potentially
unreadable.

This commit adds support for rendering _part_ of a page (called
`PDFPageDetailView` in the code), so that we can render portion of a
page in a smaller canvas without hiting the maximun canvas size limit.

Specifically, we render an area of that page that is slightly larger
than the area that is visible on the screen (100% larger in each
direction, unless we have to limit it due to the maximum canvas size).
As the user scrolls around the page, we re-render a new area centered
around what is currently visible.
  • Loading branch information
nicolo-ribaudo committed Dec 9, 2024
1 parent 5dc2d25 commit f68dd33
Show file tree
Hide file tree
Showing 6 changed files with 538 additions and 220 deletions.
22 changes: 16 additions & 6 deletions test/unit/ui_utils_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,25 +279,35 @@ describe("ui_utils", function () {
viewTop < scrollBottom &&
viewBottom > scrollTop
) {
const hiddenHeight =
Math.max(0, scrollTop - viewTop) +
Math.max(0, viewBottom - scrollBottom);
const hiddenWidth =
Math.max(0, scrollLeft - viewLeft) +
Math.max(0, viewRight - scrollRight);
const minY = Math.max(0, scrollTop - viewTop);
const minX = Math.max(0, scrollLeft - viewLeft);

const hiddenHeight = minY + Math.max(0, viewBottom - scrollBottom);
const hiddenWidth = minX + Math.max(0, viewRight - scrollRight);

const fractionHeight =
(div.clientHeight - hiddenHeight) / div.clientHeight;
const fractionWidth =
(div.clientWidth - hiddenWidth) / div.clientWidth;
const percent = (fractionHeight * fractionWidth * 100) | 0;

let visibleArea = null;
if (percent < 100) {
visibleArea = {
minX,
minY,
maxX: Math.min(viewRight, scrollRight) - viewLeft,
maxY: Math.min(viewBottom, scrollBottom) - viewTop,
};
}

views.push({
id: view.id,
x: viewLeft,
y: viewTop,
view,
percent,
visibleArea,
widthPercent: (fractionWidth * 100) | 0,
});
ids.add(view.id);
Expand Down
8 changes: 4 additions & 4 deletions web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2280,18 +2280,18 @@ if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
};
}

function onPageRender({ pageNumber }) {
function onPageRender({ pageNumber, source }) {
// If the page is (the most) visible when it starts rendering,
// ensure that the page number input loading indicator is displayed.
if (pageNumber === this.page) {
if (pageNumber === this.page && !source.detailView) {
this.toolbar?.updateLoadingIndicatorState(true);
}
}

function onPageRendered({ pageNumber, error }) {
function onPageRendered({ pageNumber, source, error }) {
// If the page is still visible when it has finished rendering,
// ensure that the page number input loading indicator is hidden.
if (pageNumber === this.page) {
if (pageNumber === this.page && !source.detailView) {
this.toolbar?.updateLoadingIndicatorState(false);
}

Expand Down
Loading

0 comments on commit f68dd33

Please sign in to comment.