Skip to content

Fix/epub reader layout reflow - #402

Open
JimmyJi0309 wants to merge 4 commits into
van-geaux:mainfrom
JimmyJi0309:fix/epub-reader-layout-reflow
Open

JimmyJi0309 wants to merge 4 commits into
van-geaux:mainfrom
JimmyJi0309:fix/epub-reader-layout-reflow

Conversation

@JimmyJi0309

Copy link
Copy Markdown
Contributor

Summary

Fix two independent EPUB-reader problems reported on a phone:

  1. A full-width illustration was split across two pages, with a narrow image strip or 1px vertical line left at the page edge.
  2. Changing typography caused a temporary layout error until the book was closed and reopened.

The tablet rendering was unaffected.

Cause

Illustration split

A reflowable EPUB with a large inline illustration (roughly 1026 × 1465, plain <p><img> with no publisher CSS, float, or fixed dimensions) exposed the issue. On the narrower phone page, the image was laid out wider than one rendered page/column and Readium split it across pages. The first normalizer attempt also ran before the WebView had a measurable width and could compute a 1px image width, producing a stray vertical edge line.

Typography layout

Readium applies typography through a live submitPreferences CSS reflow, but its pagination is index-based. After a large reflow it keeps the old page index instead of re-anchoring the locator, so the visible page is temporarily wrong. Reopening recreates the navigator and paginates once from the saved locator, which is why close/reopen fixed it.

A separate EPUB defect was also fixed: unlike the PDF and comic readers, the EPUB reader did not reserve space for the optional title/author header, so the header could overlay content.

Changes

  • Add epubLayoutChangeRequiresRelayout(...) covering font size/family, spacing, alignment, hyphenation, page padding, header visibility, progress-footer visibility and layout mode. Reading-direction-only changes are excluded because EPUB reading progression is fixed to LTR.
  • When such a change is made from the reader options sheet, mark a relayout pending. On closing the sheet, recreate the reader once so Readium applies the final pagination from its restored locator instead of keeping the stale live offset.
  • Keep the pending relayout from recreating while chrome is being shown; only an actual options-sheet close triggers the one-pass reopen.
  • Reserve the header top padding in the EPUB applyReaderPadding() path using the same readerHeaderReservedTopSpace(...) helper as PDF/comic, and re-apply padding after header/inset changes.
  • Add a large-media normalizer to each EPUB document: images/SVGs larger than 512px are capped to one rendered page/column width and height, centered, and re-run on load/resize. Small inline icons are left alone.
  • Wait for a measurable WebView width and leave an 8px edge gap before normalizing, preventing a 1px image edge from becoming a vertical line at the page margin.
  • Add a JVM regression test for the relayout predicate.

Verification

  • Real phone Huawei ELS-AN00, debug build: illustration no longer splits across pages; the 1px edge line is gone; typography layout stays correct after changing settings and closing the options sheet.
  • API 35 phone emulator: the same structure renders with the illustration on one page in portrait and landscape.
  • Tested locally with a reflowable EPUB containing a large inline <p><img> (about 1026×1465) and no image CSS; the fixture is not attached to keep the PR small.
  • JVM: 1,335 tests, 0 failures
  • lint: 0 errors
  • ./gradlew testDebugUnitTest lintDebug assembleDebug assembleDebugAndroidTest — passed
  • No changes to Readium's publisherStyles, shouldApplyInsetsPadding, or the legacy WebView reader path.

Notes

The EPUB fixes are independent of the reader-settings feature branch. The typography fix intentionally recreates once when the options sheet is closed; changing typography and continuing to read with the sheet open may still show the live reflow until the sheet is dismissed.

Close #401

- Recreate the EPUB reader once after layout-critical reader settings are changed
  and the options sheet is closed, avoiding a stale Readium page offset.
- Reserve the optional title/author header space in the EPUB reader padding path,
  matching the PDF and comic readers.
- Add a JVM test for the layout-change predicate.
Address review follow-ups: include header/progress padding changes in the
relayout predicate, recompute padding when header insets change, skip recreation
while showing chrome, and avoid recreating for reading-direction-only changes.
The supplied EPUB has a 1026x1465 inline image that can be laid out at its
intrinsic width and split across two phone pages. Normalize large images/SVGs
to the current page/column width and height after load/resize, leaving small
icons alone.
Do not normalize images until the WebView has a measurable column width, and
leave an 8px edge gap so a rounded image width cannot paint a stray vertical
line at the page edge.
@RobinD42

RobinD42 commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

The layout reflow issue was on my list too. 😄

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.

Bug&Fix: EPUB illustrations split across pages and typography changes leave a stale layout on phones

2 participants