|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Greedy line-break + page-break engine for reflow. 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"Go to the source code of this file.
Functions | |
| bool | priv_reflow_internal_is_indent_tag (uint8_t tag) |
Return true iff tag is a block-level indent tag. | |
| bool | priv_reflow_internal_right_overflow_break (int32_t cursor_x, int32_t advance, int32_t right_limit, uint8_t line_has_content) |
| AND helper for the right-margin overflow break decision. | |
| bool | priv_reflow_internal_xhtml_invalid (const void *xhtml_buf, size_t xhtml_len) |
| OR helper for the cached-XHTML invalid decision. | |
| bool | priv_reflow_internal_final_page_needed (uint32_t page_count, uint32_t token_count) |
| AND helper for the synthesise-final-page decision. | |
| void | priv_reflow_layout_byte_zero (uint8_t *dst, size_t n) |
| Implementation of priv_reflow_layout_byte_zero() – bounded byte-walk. | |
| ra8_err_t | priv_reflow_layout_init_font (const reflow_t *engine, stbtt_fontinfo *out_font) |
| Implementation of priv_reflow_layout_init_font() – parse the TTF blob. | |
| uint16_t | priv_reflow_layout_line_height (uint16_t font_px) |
| Implementation of priv_reflow_layout_line_height() – scaled integer ratio. | |
| static uint16_t | internal_block_font_px (uint16_t body_px, reflow_html_tag_t tag) |
| Pick the font size for a given block tag. | |
| int32_t | priv_reflow_layout_glyph_advance (const stbtt_fontinfo *font, uint16_t font_px, int32_t cp) |
| Implementation of priv_reflow_layout_glyph_advance() – scaled hmetrics. | |
| 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) |
| Implementation of priv_reflow_layout_push_glyph() – append + bounds check. | |
| bool | priv_reflow_layout_finish_page (reflow_t *engine, priv_cursor_t *cur) |
| Implementation of priv_reflow_layout_finish_page() – flush + reset cursor. | |
| static void | internal_justify_glyphs (reflow_t *engine, uint32_t lo, uint32_t hi, int32_t slack) |
Spread slack across the inter-word gaps of glyphs [lo, hi). | |
| static void | internal_finish_line (reflow_t *engine, priv_cursor_t *cur, bool allow_justify) |
| Apply the active block alignment to the just-completed line. | |
| bool | priv_reflow_layout_newline (reflow_t *engine, priv_cursor_t *cur, bool allow_justify) |
| Implementation of priv_reflow_layout_newline() – align, advance, page-break. | |
| static ra8_err_t | internal_emit_char (reflow_t *engine, priv_cursor_t *cur, const stbtt_fontinfo *font, int32_t cp, uint32_t color, uint8_t link_id) |
| Append one ASCII code point at the current cursor, wrapping if it would overflow the right margin. | |
| static ra8_err_t | internal_layout_text (reflow_t *engine, priv_cursor_t *cur, const stbtt_fontinfo *font, const reflow_token_t *tok) |
| Lay out one text token: walk byte-by-byte, breaking at whitespace, and emit each character through internal_emit_char. | |
| static bool | internal_open_block (reflow_t *engine, priv_cursor_t *cur, const reflow_token_t *tok) |
| Apply a block_start token: flush current line, set heading font size, set indent. | |
| static bool | internal_close_block (reflow_t *engine, priv_cursor_t *cur, const reflow_token_t *tok) |
| Apply a block_end token: flush line + add paragraph gap. | |
| static bool | internal_apply_rule (reflow_t *engine, priv_cursor_t *cur) |
| Apply a <hr> rule token: flush the line and bump the cursor. | |
| static void | internal_emit_link_rect (reflow_t *engine, const stbtt_fontinfo *font, uint32_t lo, uint32_t hi, uint8_t link, uint32_t page) |
| Record one tappable link rect spanning glyphs [lo, hi). | |
| void | priv_reflow_layout_build_link_rects (reflow_t *engine, const stbtt_fontinfo *font) |
| Implementation of priv_reflow_layout_build_link_rects() – per-page link runs. | |
| ra8_err_t | priv_reflow_layout_apply_token (reflow_t *engine, priv_cursor_t *cur, const stbtt_fontinfo *font, const reflow_token_t *tok) |
| Implementation of priv_reflow_layout_apply_token() – per-token switch. | |
Greedy line-break + page-break engine for reflow.
Consumes the token stream produced by reflow_parse_xhtml() and lays it out as a flat list of positioned glyphs grouped into pages. The algorithm is a textbook greedy break-on-overflow:
Block-level tokens (<p>, <h1> ..) flush the current line, add a paragraph gap, and (for headings) bump the active font size.
No floating-point allocations and no recursion – the recursion already happened during the parse pass; layout is a flat loop.
[Ring 4 / Reflow] {World: NS}
Definition in file reflow_layout.c.
|
static |
Apply a <hr> rule token: flush the line and bump the cursor.
See implementation.
| [in] | engine | See implementation. |
| [in] | cur | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 666 of file reflow_layout.c.
References k_priv_hr_thickness_px, priv_cursor_t::line_has_content, priv_cursor_t::line_top, priv_reflow_layout_newline(), and priv_cursor_t::y.
Referenced by priv_reflow_layout_apply_token().
|
static |
Pick the font size for a given block tag.
See implementation.
| [in] | body_px | See implementation. |
| [in] | tag | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 195 of file reflow_layout.c.
References k_reflow_h1_scale_pct, k_reflow_h2_scale_pct, k_reflow_h3_scale_pct, k_reflow_h4_scale_pct, k_reflow_h5_scale_pct, k_reflow_h6_scale_pct, k_reflow_pct_full, k_reflow_tag_h1, k_reflow_tag_h2, k_reflow_tag_h3, k_reflow_tag_h4, k_reflow_tag_h5, and k_reflow_tag_h6.
Referenced by internal_open_block().
|
static |
Apply a block_end token: flush line + add paragraph gap.
See implementation.
| [in] | engine | See implementation. |
| [in] | cur | See implementation. |
| [in] | tok | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 624 of file reflow_layout.c.
References priv_cursor_t::active_font_px, reflow_t::font_px, priv_cursor_t::indent_px, k_reflow_margin_px, k_reflow_paragraph_gap_px, priv_cursor_t::line_has_content, priv_cursor_t::line_height_px, priv_cursor_t::line_top, priv_reflow_internal_is_indent_tag(), priv_reflow_layout_finish_page(), priv_reflow_layout_line_height(), priv_reflow_layout_newline(), reflow_token_t::tag, reflow_t::viewport_h, priv_cursor_t::x, and priv_cursor_t::y.
Referenced by priv_reflow_layout_apply_token().
|
static |
Append one ASCII code point at the current cursor, wrapping if it would overflow the right margin.
Measures the advance width of cp via priv_reflow_layout_glyph_advance, clamps it to at least k_priv_min_word_w_px to prevent zero-width stalls, and checks the right-overflow predicate (priv_reflow_internal_right_overflow_break). If a line break is needed and the line already has content, priv_reflow_layout_newline is called before the glyph is pushed. The glyph is then appended via priv_reflow_layout_push_glyph and cur->x is advanced by the clamped advance. cur->line_has_content is set to 1 after the first glyph lands.
| [in,out] | engine | Engine whose glyph pool grows. |
| [in,out] | cur | Layout cursor; x and line state are updated. |
| [in] | font | Font metrics for advance measurement. |
| [in] | cp | Unicode code point to emit (ASCII range in practice). |
| [in] | color | Packed ARGB glyph colour. |
| [in] | link_id | 1-based link identifier; 0 means not a link. |
| k_ra8_ok | Glyph emitted successfully. |
| k_ra8_err_no_mem | Page pool or glyph pool overflowed. |
engine. Definition at line 442 of file reflow_layout.c.
References priv_cursor_t::active_font_px, priv_cursor_t::active_style, k_priv_min_word_w_px, k_ra8_err_no_mem, k_ra8_ok, k_reflow_margin_px, priv_cursor_t::line_has_content, priv_reflow_internal_right_overflow_break(), priv_reflow_layout_glyph_advance(), priv_reflow_layout_newline(), priv_reflow_layout_push_glyph(), reflow_t::viewport_w, priv_cursor_t::x, and priv_cursor_t::y.
Referenced by internal_layout_text().
|
static |
Record one tappable link rect spanning glyphs [lo, hi).
The glyphs are a same-link, same-baseline run on one page. The rect spans from the first glyph's left edge to the last glyph's right edge (measured by priv_reflow_layout_glyph_advance), with a generous vertical band (approximately 1.5 em centered on the baseline) for forgiving tap targets. The target field is stored 0-based (link - 1). If the link-rect pool is already full the function returns immediately without modifying state.
| [in,out] | engine | Engine whose link-rect pool grows by one entry. |
| [in] | font | Font metrics for last-glyph advance measurement. |
| [in] | lo | First glyph index in engine->glyphs[] (inclusive). |
| [in] | hi | One past the last glyph index (exclusive). |
| [in] | link | 1-based link identifier; stored as link - 1. |
| [in] | page | Page index the rect belongs to. |
engine. Definition at line 707 of file reflow_layout.c.
References reflow_glyph_t::cp, reflow_glyph_t::font_px, reflow_t::glyphs, reflow_link_rect_t::h, k_reflow_max_link_rects, reflow_t::link_rect_count, reflow_t::link_rects, reflow_link_rect_t::page_index, priv_reflow_layout_glyph_advance(), reflow_link_rect_t::target, reflow_link_rect_t::w, reflow_glyph_t::x, reflow_link_rect_t::x, reflow_glyph_t::y, and reflow_link_rect_t::y.
Referenced by priv_reflow_layout_build_link_rects().
|
static |
Apply the active block alignment to the just-completed line.
Left alignment is a no-op (the default). Centre and right shift every glyph in the range [cur->line_first_glyph, engine->glyph_count) so the content edge meets the centre or right margin. Justify distributes the slack across inter-word gaps via internal_justify_glyphs – but only when allow_justify is true (wrapped lines); the last line of a paragraph keeps its left alignment. A trailing space at the break point is excluded from the content extent before computing the slack so justification does not over-expand.
| [in,out] | engine | Engine whose laid-out glyphs are aligned. |
| [in] | cur | Cursor (line range + alignment + pen x). |
| [in] | allow_justify | True on a wrapped line, false on a paragraph end. |
engine. Definition at line 358 of file reflow_layout.c.
References priv_cursor_t::align, reflow_glyph_t::cp, reflow_t::glyph_count, reflow_t::glyphs, internal_justify_glyphs(), k_reflow_align_center, k_reflow_align_justify, k_reflow_align_left, k_reflow_margin_px, priv_cursor_t::line_first_glyph, reflow_t::viewport_w, priv_cursor_t::x, and reflow_glyph_t::x.
Referenced by priv_reflow_layout_newline().
|
static |
Spread slack across the inter-word gaps of glyphs [lo, hi).
Each space glyph absorbs an equal share of the slack (with the remainder spread one pixel at a time across the leftmost gaps); every glyph shifts right by the accumulated widening to its left, so the run's right edge lands at the margin with an even gap distribution. If the run contains no space glyphs the function returns early without modifying anything.
| [in,out] | engine | Engine whose glyph x positions are adjusted. |
| [in] | lo | First glyph index (inclusive). |
| [in] | hi | One past the last glyph index. |
| [in] | slack | Total pixels to distribute (> 0). |
slack total. engine. Definition at line 305 of file reflow_layout.c.
References reflow_glyph_t::cp, reflow_t::glyphs, and reflow_glyph_t::x.
Referenced by internal_finish_line().
|
static |
Lay out one text token: walk byte-by-byte, breaking at whitespace, and emit each character through internal_emit_char.
See implementation.
| [in] | engine | See implementation. |
| [in] | cur | See implementation. |
| [in] | font | See implementation. |
| [in] | tok | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 496 of file reflow_layout.c.
References priv_cursor_t::active_font_px, reflow_t::body_color, reflow_token_t::color, internal_emit_char(), k_ra8_err_no_mem, k_ra8_ok, k_reflow_color_inherit, k_reflow_margin_px, priv_cursor_t::line_has_content, reflow_t::link_color, priv_reflow_internal_right_overflow_break(), priv_reflow_layout_glyph_advance(), priv_reflow_layout_newline(), reflow_token_t::reserved, reflow_token_t::text_len, reflow_token_t::text_off, reflow_t::text_pool, reflow_t::viewport_w, and priv_cursor_t::x.
Referenced by priv_reflow_layout_apply_token().
|
static |
Apply a block_start token: flush current line, set heading font size, set indent.
See implementation.
| [in] | engine | See implementation. |
| [in] | cur | See implementation. |
| [in] | tok | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 573 of file reflow_layout.c.
References priv_cursor_t::active_font_px, priv_cursor_t::align, reflow_t::anchor_count, reflow_t::anchors, reflow_token_t::css_font_px, reflow_t::font_px, reflow_anchor_t::id_len, reflow_anchor_t::id_off, priv_cursor_t::indent_px, internal_block_font_px(), k_reflow_indent_px, k_reflow_margin_px, k_reflow_max_anchors, priv_cursor_t::line_has_content, priv_cursor_t::line_height_px, reflow_t::page_count, reflow_anchor_t::page_index, priv_reflow_internal_is_indent_tag(), priv_reflow_layout_line_height(), priv_reflow_layout_newline(), reflow_token_t::reserved, reflow_token_t::tag, reflow_token_t::text_len, reflow_token_t::text_off, priv_cursor_t::x, priv_cursor_t::y, and reflow_anchor_t::y.
Referenced by priv_reflow_layout_apply_token().
| bool priv_reflow_internal_final_page_needed | ( | uint32_t | page_count, |
| uint32_t | token_count ) |
AND helper for the synthesise-final-page decision.
Decide whether the layout pass produced zero pages but the token stream was non-empty (must synthesise a final page).
Promoted from line 750 in reflow_run_layout.
| [in] | page_count | Number of pages flushed during the pass. |
| [in] | token_count | Total parsed-token count. |
| true | Caller must synthesise a single final page. |
| false | No fixup required. |
Definition at line 135 of file reflow_layout.c.
Referenced by reflow_run_layout().
| bool priv_reflow_internal_is_indent_tag | ( | uint8_t | tag | ) |
Return true iff tag is a block-level indent tag.
Return true iff tag is a tag that introduces / removes a block-level indent (currently <li> and <blockquote>).
Pure helper factored out of internal_open_block (line 479) and internal_close_block (line 513) so the tag == li || tag == blockquote decision can be driven directly by host MC/DC tests via priv_reflow_internal_is_indent_tag.
| [in] | tag | Token tag value (raw uint8_t storage of reflow_html_tag_t). |
| true | Tag is k_reflow_tag_li or k_reflow_tag_blockquote. |
| false | Otherwise. |
tag.Definition at line 67 of file reflow_layout.c.
References k_reflow_tag_blockquote, and k_reflow_tag_li.
Referenced by internal_close_block(), and internal_open_block().
| bool priv_reflow_internal_right_overflow_break | ( | int32_t | cursor_x, |
| int32_t | advance, | ||
| int32_t | right_limit, | ||
| uint8_t | line_has_content ) |
AND helper for the right-margin overflow break decision.
Decide whether a glyph emission would overflow the right margin AND the current line already has content.
Promoted from inline expressions at original lines 404, 468 and 605 so MC/DC tests can drive both arms of the (cur->x + advance > right_limit) && line_has_content decision directly.
| [in] | cursor_x | Pen x position in pixels. |
| [in] | advance | Width about to be emitted in pixels. |
| [in] | right_limit | Right edge in pixels. |
| [in] | line_has_content | Non-zero iff the line already has glyphs. |
| true | Caller must call priv_reflow_layout_newline before emitting. |
| false | Emitting in place is safe. |
Definition at line 92 of file reflow_layout.c.
Referenced by internal_apply_image_placeholder(), internal_emit_char(), and internal_layout_text().
| bool priv_reflow_internal_xhtml_invalid | ( | const void * | xhtml_buf, |
| size_t | xhtml_len ) |
OR helper for the cached-XHTML invalid decision.
Decide whether the cached XHTML buffer pointer/length pair is unusable for a re-flow (NULL pointer OR zero length).
Promoted from line 953 in reflow_set_font_size.
| [in] | xhtml_buf | Cached buffer pointer (may be NULL). |
| [in] | xhtml_len | Cached buffer length (may be zero). |
| true | Buffer is unusable. |
| false | Buffer is usable. |
Definition at line 115 of file reflow_layout.c.
Referenced by reflow_bind_font(), and reflow_set_font_size().
| ra8_err_t priv_reflow_layout_apply_token | ( | reflow_t * | engine, |
| priv_cursor_t * | cur, | ||
| const stbtt_fontinfo * | font, | ||
| const reflow_token_t * | tok ) |
Implementation of priv_reflow_layout_apply_token() – per-token switch.
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().
| void priv_reflow_layout_build_link_rects | ( | reflow_t * | engine, |
| const stbtt_fontinfo * | font ) |
Implementation of priv_reflow_layout_build_link_rects() – per-page link runs.
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().
| void priv_reflow_layout_byte_zero | ( | uint8_t * | dst, |
| size_t | n ) |
Implementation of priv_reflow_layout_byte_zero() – bounded byte-walk.
Bounded zero-fill used in place of memset(0).
Definition at line 141 of file reflow_layout.c.
Referenced by reflow_init().
| bool priv_reflow_layout_finish_page | ( | reflow_t * | engine, |
| priv_cursor_t * | cur ) |
Implementation of priv_reflow_layout_finish_page() – flush + reset cursor.
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().
| int32_t priv_reflow_layout_glyph_advance | ( | const stbtt_fontinfo * | font, |
| uint16_t | font_px, | ||
| int32_t | cp ) |
Implementation of priv_reflow_layout_glyph_advance() – scaled hmetrics.
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().
Implementation of priv_reflow_layout_init_font() – parse the TTF blob.
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().
| uint16_t priv_reflow_layout_line_height | ( | uint16_t | font_px | ) |
Implementation of priv_reflow_layout_line_height() – scaled integer ratio.
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().
| bool priv_reflow_layout_newline | ( | reflow_t * | engine, |
| priv_cursor_t * | cur, | ||
| bool | allow_justify ) |
Implementation of priv_reflow_layout_newline() – align, advance, page-break.
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().
| 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 ) |
Implementation of priv_reflow_layout_push_glyph() – append + bounds check.
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().