40#include "stb_truetype.h"
95 uint8_t line_has_content)
97 return ((cursor_x + advance) > right_limit) && (line_has_content != 0U);
117 return (xhtml_buf ==
nullptr) || (xhtml_len == 0U);
137 return (page_count == 0U) && (token_count > 0U);
143 for (
size_t i = 0U; i < n; ++i) {
160 const int32_t offset = stbtt_GetFontOffsetForIndex(engine->
font_data, 0);
164 if (stbtt_InitFont(out_font, engine->
font_data, (
int)engine->
font_len, offset) == 0) {
227 const float scale = stbtt_ScaleForPixelHeight(font, (
float)font_px);
228 int advance_units = 0;
230 stbtt_GetCodepointHMetrics(font, cp, &advance_units, &lsb);
231 return (int32_t)((float)advance_units * scale);
307 uint32_t spaces = 0U;
308 for (uint32_t i = lo; i < hi; ++i) {
309 if (engine->
glyphs[i].
cp == (int32_t)
' ') {
316 const int32_t per = slack / (int32_t)spaces;
317 const int32_t rem = slack % (int32_t)spaces;
320 for (uint32_t i = lo; i < hi; ++i) {
322 if (engine->
glyphs[i].
cp == (int32_t)
' ') {
324 if ((int32_t)seen < rem) {
368 int32_t content_right = cur->
x;
369 if (engine->
glyphs[hi - 1U].
cp == (int32_t)
' ') {
370 content_right = engine->
glyphs[hi - 1U].
x;
374 const int32_t slack = right_limit - content_right;
375 if ((hi <= lo) || (slack <= 0)) {
385 for (uint32_t i = lo; i < hi; ++i) {
444 const stbtt_fontinfo* font,
450 const int32_t advance_clamped =
472 cur->
x += advance_clamped;
498 const stbtt_fontinfo* font,
503 const uint8_t link_id = tok->
reserved;
518 if (base[i] == (uint8_t)
' ') {
528 uint32_t word_end = i;
530 while ((word_end < len) && (base[word_end] != (uint8_t)
' ')) {
544 while (i < word_end) {
708 const stbtt_fontinfo* font,
719 const int32_t fpx = (int32_t)gfirst->
font_px;
723 rect->
y = gfirst->
y - fpx;
724 rect->
w = (x1 > gfirst->
x) ? (x1 - gfirst->
x) : 1;
725 rect->
h = fpx + (fpx / 2);
726 rect->
target = (uint32_t)link - 1U;
734 for (uint32_t p = 0U; p < engine->
page_count; ++p) {
738 while (k < page->glyph_count) {
744 const int32_t y = engine->
glyphs[base + k].
y;
746 while ((e < page->glyph_count) && (engine->
glyphs[base + e].
reserved == link) &&
747 (engine->
glyphs[base + e].
y == y)) {
759 const stbtt_fontinfo* font,
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Error Code Definitions for ra8-firmware.
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
@ k_ra8_err_validation_failed
Validation rule failed (caller-supplied invariant not satisfied).
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
HTML / CSS reflow + paginate engine for the ra8d2 ereader.
Test-access surface for reflow internal helpers (MC/DC).
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.
bool priv_reflow_internal_is_indent_tag(uint8_t tag)
Return true iff tag is a block-level indent tag.
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.
bool priv_reflow_internal_final_page_needed(uint32_t page_count, uint32_t token_count)
AND helper for the synthesise-final-page decision.
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.
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.
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 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_internal_xhtml_invalid(const void *xhtml_buf, size_t xhtml_len)
OR helper for the cached-XHTML invalid decision.
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.
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 in...
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 bool internal_apply_rule(reflow_t *engine, priv_cursor_t *cur)
Apply a <hr> rule token: flush the line and bump the cursor.
bool priv_reflow_layout_finish_page(reflow_t *engine, priv_cursor_t *cur)
Implementation of priv_reflow_layout_finish_page() – flush + reset cursor.
void priv_reflow_layout_byte_zero(uint8_t *dst, size_t n)
Implementation of priv_reflow_layout_byte_zero() – bounded byte-walk.
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.
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.
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).
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.
uint16_t priv_reflow_layout_line_height(uint16_t font_px)
Implementation of priv_reflow_layout_line_height() – scaled integer ratio.
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.
Cross-TU shared declarations for the reflow layout engine.
@ k_priv_min_word_w_px
Minimum word width before forcing a break.
@ k_priv_hr_thickness_px
Pixel thickness of an <hr> (placeholder).
reflow_html_tag_t
Recognised HTML element kinds.
@ k_reflow_tag_blockquote
Blockquote indent.
@ k_reflow_tag_h5
Heading level 5.
@ k_reflow_tag_h1
Heading level 1.
@ k_reflow_tag_h4
Heading level 4.
@ k_reflow_tag_li
List item.
@ k_reflow_tag_h2
Heading level 2.
@ k_reflow_tag_h6
Heading level 6.
@ k_reflow_tag_h3
Heading level 3.
@ k_reflow_color_inherit
No per-run CSS colour.
@ k_reflow_max_anchors
Max id= anchor positions.
@ k_reflow_max_link_rects
Max positioned link rectangles.
@ k_reflow_max_glyphs
Total positioned glyphs.
@ k_reflow_max_pages
Max paginated pages.
@ k_reflow_paragraph_gap_px
Vertical gap after a block.
@ k_reflow_margin_px
Page edge inset, pixels.
@ k_reflow_h6_scale_pct
H6 size = 100 % of body.
@ k_reflow_h2_scale_pct
H2 size = 175 % of body.
@ k_reflow_h5_scale_pct
H5 size = 110 % of body.
@ k_reflow_h1_scale_pct
H1 size = 200 % of body.
@ k_reflow_h4_scale_pct
H4 size = 125 % of body.
@ k_reflow_h3_scale_pct
H3 size = 150 % of body.
@ k_reflow_line_spacing_den
Line height denominator.
@ k_reflow_line_spacing_num
Line height numerator (= 1.2x).
@ k_reflow_indent_px
Indent for blockquote / li.
@ k_reflow_pct_full
Percentage denominator.
@ k_reflow_align_center
Centred.
@ k_reflow_align_justify
Justified (last line left-aligned).
@ k_reflow_align_left
Left (default, ragged right).
@ k_reflow_tok_block_end
Close of a block-flow element.
@ k_reflow_tok_break
Forced line break (<br>).
@ k_reflow_tok_image
Image placeholder (<img>).
@ k_reflow_tok_text
Text run (slice into pool).
@ k_reflow_tok_block_start
Open of a block-flow element.
@ k_reflow_tok_rule
Horizontal rule (<hr>).
@ k_reflow_face_shift
Bit position of the face index in style.
@ k_reflow_face_mask
Face-index mask once shifted down.
Mutable state carried through the layout loop.
uint32_t page_first_image
First image-box index of the active page.
uint8_t line_has_content
1 once any glyph landed on this line.
int32_t line_top
Pixel row of the current line's top.
uint16_t active_font_px
Active font size (body or heading).
uint32_t page_first_glyph
First glyph index of the active page.
int32_t x
Pixel column for next glyph.
uint32_t line_first_glyph
First glyph index of the active line.
uint16_t line_height_px
Active line height in pixels.
int32_t y
Pixel row baseline for next glyph.
uint8_t align
Active block alignment (reflow_align_t).
uint16_t indent_px
Active left indent (li, blockquote).
uint8_t active_style
Active inline-style stamp.
A laid-out element id, for same-chapter #fragment jumps.
uint32_t page_index
Page the id landed on.
uint32_t id_len
Id slice length, bytes.
uint32_t id_off
Id slice offset into the text pool.
int32_t y
Page-local top y of the element.
One positioned glyph after layout.
uint8_t style
Font-style bitmask.
int32_t cp
Unicode code point.
uint32_t color
32-bit RGB colour.
int32_t x
Pixel column of glyph baseline-left.
uint16_t font_px
Pixel size used for this glyph.
int32_t y
Pixel row of glyph baseline.
One tappable rectangle covering a run of <a> glyphs on a page.
int32_t w
Rect width, pixels.
uint32_t target
Index into engine->link_targets[].
uint32_t page_index
Page this rect belongs to.
int32_t x
Page-local left edge, pixels.
int32_t h
Rect height, pixels.
int32_t y
Page-local top edge, pixels.
Index range of glyphs that belong to one page.
uint32_t glyph_count
Number of glyphs in this page.
uint32_t glyph_first
Index of first glyph in this page.
Reflow / pagination engine state.
uint32_t page_count
Pages used.
const uint8_t * font_data
TTF blob; outlives the engine.
uint32_t link_color
Anchor text colour (0xRRGGBB).
reflow_glyph_t glyphs[k_reflow_max_glyphs]
Positioned glyphs.
uint32_t glyph_count
Glyphs used.
reflow_link_rect_t link_rects[k_reflow_max_link_rects]
Tappable rects.
reflow_page_t pages[k_reflow_max_pages]
Page index ranges.
uint8_t text_pool[k_reflow_text_pool_bytes]
Text bytes.
reflow_anchor_t anchors[k_reflow_max_anchors]
id= anchor positions.
size_t font_len
Length of font_data, bytes.
uint16_t font_px
Body font size in pixels.
uint16_t viewport_w
Viewport width, pixels.
uint32_t anchor_count
Anchor positions used.
uint16_t viewport_h
Viewport height, pixels.
uint32_t body_color
Body text colour (0xRRGGBB).
uint32_t image_box_count
Image boxes used.
uint32_t link_rect_count
Link rects used.
One parsed token in the engine's token stream.
uint16_t css_font_px
Block-start CSS font px (0 = none -> UA default).
uint32_t text_off
Byte offset into the text pool.
uint32_t text_len
Byte length within the text pool.
uint32_t color
0xRRGGBB CSS colour, or k_reflow_color_inherit.
uint8_t kind
reflow_token_kind_t.
uint8_t tag
reflow_html_tag_t (0 if N/A).
uint8_t style
Font-style bitmask.
uint16_t reserved16
Padding to 4-byte stride.
uint8_t reserved
Block align / <a> link id.