ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
reflow_layout_driver.c File Reference

Token-stream driver + public lifecycle API for the reflow engine. More...

#include <stddef.h>
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_err.h"
#include "ra8_stbtt_guard.h"
#include "reflow.h"
#include "reflow_internal.h"
#include "reflow_layout_internal.h"
#include "stb_truetype.h"
Include dependency graph for reflow_layout_driver.c:

Go to the source code of this file.

Functions

static ra8_err_t internal_layout_tokens (reflow_t *engine, const stbtt_fontinfo *font)
 Run one pass over the token stream populating engine->glyphs[] and engine->pages[].
ra8_err_t reflow_run_layout (reflow_t *engine)
 Run the line-break + page-break pass over engine->tokens[].
ra8_err_t reflow_init (uint16_t viewport_w, uint16_t viewport_h, const uint8_t *font_data, size_t font_len, uint16_t font_px, uint32_t body_color, uint32_t link_color, reflow_t *out_engine)
 Initialise a reflow engine for a given viewport / font.
ra8_err_t reflow_close (reflow_t *engine)
 Release a previously initialized engine.
ra8_err_t reflow_set_image_loader (reflow_t *engine, reflow_image_loader_fn loader, void *ctx, ra8_img_arena_t *arena)
 Bind an <img> byte loader + decode arena to enable image rendering.
ra8_err_t reflow_set_css_loader (reflow_t *engine, reflow_css_loader_fn loader, void *ctx)
 Bind the external-stylesheet loader for <link rel="stylesheet">.
ra8_err_t reflow_layout_chapter (reflow_t *engine, const uint8_t *xhtml_buf, size_t xhtml_len, uint32_t *out_total_pages)
 Parse + lay out one chapter of XHTML.
ra8_err_t reflow_get_page_count (const reflow_t *engine, uint32_t *out_count)
 Report the laid-out page count.
ra8_err_t reflow_set_font_size (reflow_t *engine, uint16_t new_font_px)
 Change the body font size and re-flow the cached chapter.
ra8_err_t reflow_bind_font (reflow_t *engine, const uint8_t *font_data, size_t font_len)
 Implementation of reflow_bind_font() – validate then swap.
ra8_err_t reflow_register_face (reflow_t *engine, uint8_t css_face_idx, const uint8_t *blob, size_t len)
 Implementation of reflow_register_face() – validate then append.

Detailed Description

Token-stream driver + public lifecycle API for the reflow engine.

Splits the outer layout driver and the public entry points out of reflow_layout.c so each translation unit stays under the project file-size cap. The driver (internal_layout_tokens) walks the parsed token stream once, dispatching <table> ranges to priv_reflow_layout_table and every other token to priv_reflow_layout_apply_token, then flushes a final page and builds the tappable link rectangles.

The public API covers engine lifecycle (reflow_init, reflow_close), loader binding (image / CSS), chapter dispatch (reflow_layout_chapter, reflow_set_font_size), font (re)binding, and face registration.

[Ring 4 / Reflow] {World: NS}

Since
0.1.0

Definition in file reflow_layout_driver.c.

Function Documentation

◆ internal_layout_tokens()

ra8_err_t internal_layout_tokens ( reflow_t * engine,
const stbtt_fontinfo * font )
static

Run one pass over the token stream populating engine->glyphs[] and engine->pages[].

See implementation.

Parameters
[in]engineSee implementation.
[in]fontSee implementation.
Returns
Result code.
Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 54 of file reflow_layout_driver.c.

References reflow_t::font_px, reflow_t::glyph_count, reflow_t::image_box_count, k_ra8_err_no_mem, k_ra8_ok, k_reflow_align_left, k_reflow_margin_px, k_reflow_style_normal, k_reflow_tag_table, k_reflow_tok_block_start, reflow_token_t::kind, priv_cursor_t::page_first_glyph, priv_cursor_t::page_first_image, priv_reflow_layout_apply_token(), priv_reflow_layout_finish_page(), priv_reflow_layout_line_height(), priv_reflow_layout_table(), reflow_token_t::tag, and reflow_t::tokens.

Referenced by reflow_run_layout().

◆ reflow_bind_font()

ra8_err_t reflow_bind_font ( reflow_t * engine,
const uint8_t * font_data,
size_t font_len )
nodiscard

◆ reflow_close()

ra8_err_t reflow_close ( reflow_t * engine)
nodiscard

Release a previously initialized engine.

Parameters
[in,out]engineEngine returned by reflow_init().
Returns
ra8_err_t
Return values
k_ra8_okClosed.
k_ra8_err_null_ptrengine is NULL.
k_ra8_err_not_initializedengine->in_use == 0.
Precondition
engine non-NULL.
engine->in_use == 1.
Postcondition
engine->in_use == 0.
engine->page_count == 0.
Since
0.1.0

Definition at line 184 of file reflow_layout_driver.c.

◆ reflow_get_page_count()

ra8_err_t reflow_get_page_count ( const reflow_t * engine,
uint32_t * out_count )
nodiscard

Report the laid-out page count.

Parameters
[in]engineLaid-out engine.
[out]out_countPage count (0 if no chapter laid out yet).
Returns
ra8_err_t
Return values
k_ra8_okReported.
k_ra8_err_null_ptrAny pointer is NULL.
k_ra8_err_not_initializedengine->in_use == 0.
Since
0.1.0

Definition at line 267 of file reflow_layout_driver.c.

◆ reflow_init()

ra8_err_t reflow_init ( uint16_t viewport_w,
uint16_t viewport_h,
const uint8_t * font_data,
size_t font_len,
uint16_t font_px,
uint32_t body_color,
uint32_t link_color,
reflow_t * out_engine )
nodiscard

Initialise a reflow engine for a given viewport / font.

Records the viewport size, font handle and colour palette into the engine handle and clears the cached chapter / glyph / page state.

Parameters
[in]viewport_wViewport width, pixels (1..4096).
[in]viewport_hViewport height, pixels (1..4096).
[in]font_dataTTF blob; must outlive the engine.
[in]font_lenLength of font_data, bytes (>= 16).
[in]font_pxInitial font size, pixels (k_reflow_min_font_px .. k_reflow_max_font_px).
[in]body_colorBody text colour (0xRRGGBB).
[in]link_colorAnchor colour (0xRRGGBB).
[out]out_engineEngine handle to populate.
Returns
ra8_err_t
Return values
k_ra8_okInitialized.
k_ra8_err_null_ptrfont_data or out_engine is NULL.
k_ra8_err_invalid_argViewport or font size out of range.
k_ra8_err_invalid_sizefont_len too small.
Precondition
font_data non-NULL, out_engine non-NULL.
Viewport and font size in their documented ranges.
Postcondition
On success, out_engine->in_use == 1 and out_engine->page_count == 0.
On failure, *out_engine is zero-initialized.
Note
Not thread-safe. Single-threaded init context.
See also
reflow_close()
Since
0.1.0

Definition at line 149 of file reflow_layout_driver.c.

◆ reflow_layout_chapter()

ra8_err_t reflow_layout_chapter ( reflow_t * engine,
const uint8_t * xhtml_buf,
size_t xhtml_len,
uint32_t * out_total_pages )
nodiscard

Parse + lay out one chapter of XHTML.

Walks the XHTML once with the no-heap streaming tokenizer, emits a token stream, then runs the greedy line-break + page-break engine to produce a flat list of positioned glyphs grouped by page. The engine caches the input buffer so reflow_set_font_size() can re-flow without the caller re-supplying it.

Algorithm summary:

  1. Tokenize the XHTML in a single no-heap forward pass, emitting tokens (block_start / text / break / ...).
  2. For each token, if it is a text run, walk word-by-word.
  3. Measure word_width = sum(stbtt advance per glyph).
  4. If cursor_x + word_width > viewport_w - margins then break to a new line.
  5. If cursor_y + line_height > viewport_h - margins then start a new page.
  6. After all tokens, record page_count.
Parameters
[in,out]engineInitialized engine handle.
[in]xhtml_bufUTF-8 / ASCII XHTML source bytes.
[in]xhtml_lenLength of xhtml_buf, bytes (>0).
[out]out_total_pagesTotal page count (>= 1 on success).
Returns
ra8_err_t
Return values
k_ra8_okLaid out.
k_ra8_err_null_ptrAny required pointer is NULL.
k_ra8_err_not_initializedengine->in_use == 0.
k_ra8_err_invalid_sizexhtml_len == 0.
k_ra8_err_validation_failedXHTML did not parse.
k_ra8_err_no_memToken / glyph / page pool full.
Precondition
engine, xhtml_buf, out_total_pages non-NULL.
engine->in_use == 1.
Postcondition
On success, *out_total_pages == engine->page_count >= 1.
Since
0.1.0

Definition at line 233 of file reflow_layout_driver.c.

Referenced by reflow_bind_font(), and reflow_set_font_size().

◆ reflow_register_face()

ra8_err_t reflow_register_face ( reflow_t * engine,
uint8_t css_face_idx,
const uint8_t * blob,
size_t len )
nodiscard

◆ reflow_run_layout()

ra8_err_t reflow_run_layout ( reflow_t * engine)
nodiscard

Run the line-break + page-break pass over engine->tokens[].

Internal helper. Consumes the token stream populated by reflow_parse_xhtml() and writes positioned glyphs into engine->glyphs[] plus page index ranges into engine->pages[].

Parameters
[in,out]engineEngine in in_use == 1 state with a populated token stream.
Returns
ra8_err_t
Return values
k_ra8_okLayout complete.
k_ra8_err_no_memGlyph or page pool full.
Since
0.1.0

Definition at line 105 of file reflow_layout_driver.c.

Referenced by reflow_layout_chapter().

◆ reflow_set_css_loader()

ra8_err_t reflow_set_css_loader ( reflow_t * engine,
reflow_css_loader_fn loader,
void * ctx )
nodiscard

Bind the external-stylesheet loader for <link rel="stylesheet">.

Mirrors reflow_set_image_loader(). When bound, reflow_layout_chapter() resolves each <link rel="stylesheet" href> in the chapter via loader and parses the returned CSS into the chapter sheet in document order (so a later inline <style> / style= overrides it). NULL loader disables the feature (chapters parse only their inline CSS, exactly as before).

Parameters
[in,out]engineEngine to bind.
[in]loaderStylesheet byte loader, or NULL to disable.
[in]ctxOpaque context handed back to loader.
Returns
ra8_err_t Error code.
Return values
k_ra8_okBinding recorded.
k_ra8_err_null_ptrengine is NULL.
k_ra8_err_not_initializedengine->in_use == 0.
Precondition
engine is non-NULL and initialized.
Postcondition
On success the engine uses (loader, ctx) for <link> stylesheets.
Binding takes effect on the next reflow_layout_chapter().
Note
Not thread-safe; bind before laying out.
Since
0.1.0

Definition at line 220 of file reflow_layout_driver.c.

References reflow_t::css_loader, reflow_t::css_loader_ctx, reflow_t::in_use, k_ra8_err_not_initialized, k_ra8_err_null_ptr, and k_ra8_ok.

◆ reflow_set_font_size()

ra8_err_t reflow_set_font_size ( reflow_t * engine,
uint16_t new_font_px )
nodiscard

Change the body font size and re-flow the cached chapter.

Re-runs the line-break + page-break engine against the most recent chapter handed to reflow_layout_chapter(). Glyph and page state are rebuilt from scratch; the previous page count and page-glyph ranges are invalidated.

Parameters
[in,out]engineInitialized + laid-out engine.
[in]new_font_pxNew body font size, pixels (k_reflow_min_font_px .. k_reflow_max_font_px).
Returns
ra8_err_t
Return values
k_ra8_okRe-flowed.
k_ra8_err_null_ptrengine is NULL.
k_ra8_err_not_initializedengine->in_use == 0.
k_ra8_err_invalid_stateNo chapter cached yet.
k_ra8_err_invalid_argnew_font_px out of range.
Since
0.1.0

Definition at line 279 of file reflow_layout_driver.c.

◆ reflow_set_image_loader()

ra8_err_t reflow_set_image_loader ( reflow_t * engine,
reflow_image_loader_fn loader,
void * ctx,
ra8_img_arena_t * arena )
nodiscard

Bind an <img> byte loader + decode arena to enable image rendering.

Without this binding (the default), <img> elements reserve a small placeholder advance and draw nothing – the historical v1 behaviour, kept so image-free content lays out byte-identically. Once a loader + arena are bound, the layout pass resolves each <img src> to its intrinsic size, reserves a scaled block (text flows below), and the render pass decodes + blits the image on demand. Pass loader == NULL or arena == NULL to disable again.

Parameters
[in,out]engineInitialized engine handle.
[in]loaderResolves an href to encoded image bytes (NULL = off).
[in]ctxOpaque context handed back to loader.
[in]arenaCaller-owned decode scratch (NULL = off); sized for the largest image (a few KiB SRAM .. a few MiB SDRAM).
Returns
ra8_err_t
Return values
k_ra8_okBinding recorded.
k_ra8_err_null_ptrengine is NULL.
k_ra8_err_not_initializedengine->in_use == 0.
Precondition
engine is non-NULL and initialized.
If non-NULL, arena->base addresses arena->cap writable bytes.
Postcondition
On success the engine uses (loader, ctx, arena) for <img>.
Binding takes effect on the next reflow_layout_chapter() / re-flow.
Note
Not thread-safe; bind before laying out.
Since
0.1.0

Definition at line 203 of file reflow_layout_driver.c.

References reflow_t::img_arena, reflow_t::img_loader, reflow_t::img_loader_ctx, reflow_t::in_use, k_ra8_err_not_initialized, k_ra8_err_null_ptr, and k_ra8_ok.

Referenced by er_reflow_relayout().