Expand description
§Page-Aware Layout Engine
This is the heart of Forme and the reason it exists.
§The Problem With Every Other Engine
Most PDF renderers do this:
- Lay out all content on an infinitely tall canvas
- Slice the canvas into pages
- Try to fix the things that broke at slice points
Step 3 is where everything falls apart. Flexbox layouts collapse because the flex algorithm ran on the pre-sliced dimensions. Table rows get split in the wrong places. Headers don’t repeat. Content gets “mashed together.”
§How Forme Works
Forme never creates an infinite canvas. The layout algorithm is:
- Open a page with known dimensions and remaining space
- Place each child node. Before placing, ask: “does this fit?”
- If it fits: place it, reduce remaining space
- If it doesn’t fit and is unbreakable: start a new page, place it there
- If it doesn’t fit and is breakable: place what fits, split the rest to a new page, and RE-RUN flex layout on both fragments
- For tables: when splitting, clone the header rows onto the new page
The key insight in step 5: when a flex container splits across pages, BOTH fragments get their own independent flex layout pass. This is why react-pdf’s flex breaks on page wrap — it runs flex once on the whole container and then slices, so the flex calculations are wrong on both halves. We run flex AFTER splitting.
Modules§
- flex
- Flex Layout Utilities
- grid
- CSS Grid Layout
- page_
break - Page Break Decisions
Structs§
- Bookmark
Entry - A bookmark entry collected during layout.
- Element
Info - Layout metadata for a single positioned element (hierarchical).
- Element
Style Info - Serializable snapshot of ResolvedStyle for the inspector panel.
- Layout
Element - A positioned element on a page.
- Layout
Engine - The main layout engine.
- Layout
Info - Complete layout metadata for all pages.
- Layout
Page - A fully laid-out page ready for PDF serialization.
- Page
Info - Layout metadata for a single page.
- Positioned
Glyph - Text
Line
Enums§
- Draw
Command - What to actually draw for this element.