Skip to content

fix: render real-size partial images at the document-to-pixel scale - #702

Merged
espresso3389 merged 1 commit into
espresso3389:masterfrom
palmoni5:fix-partial-render-scale-custom-layout
Sep 2, 2026
Merged

fix: render real-size partial images at the document-to-pixel scale#702
espresso3389 merged 1 commit into
espresso3389:masterfrom
palmoni5:fix-partial-render-scale-custom-layout

Conversation

@palmoni5

@palmoni5 palmoni5 commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Problem

A custom layoutPages that does not lay pages out at their natural point size gets a permanently blurry page when the user zooms in — the high-resolution partial render never reaches the resolution the viewer is actually displaying, and zooming further does not help.

Cause

In _paintPagesCustom:

final pageScale = scale * max(rect.width / page.width, rect.height / page.height);
if (!enableLowResolutionPagePreview || pageScale > previewScaleLimit) {
  _requestRealSizePartialImage(cache, page, pageScale, targetRect);
}

scale is _currentZoom * devicePixelRatio — the document-units-to-physical-pixels factor. pageScale multiplies it by the layout ratio r = pageRect.size / page.size, which is the right quantity for the previewScaleLimit comparison, because previewScaleLimit is a page-points-to-pixels density (the preview is rendered as page.width * previewScaleLimit).

But _createRealSizePartialImage then uses the value it receives as a document-to-pixel factor again:

final width = (inPageRect.width * scale).toInt();   // inPageRect is in document units
fullWidth: pageRect.width * scale                   // pageRect is in document units

So r is counted twice:

needed:   pageRect.width * zoom * dpr
rendered: pageRect.width * (zoom * dpr * r)

With the built-in layouts r == 1, so the two are equal and nothing is wrong — which is why this only shows up with a custom layoutPages. With r = 0.5 (a two-page book-style spread laid out at half size, which is how I hit this) the partial image is rendered at half the required resolution and is upscaled 2x on screen. The error is proportional, so it never improves with more zoom.

Fix

Pass scale rather than pageScale to _requestRealSizePartialImage. The threshold comparison keeps using pageScale, which is correct there.

This is a no-op for every layout with r == 1, i.e. all built-in layouts.

Testing

To be explicit about what I have and have not checked: the analysis above is derived from reading the code, and I have not yet run a visual before/after in a built app. What I can state is that the change is provably a no-op wherever r == 1 (pageScale and scale are equal there by definition), which covers every built-in layout, so the risk to existing users is nil.

Happy to add a regression test if you can point me at where you would want it — the value is computed inside a private paint method, so I did not see an obvious seam in packages/pdfrx/test.

`_requestRealSizePartialImage` was called with `pageScale`, which is
`scale * (pageRect.size / page.size)`. Inside
`_createRealSizePartialImage` that value is used as a document-to-pixel
factor again (`fullWidth: pageRect.width * scale`), so the layout ratio
is counted twice.

With the default layouts the ratio is 1 and the two are identical, so
nothing changes. With a custom `layoutPages` that lays pages out at a
size other than their natural one, the high-resolution partial image is
rendered at `ratio` times the resolution the viewer actually needs, and
the page stays blurry no matter how far the user zooms in.

Pass `scale` instead: it is the document-to-physical-pixel factor the
partial renderer expects. The `pageScale > previewScaleLimit` threshold
keeps using `pageScale`, which is correct there -- it compares a
page-points-to-pixels density against the preview render scale.
@palmoni5
palmoni5 force-pushed the fix-partial-render-scale-custom-layout branch from 7ef4c93 to 2379b99 Compare August 30, 2026 09:31
@espresso3389
espresso3389 merged commit 0c795c3 into espresso3389:master Sep 2, 2026
12 checks passed
@palmoni5
palmoni5 deleted the fix-partial-render-scale-custom-layout branch September 2, 2026 13:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants