Skip to content

feat(engines): page composer for the layout engine - #840

Merged
KnifeLemon merged 1 commit into
builtin-enginesfrom
engine/page-composer
Oct 30, 2026
Merged

KnifeLemon merged 1 commit into
builtin-enginesfrom
engine/page-composer

Conversation

@KnifeLemon

Copy link
Copy Markdown
Owner

What does this change?

Implements the Project 4 item "Layout engine: page composer". It replaces the interim page flow from #834.

Stacked on #839 (stored line layout). The base is engine/stored-lines; it moves to builtin-engines once #839 is merged.

Page composer (Typesetting/PageComposer.cs)

  • Pages
    • Each section starts a page with its paper, margins and gutter.
    • The body runs from the top margin and header area down to the footer area.
    • A page break before a paragraph starts a page. So does a column break, but only in a one-column section; columns are a later item.
  • Keep rules
    • Keep lines together.
    • Keep with next: the paragraph and the next one's first line start on one page.
    • Widow and orphan control: two lines on either page.
    • None of them moves anything off an empty page.
  • 한글's stored layout (feat(engines): follow 한글's stored line layout where it can be used #839)
    • Lines on their stored layout take 한글's page breaks (the stored first-line-of-page flag).
    • They also take their stored place on the page, while the page so far follows it.
    • A paragraph Filee broke again, or a table, ends that until 한글's next page.
  • Headers and footers
    • For both pages, odd pages or even pages, chosen by page number.
    • None on a section's first page where the section hides them.
    • Laid out in the header and footer areas.
  • Page numbers
    • Numbers count on across sections, or restart where a section says.
    • Page number fields show their page's number.
    • Total pages fields show the count; a first pass finds it when the body has one.
  • Pictures laid out like characters (no anchor)
    • Their size is their own, else their pixels at 96 dpi.
    • They stand on the baseline and are drawn with their crop.
    • The HWPX reader counts them in the converted line starts.
  • Other formats (TXT, Markdown, HTML, EPUB, FB2, MOBI, DOCX …) leave formats to the 한글 style. With a StyleResolver, every paragraph and run is resolved before layout, as the HWPX writer would write it.
  • Links, bookmarks and the heading outline carry over from the paragraph layout.

Tables are still stacked cell by cell (the tables item). Columns, notes, floating objects and master pages are separate items too.

Acceptance

Tests

PageComposerTests covers:

  • page geometry;
  • flowing onto pages within the body;
  • page and column breaks;
  • keep with next, keep lines together, widow and orphan control;
  • odd, even and hidden-first headers and footers with page and total-page fields;
  • page numbers across sections with a restart;
  • a total pages field in the body;
  • inline pictures;
  • 한글's stored page starts and places;
  • the six other formats;
  • the 640-page novel.

RepositoryFonts (the pinned Noto fonts as a font collection) moves out of ParagraphLayoutTests so both test classes share it. Engines suite locally: 2326 passed, 0 failed.

🤖 Generated with Claude Code

…ooters, page numbers, inline pictures

Replaces the interim page flow. Sections' paper, margins and gutter; page and column breaks; keep lines together,
keep with next, widow and orphan control; 한글's stored page breaks and places while the page follows them; headers
and footers for both, odd and even pages and a hidden first page; page numbers across sections and restarts, page
number and total pages fields (a first pass for the body's total); pictures laid out like characters; formats of other
documents resolved through the 한글 style first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@KnifeLemon KnifeLemon added the built-in engines Filee: built-in engines (Project 4), on the builtin-engines branch, not released yet label Oct 30, 2026
@github-actions github-actions Bot added the feature New features label Oct 30, 2026
@KnifeLemon
KnifeLemon changed the base branch from engine/stored-lines to builtin-engines October 30, 2026 16:01
@KnifeLemon
KnifeLemon merged commit cd4129a into builtin-engines Oct 30, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

built-in engines Filee: built-in engines (Project 4), on the builtin-engines branch, not released yet feature New features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant