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

Implementation of the bounded box-model layout engine. More...

#include "ra8_box.h"
#include <stddef.h>
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_ui.h"
Include dependency graph for ra8_box.c:

Go to the source code of this file.

Functions

static ra8_ui_rect_t internal_inset (ra8_ui_rect_t outer, int32_t pad)
 Inset a rectangle by a uniform padding, clamping size to >= 0.
static bool internal_iter_live (int32_t link, uint16_t guard, uint16_t count)
 Child-walk loop guard: link is live and the bound is not hit.
static void internal_tally (const ra8_box_tree_t *tree, int16_t parent, uint16_t *out_count, int32_t *out_fixed, uint32_t *out_flex)
 Sum child count, fixed extent, and flex weight of a container.
static void internal_layout_stack (ra8_box_tree_t *tree, int16_t parent, bool horizontal)
 Lay out a stack container's children along one axis.
static void internal_layout_grid (ra8_box_tree_t *tree, int16_t parent)
 Lay out a grid container's children row-major.
ra8_err_t ra8_box_tree_init (ra8_box_tree_t *tree, ra8_box_t *storage, uint16_t cap)
 Bind a tree builder to caller-owned node storage.
int16_t ra8_box_add (ra8_box_tree_t *tree, int16_t parent, const ra8_box_t *node)
 Append a node and link it as a child of parent.
ra8_err_t ra8_box_layout (ra8_box_tree_t *tree, int16_t root, const ra8_ui_rect_t *frame)
 Lay out the tree, filling every node's rect.

Variables

static const char *const s_tag = "ra8_box"
 Component tag for diagnostic logging.

Detailed Description

Implementation of the bounded box-model layout engine.

Tag
[Ring 5 / UI] {World: NS}

Single forward-pass layout (no recursion, P10 Rule 1). See ra8_box.h for the contract. The engine computes geometry only; colours/tags are carried through untouched for the renderer.

Since
0.1.0

Definition in file ra8_box.c.

Function Documentation

◆ internal_inset()

ra8_ui_rect_t internal_inset ( ra8_ui_rect_t outer,
int32_t pad )
static

Inset a rectangle by a uniform padding, clamping size to >= 0.

Shifts the origin in by pad on each side and shrinks width/height by twice pad, flooring both at zero so an over-large padding collapses the content box rather than producing a negative extent.

Parameters
[in]outerRectangle to inset.
[in]padPadding applied to all four sides.
Returns
The content rectangle.
Return values
rectPadded rectangle with width/height clamped to >= 0.
Precondition
None.
None.
Postcondition
Returned width/height are never negative.
Returned origin is shifted in by pad.
Note
Pure.
Since
0.1.0

Definition at line 52 of file ra8_box.c.

References ra8_ui_rect_t::h, RA8_INTERNAL, ra8_ui_rect_t::w, ra8_ui_rect_t::x, and ra8_ui_rect_t::y.

Referenced by internal_layout_grid(), and internal_layout_stack().

◆ internal_iter_live()

bool internal_iter_live ( int32_t link,
uint16_t guard,
uint16_t count )
static

Child-walk loop guard: link is live and the bound is not hit.

Centralises the "link is live, and the iteration bound is not yet reached" test used by every child / sibling traversal, so the compound decision lives in one place (one MC/DC obligation). The bound arm is a defensive guard against a malformed cyclic link; ra8_box_add never builds a cycle, so it only ever evaluates true on a well-formed tree.

Parameters
[in]linkNext node index, or k_ra8_box_none.
[in]guardIteration counter.
[in]countNode count (hard upper bound on iterations).
Returns
true to continue the walk, false to stop.
Return values
trueThe link is live and the bound is not yet reached.
falseThe link is none, or the iteration bound was hit.
Precondition
None.
None.
Postcondition
No state modified.
Returns false once link is none or guard reaches count.
Note
Pure.
Since
0.1.0

Definition at line 94 of file ra8_box.c.

References k_ra8_box_none, and RA8_INTERNAL.

Referenced by internal_layout_grid(), internal_layout_stack(), internal_tally(), and ra8_box_add().

◆ internal_layout_grid()

void internal_layout_grid ( ra8_box_tree_t * tree,
int16_t parent )
static

Lay out a grid container's children row-major.

Insets by padding, derives a uniform cell width from the column count and gap, and a uniform cell height from the implied row count (ceil of child count over columns). Children are placed left-to-right, top-to- bottom; a child with a fixed extent keeps that as its height.

Parameters
[in,out]treeTree being laid out.
[in]parentGrid node index (rect already set).
Precondition
tree non-NULL; parent a valid grid node with rect set.
Child links terminate.
Postcondition
Each child sits in its row-major cell; fixed children keep their own height, otherwise rows share the content height evenly.
Cell width/height are floored at zero for tiny content boxes.
Note
Not thread-safe.
Since
0.1.0

Definition at line 246 of file ra8_box.c.

References ra8_box_tree_t::count, ra8_box_t::first_child, ra8_box_t::fixed, ra8_box_t::gap, ra8_box_t::grid_cols, ra8_ui_rect_t::h, internal_inset(), internal_iter_live(), internal_tally(), ra8_box_t::next, ra8_box_tree_t::nodes, ra8_box_t::pad, RA8_INTERNAL, ra8_box_t::rect, ra8_ui_rect_t::w, ra8_ui_rect_t::x, and ra8_ui_rect_t::y.

Referenced by ra8_box_layout().

◆ internal_layout_stack()

void internal_layout_stack ( ra8_box_tree_t * tree,
int16_t parent,
bool horizontal )
static

Lay out a stack container's children along one axis.

Insets the container by its padding, tallies fixed extent and flex weight, then walks the children placing each at a running cursor: fixed children take their fixed size, flex children split the leftover space by weight, and gap separates them. The cross axis fills the content box.

Parameters
[in,out]treeTree being laid out.
[in]parentStack node index (rect already set).
[in]horizontaltrue for a row (main axis X), false a column.
Precondition
tree non-NULL; parent a valid stack node with rect set.
Child links terminate.
Postcondition
Each child's rect is positioned along the main axis.
Fixed children take fixed; the rest split leftover by flex.
Note
Not thread-safe.
Since
0.1.0

Definition at line 179 of file ra8_box.c.

References ra8_box_tree_t::count, ra8_box_t::first_child, ra8_box_t::fixed, ra8_box_t::flex, ra8_box_t::gap, ra8_ui_rect_t::h, internal_inset(), internal_iter_live(), internal_tally(), ra8_box_t::next, ra8_box_tree_t::nodes, ra8_box_t::pad, ra8_box_t::rect, ra8_ui_rect_t::w, ra8_ui_rect_t::x, and ra8_ui_rect_t::y.

Referenced by ra8_box_layout().

◆ internal_tally()

void internal_tally ( const ra8_box_tree_t * tree,
int16_t parent,
uint16_t * out_count,
int32_t * out_fixed,
uint32_t * out_flex )
static

Sum child count, fixed extent, and flex weight of a container.

One bounded walk of the child chain: fixed children (fixed greater than zero) contribute to the fixed total, the rest contribute their flex weight. The result drives flex-space distribution in the stack/grid passes.

Parameters
[in]treeTree being laid out.
[in]parentContainer node index.
[out]out_countReceives the child count.
[out]out_fixedReceives the total fixed main-axis extent.
[out]out_flexReceives the total flex weight.
Precondition
All pointers non-NULL; parent valid.
Child links terminate (guarded by the node count).
Postcondition
The three out-params summarise the direct children.
No node is modified.
Note
Pure read.
Since
0.1.0

Definition at line 131 of file ra8_box.c.

References ra8_box_tree_t::count, ra8_box_t::first_child, ra8_box_t::fixed, ra8_box_t::flex, internal_iter_live(), ra8_box_t::next, ra8_box_tree_t::nodes, and RA8_INTERNAL.

Referenced by internal_layout_grid(), and internal_layout_stack().

◆ ra8_box_add()

int16_t ra8_box_add ( ra8_box_tree_t * tree,
int16_t parent,
const ra8_box_t * node )
nodiscard

Append a node and link it as a child of parent.

Copies node into storage, resets its tree links, and appends it to parent's child chain (or makes it a root when parent == k_ra8_box_none). Returns the new node's index for use as a parent in later calls.

Parameters
[in,out]treeInitialised tree.
[in]parentParent index, or k_ra8_box_none for a root.
[in]nodeNode template (kind / sizing / colours).
Returns
New node index in [0, cap), or k_ra8_box_none on error.
Precondition
tree and node non-NULL; tree initialised.
parent is k_ra8_box_none or a valid earlier index.
Postcondition
On success tree->count grew by one and the node is linked.
On overflow / bad parent the tree is unchanged.
Note
Not thread-safe.
Since
0.1.0

Definition at line 297 of file ra8_box.c.

References ra8_box_tree_t::cap, ra8_box_tree_t::count, ra8_box_t::first_child, internal_iter_live(), k_ra8_box_none, ra8_box_t::next, and ra8_box_tree_t::nodes.

Referenced by ch_build_chrome(), er_add_book_tile(), er_build_library(), er_build_nav(), er_build_toolbar(), internal_build_stack_tree(), and sh_layout_cards().

◆ ra8_box_layout()

ra8_err_t ra8_box_layout ( ra8_box_tree_t * tree,
int16_t root,
const ra8_ui_rect_t * frame )
nodiscard

Lay out the tree, filling every node's rect.

Sets nodes[root].rect = *frame, then makes one forward pass: each container distributes its content box (its rect inset by pad) across its children – fixed children take their fixed extent, the rest split the leftover by flex weight, separated by gap. Grids place children row-major across grid_cols. Because parents precede children in index order, a single in-order pass suffices (no recursion).

Parameters
[in,out]treeBuilt tree (>= 1 node).
[in]rootIndex of the root node.
[in]frameOuter rectangle the root fills.
Returns
ra8_err_t
Return values
k_ra8_okLaid out; every reachable rect set.
k_ra8_err_null_ptrtree or frame is NULL.
k_ra8_err_invalid_argroot out of range, or empty tree.
Precondition
tree and frame non-NULL; 0 <= root < tree->count.
Children indices exceed their parent's (ensured by ra8_box_add).
Postcondition
Every node reachable from root has its rect computed.
Note
Not thread-safe.
Since
0.1.0

Definition at line 331 of file ra8_box.c.

References ra8_box_tree_t::count, internal_layout_grid(), internal_layout_stack(), k_ra8_box_grid, k_ra8_box_leaf, k_ra8_box_stack_h, k_ra8_box_stack_v, k_ra8_err_invalid_arg, k_ra8_ok, ra8_box_t::kind, ra8_box_tree_t::nodes, RA8_CHECK_NULL_PTR, ra8_box_t::rect, and s_tag.

Referenced by er_build_library(), main(), ra8_widget_layout_stack(), and sh_layout_cards().

◆ ra8_box_tree_init()

ra8_err_t ra8_box_tree_init ( ra8_box_tree_t * tree,
ra8_box_t * storage,
uint16_t cap )
nodiscard

Bind a tree builder to caller-owned node storage.

Parameters
[out]treeTree to initialise.
[in]storageNode array owned by the caller.
[in]capNumber of nodes storage holds (>= 1).
Returns
ra8_err_t
Return values
k_ra8_okInitialised (empty tree).
k_ra8_err_null_ptrtree or storage is NULL.
k_ra8_err_invalid_argcap is 0.
Precondition
tree and storage non-NULL; cap >= 1.
None.
Postcondition
tree->count == 0.
tree references storage.
Note
Not thread-safe.
Since
0.1.0

Definition at line 284 of file ra8_box.c.

References ra8_box_tree_t::cap, ra8_box_tree_t::count, k_ra8_err_invalid_arg, k_ra8_ok, ra8_box_tree_t::nodes, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by ch_build_chrome(), er_build_library(), internal_build_stack_tree(), and sh_layout_cards().

Variable Documentation

◆ s_tag

const char* const s_tag = "ra8_box"
static

Component tag for diagnostic logging.

Definition at line 29 of file ra8_box.c.