HTML / CSS reflow + paginate engine for the ra8d2 ereader.
reflow is a small, hand-written HTML reflow + pagination engine sitting between apps/shared_libs/epub (which produces per-chapter XHTML byte streams) and libs/ra8_gfx (which owns the framebuffer). It is the page-layout core of the ereader application.
The engine is intentionally bare-metal friendly:
- Zero dynamic allocation. Every buffer is statically sized via a reflow_limits_t enum and lives inside the engine handle.
- Greedy line-break. Walks each text run word-by-word measuring glyph widths via stb_truetype; when adding the next word would exceed viewport_w - 2 * k_reflow_margin_px, the engine breaks and starts a new line.
- Page-break-on-overflow. When the accumulated line height would exceed viewport_h - 2 * k_reflow_margin_px, the engine starts a new page.
- Caller-owned framebuffer. Rendering blits each glyph via ra8_gfx_pixel() so the same engine works on the GLCDC plane, an off-screen scratch buffer, or a host-test buffer.
Supported HTML subset (v1)
- Block-flow tags: <p>, <h1> .. <h6>, <blockquote>, <ul>, <ol>, <li>, <hr>.
- Tables: <table> / <tr> / <td> / <th> – an equal-column grid with per-cell text flow and row-level page breaks (#107).
- Inline tags: <em>, <strong>, <b>, <i>, <a>, <br>. <a href> links are hit-testable and followable (#110).
- Replaced elements: <img> – decoded + scaled + blitted when an image loader is bound, else a placeholder (#106).
- Alignment: text-align (left / right / centre / justify) from an inline style on a block (#108).
- Everything else (the rest of CSS, scripts, <div>, <span>) is treated as a transparent flow-pass-through; child content is still laid out, the wrapping element itself contributes no styling.
Lifecycle
- reflow_init() – bind viewport, font, colours.
- reflow_layout_chapter() – parse + lay out one XHTML chapter, return total page count.
- reflow_render_page() – rasterise page N into the active ra8_gfx framebuffer.
- (optional) reflow_set_font_size() – triggers a re-flow on the cached chapter.
- reflow_close() – mark engine unused.
- Note
- This is a thin umbrella header. The data model (enums, structs, the engine handle) lives in reflow_types.h, and the callable function prototypes live in reflow_api.h. Consumers should continue to include reflow.h directly – it pulls in both sub-headers so the public surface is unchanged.
[Ring 4 / Reflow] {World: NS}
- Copyright
- Copyright (c) 2026 Brighton Sikarskie SPDX-License-Identifier: MIT
- Since
- 0.1.0
Definition in file reflow.h.