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

Cross-TU shared declarations for the reflow layout engine. More...

#include <stddef.h>
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_err.h"
#include "reflow.h"
#include "reflow_internal.h"
#include "stb_truetype.h"
Include dependency graph for reflow_layout_internal.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  priv_cursor_t
 Mutable state carried through the layout loop. More...

Enumerations

enum  priv_layout_consts_t : uint16_t {
  k_priv_min_word_w_px = 1U ,
  k_priv_hr_thickness_px = 2U ,
  k_priv_image_placeholder_px = 32U ,
  k_priv_min_chapter_pages = 1U ,
  k_priv_cell_pad_px = 6U ,
  k_priv_row_gap_px = 4U
}
 Internal sizing knobs for the layout pass. More...

Functions

void priv_reflow_layout_byte_zero (uint8_t *dst, size_t n)
 Bounded zero-fill used in place of memset(0).
ra8_err_t priv_reflow_layout_init_font (const reflow_t *engine, stbtt_fontinfo *out_font)
 Initialise an stbtt_fontinfo from engine->font_data.
uint16_t priv_reflow_layout_line_height (uint16_t font_px)
 Compute the line height in pixels for a given font size.
int32_t priv_reflow_layout_glyph_advance (const stbtt_fontinfo *font, uint16_t font_px, int32_t cp)
 Measure a single ASCII code point's advance width in pixels.
bool priv_reflow_layout_push_glyph (reflow_t *engine, int32_t x, int32_t y, int32_t cp, uint16_t font_px, uint8_t style, uint32_t color, uint8_t link_id)
 Push one positioned glyph into the engine glyph pool.
bool priv_reflow_layout_finish_page (reflow_t *engine, priv_cursor_t *cur)
 Finalise the current page and start a new one.
bool priv_reflow_layout_newline (reflow_t *engine, priv_cursor_t *cur, bool allow_justify)
 Wrap to a new line, finishing a page if the bottom margin is hit.
ra8_err_t priv_reflow_layout_apply_token (reflow_t *engine, priv_cursor_t *cur, const stbtt_fontinfo *font, const reflow_token_t *tok)
 Dispatch one parsed token through the layout cursor.
void priv_reflow_layout_build_link_rects (reflow_t *engine, const stbtt_fontinfo *font)
 Post-layout pass: group link-tagged glyphs into tappable rects.
bool priv_reflow_layout_apply_image (reflow_t *engine, priv_cursor_t *cur, const reflow_token_t *tok)
 Apply an <img> token: real image when a loader is bound, else a placeholder.
ra8_err_t priv_reflow_layout_table (reflow_t *engine, priv_cursor_t *cur, const stbtt_fontinfo *font, uint32_t start, uint32_t *out_next)
 Lay out a <table> token range as an equal-column grid.

Detailed Description

Cross-TU shared declarations for the reflow layout engine.

The layout engine is split across three translation units so each stays under the project file-size cap:

  • reflow_layout.c – core line/page break + inline flow.
  • priv_reflow_layout_table.c<table> equal-column grid layout.
  • reflow_layout_driver.c – the token-stream driver + public API.

Any symbol referenced by more than one of those units lives here: the mutable layout cursor type, the internal sizing constants, and the handful of layout helpers that one unit calls across the file boundary. Symbols used by a single unit stay private (static) in that unit.

[Ring 4 / Reflow] {World: NS}

Since
0.1.0

Definition in file reflow_layout_internal.h.

Enumeration Type Documentation

◆ priv_layout_consts_t

enum priv_layout_consts_t : uint16_t

Internal sizing knobs for the layout pass.

Enumerator
k_priv_min_word_w_px 

Minimum word width before forcing a break.

k_priv_hr_thickness_px 

Pixel thickness of an <hr> (placeholder).

k_priv_image_placeholder_px 

Side length of <img> placeholder.

k_priv_min_chapter_pages 

Floor for non-empty input.

k_priv_cell_pad_px 

Left/right inset inside a table cell.

k_priv_row_gap_px 

Vertical gap between table rows.

Definition at line 47 of file reflow_layout_internal.h.

Function Documentation

◆ priv_reflow_layout_apply_image()

bool priv_reflow_layout_apply_image ( reflow_t * engine,
priv_cursor_t * cur,
const reflow_token_t * tok )

Apply an <img> token: real image when a loader is bound, else a placeholder.

Defined in reflow_layout_image.c. When the engine has a bound image loader + arena and the token carries a source slice, the image is sized to the text column, page-broken as a block, and recorded as an image box; any failure (full pool, unresolved src, flush overflow) falls back to the historic fixed-size placeholder advance so image-free content stays byte-identical.

Parameters
[in]engineSee implementation.
[in]curSee implementation.
[in]tokSee implementation.
Returns
Boolean.
Return values
trueToken applied (image placed or placeholder reserved).
falsePool overflow propagated from a sub-step.
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 270 of file reflow_layout_image.c.

References reflow_t::img_arena, reflow_t::img_loader, internal_apply_image_placeholder(), internal_place_image(), and reflow_token_t::text_len.

Referenced by priv_reflow_layout_apply_token().

◆ priv_reflow_layout_apply_token()

ra8_err_t priv_reflow_layout_apply_token ( reflow_t * engine,
priv_cursor_t * cur,
const stbtt_fontinfo * font,
const reflow_token_t * tok )

Dispatch one parsed token through the layout cursor.

Splits the per-token switch out of the layout driver to keep the outer loop under clang-tidy's cognitive-complexity threshold (Rule 4 / 25-statement budget).

Parameters
[in]engineSee implementation.
[in]curSee implementation.
[in]fontSee implementation.
[in]tokSee 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

Dispatch one parsed token through the layout cursor.

Definition at line 757 of file reflow_layout.c.

References priv_cursor_t::active_style, internal_apply_rule(), internal_close_block(), internal_layout_text(), internal_open_block(), k_ra8_err_no_mem, k_ra8_ok, k_reflow_face_mask, k_reflow_face_shift, k_reflow_tok_block_end, k_reflow_tok_block_start, k_reflow_tok_break, k_reflow_tok_image, k_reflow_tok_rule, k_reflow_tok_text, reflow_token_t::kind, priv_reflow_layout_apply_image(), priv_reflow_layout_newline(), reflow_token_t::reserved16, and reflow_token_t::style.

Referenced by internal_layout_tokens().

◆ priv_reflow_layout_build_link_rects()

void priv_reflow_layout_build_link_rects ( reflow_t * engine,
const stbtt_fontinfo * font )

Post-layout pass: group link-tagged glyphs into tappable rects.

Iterates over every page in engine->pages[]. For each page, walks the glyph run in order; when a glyph carries a non-zero reserved (link id) it scans forward to find the end of the consecutive same-link, same-baseline-y run, then emits a link rect for that span. A multi-line anchor link therefore produces one rect per wrapped line. Glyphs with reserved == 0 are skipped.

Parameters
[in,out]engineEngine holding laid-out glyphs and pages; its link-rect pool grows.
[in]fontFont metrics for last-glyph advance measurement.
Returns
Nothing.
Precondition
engine->pages[] and engine->glyphs[] are fully populated by the layout pass.
engine->link_rect_count == 0 on entry (reset by reflow_run_layout).
Postcondition
engine->link_rects[] contains page-local tappable rectangles for every link run found.
engine->link_rect_count reflects the total number of rects emitted.
Note
Not thread-safe; caller must serialize access to engine.
Since
0.1.0

Post-layout pass: group link-tagged glyphs into tappable rects.

Definition at line 732 of file reflow_layout.c.

References reflow_page_t::glyph_first, reflow_t::glyphs, internal_emit_link_rect(), reflow_t::page_count, reflow_t::pages, reflow_glyph_t::reserved, and reflow_glyph_t::y.

Referenced by reflow_run_layout().

◆ priv_reflow_layout_byte_zero()

void priv_reflow_layout_byte_zero ( uint8_t * dst,
size_t n )

Bounded zero-fill used in place of memset(0).

Clang-tidy's clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling rule rejects memset(). We use a tiny private byte-walk so the engine handle can be wiped without dragging the C runtime's deprecated string API into the analyser.

Parameters
[in]dstSee implementation.
[in]nSee implementation.
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

Bounded zero-fill used in place of memset(0).

Definition at line 141 of file reflow_layout.c.

Referenced by reflow_init().

◆ priv_reflow_layout_finish_page()

bool priv_reflow_layout_finish_page ( reflow_t * engine,
priv_cursor_t * cur )

Finalise the current page and start a new one.

Returns
false if the page pool overflowed, true otherwise.

See implementation.

Parameters
[in]engineSee implementation.
[in]curSee implementation.
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

Finalise the current page and start a new one.

Definition at line 260 of file reflow_layout.c.

References reflow_page_t::glyph_count, reflow_t::glyph_count, reflow_page_t::glyph_first, reflow_t::image_box_count, priv_cursor_t::indent_px, k_reflow_margin_px, k_reflow_max_pages, priv_cursor_t::line_first_glyph, priv_cursor_t::line_has_content, priv_cursor_t::line_top, reflow_t::page_count, priv_cursor_t::page_first_glyph, priv_cursor_t::page_first_image, reflow_t::pages, priv_cursor_t::x, and priv_cursor_t::y.

Referenced by internal_close_block(), internal_layout_row(), internal_layout_tokens(), internal_place_image(), and priv_reflow_layout_newline().

◆ priv_reflow_layout_glyph_advance()

int32_t priv_reflow_layout_glyph_advance ( const stbtt_fontinfo * font,
uint16_t font_px,
int32_t cp )

Measure a single ASCII code point's advance width in pixels.

Uses stbtt_GetCodepointHMetrics() (advance is in font-units; we scale by stbtt_ScaleForPixelHeight).

Parameters
[in]fontSee implementation.
[in]font_pxSee implementation.
[in]cpSee 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

Measure a single ASCII code point's advance width in pixels.

Definition at line 225 of file reflow_layout.c.

Referenced by internal_cell_text(), internal_emit_char(), internal_emit_link_rect(), and internal_layout_text().

◆ priv_reflow_layout_init_font()

ra8_err_t priv_reflow_layout_init_font ( const reflow_t * engine,
stbtt_fontinfo * out_font )

Initialise an stbtt_fontinfo from engine->font_data.

Returns
k_ra8_ok if the blob parses, k_ra8_err_validation_failed on a malformed TTF.

See implementation.

Parameters
[in]engineSee implementation.
[in]out_fontSee implementation.
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

Initialise an stbtt_fontinfo from engine->font_data.

Definition at line 158 of file reflow_layout.c.

References reflow_t::font_data, reflow_t::font_len, k_ra8_err_validation_failed, and k_ra8_ok.

Referenced by reflow_run_layout().

◆ priv_reflow_layout_line_height()

uint16_t priv_reflow_layout_line_height ( uint16_t font_px)

Compute the line height in pixels for a given font size.

line_height = font_px * num / den with the constants picked from the public enum so the value is searchable.

Parameters
[in]font_pxSee 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

Compute the line height in pixels for a given font size.

Definition at line 171 of file reflow_layout.c.

References k_reflow_line_spacing_den, and k_reflow_line_spacing_num.

Referenced by internal_cell_text(), internal_close_block(), internal_layout_row(), internal_layout_tokens(), and internal_open_block().

◆ priv_reflow_layout_newline()

bool priv_reflow_layout_newline ( reflow_t * engine,
priv_cursor_t * cur,
bool allow_justify )

Wrap to a new line, finishing a page if the bottom margin is hit.

Calls internal_finish_line to apply alignment to the just-completed line, then advances cur->y by cur->line_height_px, resets cur->x to the left margin plus the active indent, clears cur->line_has_content, and updates cur->line_first_glyph. If the new baseline plus one line height would exceed the bottom margin it calls priv_reflow_layout_finish_page to flush the current page and reset the cursor to the top of a fresh page.

Parameters
[in,out]engineEngine whose page pool may grow by one entry.
[in,out]curLayout cursor; x, y, line state are updated.
[in]allow_justifyPassed to internal_finish_line; true on a wrapped line, false at an explicit paragraph end.
Returns
Boolean success flag.
Return values
trueLine advanced; page flushed if needed.
falsePage pool overflowed; no further layout should proceed.
Precondition
engine != nullptr and cur != nullptr.
cur->line_height_px > 0.
Postcondition
cur->line_has_content == 0 on true return.
On false, engine->page_count == k_reflow_max_pages.
Note
Not thread-safe; caller must serialize access to engine.
Since
0.1.0

Wrap to a new line, finishing a page if the bottom margin is hit.

Definition at line 391 of file reflow_layout.c.

References reflow_t::glyph_count, priv_cursor_t::indent_px, internal_finish_line(), k_reflow_margin_px, priv_cursor_t::line_first_glyph, priv_cursor_t::line_has_content, priv_cursor_t::line_height_px, priv_cursor_t::line_top, priv_reflow_layout_finish_page(), reflow_t::viewport_h, priv_cursor_t::x, and priv_cursor_t::y.

Referenced by internal_apply_image_placeholder(), internal_apply_rule(), internal_close_block(), internal_emit_char(), internal_layout_text(), internal_open_block(), internal_place_image(), priv_reflow_layout_apply_token(), and priv_reflow_layout_table().

◆ priv_reflow_layout_push_glyph()

bool priv_reflow_layout_push_glyph ( reflow_t * engine,
int32_t x,
int32_t y,
int32_t cp,
uint16_t font_px,
uint8_t style,
uint32_t color,
uint8_t link_id )

Push one positioned glyph into the engine glyph pool.

Appends a new reflow_glyph_t entry at engine->glyphs[engine->glyph_count], populates all fields from the supplied arguments, and increments engine->glyph_count. The link_id byte is stored in the reserved field of the glyph so that the post-layout link-rect pass can identify link runs. Returns false immediately – without mutating state – if the pool is already at capacity (engine->glyph_count >= k_reflow_max_glyphs).

Parameters
[in,out]engineEngine whose glyph pool grows by one entry.
[in]xHorizontal pen position in pixels.
[in]yBaseline row in pixels.
[in]cpUnicode code point (ASCII range in practice).
[in]font_pxActive font size in pixels.
[in]styleInline style stamp (bold/italic/underline + face id).
[in]colorPacked ARGB glyph colour.
[in]link_id1-based link identifier; 0 means not a link.
Returns
Boolean success flag.
Return values
trueGlyph appended; engine->glyph_count incremented.
falsePool full; engine state is unchanged.
Precondition
engine != nullptr.
engine->glyph_count <= k_reflow_max_glyphs.
Postcondition
On true, engine->glyphs[engine->glyph_count - 1] holds the new glyph.
On false, no state mutated.
Note
Not thread-safe; caller must serialize access to engine.
Since
0.1.0

Push one positioned glyph into the engine glyph pool.

Definition at line 235 of file reflow_layout.c.

References reflow_glyph_t::color, reflow_glyph_t::cp, reflow_glyph_t::font_px, reflow_t::glyph_count, reflow_t::glyphs, k_reflow_max_glyphs, reflow_glyph_t::reserved, reflow_glyph_t::style, reflow_glyph_t::x, and reflow_glyph_t::y.

Referenced by internal_cell_text(), and internal_emit_char().

◆ priv_reflow_layout_table()

ra8_err_t priv_reflow_layout_table ( reflow_t * engine,
priv_cursor_t * cur,
const stbtt_fontinfo * font,
uint32_t start,
uint32_t * out_next )

Lay out a <table> token range as an equal-column grid.

Flushes the pending line (if any) via priv_reflow_layout_newline, locates the matching table block-end, and counts the maximum column count. If the table has no cells the function advances out_next past the block-end and returns immediately. Otherwise the content width is divided equally by column count to derive col_w, then each <tr> block-start in the range is processed (which handles row-level page breaks). After all rows are placed the cursor is repositioned to the left margin and a paragraph gap is added so linear text flow resumes cleanly below the table.

Parameters
[in,out]engineEngine whose glyph and page pools grow.
[in,out]curLayout cursor; x, y and line state are updated.
[in]fontFont metrics for row and cell layout.
[in]startToken index of the <table> block-start.
[out]out_nextReceives the token index just past the table block-end.
Returns
ra8_err_t error code.
Return values
k_ra8_okTable laid out; out_next set.
k_ra8_err_no_memPending line flush overflowed the page pool.
Precondition
engine != nullptr, cur != nullptr, font != nullptr, out_next != nullptr.
start < engine->token_count and engine->tokens[start] is a <table> block-start.
Postcondition
On k_ra8_ok, *out_next > start and points past the table block-end.
On k_ra8_ok, cur->align == k_reflow_align_left and cur->line_has_content == 0.
Note
Not thread-safe; caller must serialize access to engine and cur.
Since
0.1.0

Definition at line 460 of file reflow_layout_table.c.

References priv_cursor_t::align, reflow_t::glyph_count, priv_cursor_t::indent_px, internal_is_row_start(), internal_layout_row(), internal_match_block_end(), internal_table_columns(), k_ra8_err_no_mem, k_ra8_ok, k_reflow_align_left, k_reflow_margin_px, k_reflow_paragraph_gap_px, priv_cursor_t::line_first_glyph, priv_cursor_t::line_has_content, priv_cursor_t::line_top, priv_reflow_layout_newline(), reflow_t::token_count, reflow_t::viewport_w, priv_cursor_t::x, and priv_cursor_t::y.

Referenced by internal_layout_tokens().