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

<table> equal-column grid layout for the reflow engine (#107). More...

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

Go to the source code of this file.

Functions

static uint32_t internal_match_block_end (const reflow_t *engine, uint32_t start, uint32_t limit)
 Find the block-end token matching the block-start at start.
static bool internal_is_cell_start (const reflow_t *engine, uint32_t i)
 True iff token i opens a table cell (<td> or <th>).
static bool internal_is_row_start (const reflow_t *engine, uint32_t i)
 True iff token i opens a table row (<tr>).
static uint32_t internal_table_columns (const reflow_t *engine, uint32_t start, uint32_t end)
 Column count = the maximum number of cells in any row of the table.
static void internal_cell_text (reflow_t *engine, const stbtt_fontinfo *font, const reflow_token_t *tok, int32_t cell_x, int32_t cell_right, uint16_t font_px, uint32_t color, int32_t *cx, int32_t *cy, uint32_t *lines)
 Flow one text token inside a cell box, wrapping at the column edge.
static uint32_t internal_layout_cell (reflow_t *engine, const stbtt_fontinfo *font, int32_t cell_x, int32_t cell_w, int32_t top_y, uint32_t color, uint32_t tstart, uint32_t tend)
 Lay out one cell's text tokens within a fixed column box (left-flow).
static uint32_t internal_row_cells (reflow_t *engine, const stbtt_fontinfo *font, uint32_t tr_start, uint32_t tr_end, int32_t col_w, int32_t row_y)
 Lay out every cell of one row at row_y; return the row's line count.
static uint32_t internal_layout_row (reflow_t *engine, priv_cursor_t *cur, const stbtt_fontinfo *font, uint32_t tr_start, uint32_t table_end, int32_t col_w)
 Lay out one table row, page-breaking before it if it would overflow.
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

<table> equal-column grid layout for the reflow engine (#107).

Splits the table-layout sub-responsibility out of reflow_layout.c so each translation unit stays under the project file-size cap. The grid is an equal-column model: the content width is divided evenly by the maximum per-row cell count, each cell flows its plain-text tokens greedily within its column box, and rows page-break as a unit (rolling the tentative glyphs back and re-laying the row at the top of a fresh page when it would overflow).

The driver enters this module through priv_reflow_layout_table; the core inline-flow helpers it reuses (line height, glyph advance/push, line wrap, page flush) are shared via reflow_layout_internal.h.

[Ring 4 / Reflow] {World: NS}

Since
0.1.0

Definition in file reflow_layout_table.c.

Function Documentation

◆ internal_cell_text()

void internal_cell_text ( reflow_t * engine,
const stbtt_fontinfo * font,
const reflow_token_t * tok,
int32_t cell_x,
int32_t cell_right,
uint16_t font_px,
uint32_t color,
int32_t * cx,
int32_t * cy,
uint32_t * lines )
static

Flow one text token inside a cell box, wrapping at the column edge.

Performs a greedy word-wrap of the text in tok within the pixel range [cell_x, cell_right), starting from the running pen at (*cx, *cy). Spaces are emitted individually only if the pen is past the left edge and the space fits before cell_right; otherwise the space is silently dropped (no leading whitespace on wrapped lines). Each word is pre-measured; if the word plus the current pen x would exceed cell_right and the pen is not already at the left edge, the pen wraps to cell_x on the next line and (*lines)++. Glyphs are pushed via priv_reflow_layout_push_glyph with style 0 and link_id 0 (table cells are always plain body text in v1).

Parameters
[in,out]engineEngine whose glyph pool grows.
[in]fontFont metrics for advance measurement.
[in]tokText token to flow; only text_off / text_len are used.
[in]cell_xCell content left edge in pixels.
[in]cell_rightCell content right edge in pixels.
[in]font_pxGlyph size in pixels.
[in]colorPacked ARGB glyph colour.
[in,out]cxRunning pen x position; updated in place.
[in,out]cyRunning pen baseline y; updated on line wrap.
[in,out]linesRunning line count; incremented on each wrap.
Returns
Nothing.
Precondition
engine != nullptr, font != nullptr, tok != nullptr.
cell_right > cell_x and cx != nullptr and cy != nullptr and lines != nullptr.
Postcondition
*lines >= 1 (starts at 1 before the first call, never decremented).
All glyphs from tok land in the range [cell_x, cell_right).
Note
Not thread-safe; caller must serialize access to engine.
Since
0.1.0

Definition at line 239 of file reflow_layout_table.c.

References priv_reflow_layout_glyph_advance(), priv_reflow_layout_line_height(), priv_reflow_layout_push_glyph(), reflow_token_t::text_len, reflow_token_t::text_off, and reflow_t::text_pool.

Referenced by internal_layout_cell().

◆ internal_is_cell_start()

bool internal_is_cell_start ( const reflow_t * engine,
uint32_t i )
static

True iff token i opens a table cell (<td> or <th>).

Checks both the token kind (must be block_start) and the tag (must be k_reflow_tag_td or k_reflow_tag_th). Used by internal_table_columns and internal_row_cells to locate cell boundaries in the flat token stream without recursion.

Parameters
[in]engineEngine holding the token stream.
[in]iIndex into engine->tokens[] to test.
Returns
Boolean cell-start predicate.
Return values
trueToken at i is a <td> or <th> block-start.
falseOtherwise.
Precondition
i < engine->token_count.
engine->tokens is a valid pointer.
Postcondition
No state mutated.
Return value depends solely on engine->tokens[i].
Note
Pure read; not thread-safe if the token stream is concurrently mutated.
Since
0.1.0

Definition at line 115 of file reflow_layout_table.c.

References k_reflow_tag_td, k_reflow_tag_th, k_reflow_tok_block_start, reflow_token_t::kind, reflow_token_t::tag, and reflow_t::tokens.

Referenced by internal_row_cells(), and internal_table_columns().

◆ internal_is_row_start()

bool internal_is_row_start ( const reflow_t * engine,
uint32_t i )
static

True iff token i opens a table row (<tr>).

Checks both the token kind (must be block_start) and the tag (must be k_reflow_tag_tr). Used by internal_table_columns and priv_reflow_layout_table to locate row boundaries while scanning the flat token stream between a table block-start and its matching block-end.

Parameters
[in]engineEngine holding the token stream.
[in]iIndex into engine->tokens[] to test.
Returns
Boolean row-start predicate.
Return values
trueToken at i is a <tr> block-start.
falseOtherwise.
Precondition
i < engine->token_count.
engine->tokens is a valid pointer.
Postcondition
No state mutated.
Return value depends solely on engine->tokens[i].
Note
Pure read; not thread-safe if the token stream is concurrently mutated.
Since
0.1.0

Definition at line 146 of file reflow_layout_table.c.

References k_reflow_tag_tr, k_reflow_tok_block_start, reflow_token_t::kind, reflow_token_t::tag, and reflow_t::tokens.

Referenced by internal_table_columns(), and priv_reflow_layout_table().

◆ internal_layout_cell()

uint32_t internal_layout_cell ( reflow_t * engine,
const stbtt_fontinfo * font,
int32_t cell_x,
int32_t cell_w,
int32_t top_y,
uint32_t color,
uint32_t tstart,
uint32_t tend )
static

Lay out one cell's text tokens within a fixed column box (left-flow).

Iterates over tokens [tstart, tend) and, for each k_reflow_tok_text token, delegates to internal_cell_text which performs greedy word-wrap within [cell_x, cell_x + cell_w) from top_y. Non-text tokens inside the cell are ignored (v1 table cells hold plain text). The running pen and line counter are local to this call; the return value conveys the height consumed so the row can allocate vertical space for the tallest cell.

Parameters
[in,out]engineEngine whose glyph pool grows.
[in]fontFont metrics for advance measurement.
[in]cell_xCell content left edge in pixels.
[in]cell_wCell content width in pixels (not including padding).
[in]top_yCell top baseline in pixels.
[in]colorPacked ARGB glyph colour for all cell text.
[in]tstartFirst token index of the cell content (inclusive).
[in]tendOne past the last token index (exclusive).
Returns
Number of text lines the cell occupies (>= 1).
Return values
1The cell fits on a single text line (the minimum).
Precondition
tstart <= tend and tend <= engine->token_count.
cell_w > 0.
Postcondition
Return value is >= 1 even for an empty cell (floor at 1 line).
All pushed glyphs have x in [cell_x, cell_x + cell_w).
Note
Not thread-safe; caller must serialize access to engine.
Since
0.1.0

Definition at line 318 of file reflow_layout_table.c.

References reflow_t::font_px, internal_cell_text(), k_reflow_tok_text, reflow_token_t::kind, and reflow_t::tokens.

Referenced by internal_row_cells().

◆ internal_layout_row()

uint32_t internal_layout_row ( reflow_t * engine,
priv_cursor_t * cur,
const stbtt_fontinfo * font,
uint32_t tr_start,
uint32_t table_end,
int32_t col_w )
static

Lay out one table row, page-breaking before it if it would overflow.

First lays the row tentatively at cur->y via internal_row_cells, computing row_h = lines * line_h. If the row's bottom (cur->y + row_h) exceeds the page bottom margin and the cursor is not already at the top margin (i.e. there is content above to preserve), the tentative glyphs are rolled back by restoring engine->glyph_count to its value before the call, a page flush is issued via priv_reflow_layout_finish_page, and the row is re-laid from the top of the fresh page. The cursor is always advanced past the row by row_h + k_priv_row_gap_px before returning.

Parameters
[in,out]engineEngine whose glyph and page pools grow.
[in,out]curLayout cursor; cur->y is advanced past the row.
[in]fontFont metrics for cell advance measurement.
[in]tr_startIndex of the row's <tr> block-start token.
[in]table_endIndex of the enclosing table block-end (scan bound).
[in]col_wColumn width in pixels.
Returns
Token index just past the row's <tr> block-end (tr_end + 1).
Return values
tr_end+1The token index immediately after the row's <tr> block-end.
Precondition
tr_start < table_end and both are within engine->token_count.
col_w > 0 and cur->y >= 0.
Postcondition
cur->y has advanced by row_h + k_priv_row_gap_px on return.
If a page break occurred, engine->page_count has increased by one.
Note
Not thread-safe; caller must serialize access to engine and cur.
Since
0.1.0

Definition at line 433 of file reflow_layout_table.c.

References reflow_t::font_px, reflow_t::glyph_count, internal_match_block_end(), internal_row_cells(), k_priv_row_gap_px, k_reflow_margin_px, priv_reflow_layout_finish_page(), priv_reflow_layout_line_height(), reflow_t::viewport_h, and priv_cursor_t::y.

Referenced by priv_reflow_layout_table().

◆ internal_match_block_end()

uint32_t internal_match_block_end ( const reflow_t * engine,
uint32_t start,
uint32_t limit )
static

Find the block-end token matching the block-start at start.

Scans engine->tokens[] forward from start + 1 to limit - 1, matching only tokens whose tag equals the tag at start. Each nested block-start increments a depth counter; each block-end decrements it. When depth reaches zero the index of that block-end is returned. If the scan reaches limit without a match (malformed input), limit is returned so callers can treat the entire remaining range as the cell or row content.

Parameters
[in]engineEngine holding the token stream.
[in]startIndex of the block-start token whose matching end is sought.
[in]limitExclusive upper bound for the scan (e.g. table block-end).
Returns
Index of the matching block-end token, or limit if not found.
Return values
limitNo matching block-end token was found before limit.
Precondition
start < limit and start < engine->token_count.
engine->tokens[start].kind == k_reflow_tok_block_start.
Postcondition
Return value is in the range [start + 1, limit].
Returned index (if < limit) refers to a block-end with the same tag.
Note
Pure read on the token stream; not thread-safe if the stream is concurrently mutated.
Since
0.1.0

Definition at line 68 of file reflow_layout_table.c.

References k_reflow_tok_block_end, k_reflow_tok_block_start, reflow_token_t::kind, reflow_token_t::tag, and reflow_t::tokens.

Referenced by internal_layout_row(), internal_row_cells(), internal_table_columns(), and priv_reflow_layout_table().

◆ internal_row_cells()

uint32_t internal_row_cells ( reflow_t * engine,
const stbtt_fontinfo * font,
uint32_t tr_start,
uint32_t tr_end,
int32_t col_w,
int32_t row_y )
static

Lay out every cell of one row at row_y; return the row's line count.

Scans the token range (tr_start, tr_end) for <td> / <th> block-starts. Each cell maps to a zero-based column index; the content area starts at margin + col * col_w + pad and has width col_w - 2 * pad (with pad = k_priv_cell_pad_px). Each cell is flowed by internal_layout_cell and the returned line count updates the per-row maximum. Cells beyond the column count are placed but may overflow the viewport (caller ensures the column count is non-zero before calling).

Parameters
[in,out]engineEngine whose glyph pool grows.
[in]fontFont metrics for advance measurement.
[in]tr_startIndex of the row's <tr> block-start token.
[in]tr_endIndex of the row's <tr> block-end token.
[in]col_wColumn width in pixels (total, before padding).
[in]row_yRow top baseline in pixels.
Returns
Maximum cell line count in the row (>= 1).
Return values
1Every cell in the row fits on a single text line (the minimum).
Precondition
tr_start < tr_end and both are within engine->token_count.
col_w > 0.
Postcondition
Return value >= 1 even for rows with no text content.
All pushed glyphs have x within [margin, margin + cols * col_w).
Note
Not thread-safe; caller must serialize access to engine.
Since
0.1.0

Definition at line 371 of file reflow_layout_table.c.

References reflow_t::body_color, internal_is_cell_start(), internal_layout_cell(), internal_match_block_end(), k_priv_cell_pad_px, and k_reflow_margin_px.

Referenced by internal_layout_row().

◆ internal_table_columns()

uint32_t internal_table_columns ( const reflow_t * engine,
uint32_t start,
uint32_t end )
static

Column count = the maximum number of cells in any row of the table.

Scans the token range (start, end) for <tr> block-starts. For each row it counts <td> / <th> block-start tokens between the row open and its matching close (via internal_match_block_end). The maximum across all rows is returned; zero is returned for a table with no cells. The scan advances by full row spans so deeply nested same-tag elements do not distort the count.

Parameters
[in]engineEngine holding the parsed token stream.
[in]startIndex of the <table> block-start token.
[in]endIndex of the <table> block-end token (exclusive bound).
Returns
Maximum cell count across all rows; 0 if the table has no cells.
Return values
0The table span contains no cells.
Precondition
start < end and end <= engine->token_count.
engine->tokens[start] is a table block-start token.
Postcondition
No state mutated; pure scan.
Return value is the maximum per-row cell count or 0.
Note
Pure read on the token stream; not thread-safe if concurrently mutated.
Since
0.1.0

Definition at line 178 of file reflow_layout_table.c.

References internal_is_cell_start(), internal_is_row_start(), and internal_match_block_end().

Referenced by priv_reflow_layout_table().

◆ 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().