72 "<svg viewBox=\"0 0 120 80\">"
73 "<rect x=\"0\" y=\"0\" width=\"120\" height=\"80\" fill=\"#283C82\"/>"
74 "<circle cx=\"34\" cy=\"40\" r=\"24\" fill=\"#E6C84B\"/>"
75 "<path d=\"M66 62 L112 62 L89 16 Z\" fill=\"#C03A37\"/>"
79typedef enum : uint32_t {
109 const uint8_t** out_bytes,
129void er_text_left(int32_t x, int32_t y,
const char* str, uint32_t color)
134void er_text_right(int32_t right, int32_t y,
const char* str, uint32_t color)
225 n.
kind = (uint8_t)kind;
256 const int16_t tb =
ra8_box_add(tree, parent, &tb_t);
260 const int16_t srch =
ra8_box_add(tree, tb, &srch_t);
290 const int16_t tile =
ra8_box_add(tree, grid, &tile_t);
299 const int16_t title =
ra8_box_add(tree, tile, &lbl_t);
301 const int16_t auth =
ra8_box_add(tree, tile, &lbl_t);
307 const int16_t bar =
ra8_box_add(tree, tile, &bar_t);
328 const int16_t nav =
ra8_box_add(tree, parent, &nav_t);
331#ifdef RA8_APP_SETTINGS
339 const int16_t item =
ra8_box_add(tree, nav, &item_t);
346typedef enum : uint32_t {
353 return ((c >=
'A') && (c <=
'Z')) ? (char)((c -
'A') +
'a') : c;
359 if (needle[0] ==
'\0') {
364 while ((j < (uint32_t)
k_ra8_kbd_text_max) && (needle[j] !=
'\0') && (hay[i + j] !=
'\0') &&
368 if (needle[j] ==
'\0') {
423 const int16_t grid =
ra8_box_add(tree, root, &grid_t);
452 for (uint16_t i = from; i < to; ++i) {
490 for (uint16_t i = 0U; i < tree->
count; ++i) {
518 (int32_t)
s_fb.width_px,
535 (int32_t)
s_fb.width_px,
561 bands[0].visible =
true;
564 bands[1].visible =
true;
596 [[gnu::section(
".sdram_data")]]
static uint8_t
606 .cell_mem = s_glyph_cells,
609 .meta = s_glyph_meta,
610 .keys = s_glyph_keys,
611 .dims = s_glyph_dims,
612 .buckets = s_glyph_buckets,
715 const int32_t body_h =
785 const int32_t width = (int32_t)
s_fb.width_px;
787 const int32_t title_x =
813 const int32_t width = (int32_t)
s_fb.width_px;
814 const int32_t height = (int32_t)
s_fb.height_px;
821 const int32_t track_w = width - (2 * (int32_t)
k_er_pad_ui);
831 const int32_t pg_cur =
834 const int32_t fill_w = (track_w * pg_cur) / pg_tot;
855 bands[0].visible =
true;
858 bands[1].visible =
true;
861 bands[2].visible =
true;
864 for (uint16_t i = 0U; i < 3U; ++i) {
892 bool crossed =
false;
944 for (uint32_t i = 0U; i < count; ++i) {
974 uint32_t path_len = 0U;
975 uint32_t frag_off = 0U;
976 uint32_t frag_len = 0U;
Pure page-turn + input-region decisions for the e-reader (#78).
static bool er_pageturn_step(uint32_t chapter, uint32_t page, uint32_t pages, uint32_t ch_count, er_dir_t dir, uint32_t *out_chap, uint32_t *out_page, bool *out_crossed)
Advance/retreat the reading location by one page, crossing chapters.
er_dir_t
Page-turn direction produced by an input decision.
static const char k_er_logo_svg[]
In-content SVG (#112): a navy field, a gold disc, and a crimson block.
static bool er_book_matches(const er_book_t *book)
Does book pass the committed search query (true if no filter)?
static const ra8_widget_vtable_t k_er_lib_sb_vt
Vtables for the Library status-bar / body band widgets.
static bool er_nav_fragment(uint32_t off, uint32_t frag_off, uint32_t frag_len)
Follow a same-chapter #fragment: jump to the anchored page.
void er_text_right(int32_t right, int32_t y, const char *str, uint32_t color)
Draw a right-anchored text run ending at column right.
static bool er_draw_reading_body_reflow(int32_t body_top, int32_t height)
Render the Reading body through reflow when an SD font is loaded.
er_filter_t
Search-filter scan bound (NASA Rule 2).
@ k_er_match_scan_max
Max title chars scanned for a match.
static void er_build_toolbar(ra8_box_tree_t *tree, int16_t parent)
Add the toolbar (search field + book-count chip) under a parent.
static void er_build_library(ra8_box_tree_t *tree, const ra8_ui_rect_t *frame)
Build the Library box tree (status bar, toolbar, grid, nav).
static void er_reset_side_tables(void)
Reset the per-node label / progress side tables.
static const ra8_widget_vtable_t k_er_read_footer_vt
static bool er_reflow_relayout(int32_t body_w, int32_t body_h, const uint8_t *font_data, uint32_t font_len)
Re-init the reflow engine and lay the current chapter into the cache.
static const ra8_widget_vtable_t k_er_read_sb_vt
Vtables for the Reading status-bar / body / footer band widgets.
static bool s_read_reflowed
Stash: did the body band reflow live text?
static void er_lib_sb_render(ra8_widget_t *w)
Render the full Library screen.
void er_render_reading(void)
Render the full Reading screen (status bar, body, footer).
static uint16_t s_lib_node_count
Library box-node count (set by er_render_library for the band widgets).
static bool er_draw_reading_body(int32_t height)
Paint the Reading body: reflowed text (SD or baked font), else bitmap.
static uint16_t s_lib_body_first
First Library body box-node (root=0, status bar=1, body from here).
static void er_collect_targets(const ra8_box_tree_t *tree)
Collect tap targets from a laid-out tree's tagged nodes.
static void er_build_nav(ra8_box_tree_t *tree, int16_t parent)
Add the bottom navigation strip under a parent.
static ra8_box_t er_leaf(int16_t fixed, uint16_t flex, uint32_t fill, uint32_t border)
Make a leaf box template carrying fill / border.
static void er_read_sb_render(ra8_widget_t *w)
Status-bar band widget: wordmark + book title + status-right + hairline.
uint32_t er_spine_count(void)
Number of chapters in the (mock) spine.
static void er_read_footer_render(ra8_widget_t *w)
Footer band widget: rule + chapter title + page label + progress bar.
static char er_lc(char c)
Lower-case an ASCII letter (identity for non-letters).
er_svg_len_t
SVG fixture size + the .svg extension length for href routing.
@ k_er_logo_svg_len
SVG byte count.
@ k_er_ext_len
Length of ".svg".
static int16_t s_progress[k_er_max_nodes]
Per-node progress percent, or -1 for "not a progress bar".
static void er_lib_body_render(ra8_widget_t *w)
Body band widget: toolbar + book grid + nav nodes + the above-nav rule.
static void er_add_book_tile(ra8_box_tree_t *tree, int16_t grid, const er_book_t *book)
Add one book card (cover, title, author, progress) under a grid.
void er_push_loc(void)
Push the current (chapter, page) on the back-stack, capacity permitting.
static void er_bind_glyph_atlas(void)
Bind the Layer-3 glyph atlas (#164) to the reflow engine.
static bool er_nav_chapter(uint32_t off, uint32_t path_len)
Follow a cross-chapter link: resolve the path against the mock spine.
void er_text_left(int32_t x, int32_t y, const char *str, uint32_t color)
Draw a left-anchored text run in the bundled font.
static void er_render_boxnodes(uint16_t from, uint16_t to)
Render box nodes [from, to) of s_nodes (fills, borders, progress bars, labels).
static ra8_box_t er_container(ra8_box_kind_t kind, int16_t fixed, int16_t pad, int16_t gap, uint8_t cols)
Make a container box template (stack or grid).
static const ra8_widget_vtable_t k_er_lib_body_vt
static uint32_t s_label_col[k_er_max_nodes]
Per-node text colour.
bool er_reading_link_tap(int32_t x, int32_t y)
Follow an in-content <a> tap in the Reading body (#110).
bool er_apply_pageturn(er_dir_t dir)
Apply a page turn to the reading location (touch + button shared path).
static void er_read_body_render(ra8_widget_t *w)
Body band widget: the reflowed (or bitmap-fallback) chapter text.
static bool er_ci_contains(const char *hay, const char *needle)
Case-insensitive: does needle occur within hay?
static ra8_err_t er_image_loader(void *ctx, const char *href, uint32_t href_len, const uint8_t **out_bytes, size_t *out_len)
reflow image loader: resolve any <img src> to the baked figure.
static const ra8_widget_vtable_t k_er_read_body_vt
void er_render_library(void)
Render the full Library screen.
E-reader UI chrome – shared contract between main.c and the per-aspect helper translation units (scre...
@ k_er_spine_count
Number of chapters in k_er_spine.
bool s_have_font
True once an SD font is loaded.
const char k_er_count_text[]
Book-count chip text.
@ k_er_fill
Flat fills / covers (g13).
@ k_er_fill_deep
Heavier fill / progress (g8).
@ k_er_rule
Hairline dividers (g10).
@ k_er_paper
Page background (g15).
@ k_er_rule_soft
Faintest hairlines / track (g12).
@ k_er_ink
Primary text / glyphs (g0).
@ k_er_ink_muted
Secondary text / metadata (g5).
bool s_reflow_open
True while the engine holds a layout.
const char k_er_search_hint[]
Search placeholder.
ra8_ui_target_t s_targets[]
Tap targets for the current screen.
reflow_t s_reflow_engine
reflow engine for the body.
ra8_kbd_text_t s_query
Live search query.
@ k_er_img_arena
SDRAM image-decode scratch.
@ k_er_glyph_cells
Glyph-cache budget.
@ k_er_reflow_ink
Body text colour (near-black ARGB).
@ k_er_glyph_cell_bytes
Bytes per cell.
@ k_er_reflow_link
Anchor colour (cerulean ARGB).
@ k_er_glyph_buckets
Glyph-cache hash buckets.
@ k_er_reflow_px
Body type size (pixels).
const char *const k_er_body_lines[]
Reading-view body paragraph lines (pre-wrapped for the font).
uint32_t s_chapter_idx
Reading chapter index.
uint16_t s_target_count
Tap targets currently populated.
uint32_t s_reflow_chapter
Chapter laid out (cache key).
volatile uint32_t g_er_turns
Count of page turns applied since boot.
const char *const k_er_nav_items[]
Bottom-nav destinations (Library / Store / Notes / Settings).
@ k_er_page_back_cap
Footnote-jump back-stack depth.
@ k_er_max_targets
Max collected tap targets.
const char k_er_page_label[]
Reading page label.
@ k_er_pad_ui
Side padding for bands / grid.
@ k_er_count_w
Toolbar "N books" chip width.
@ k_er_card_label_h
Card title / author row height.
@ k_er_text_inset_y
16 px text centred in a 64 px band.
@ k_er_border_w
Card / control border weight.
@ k_er_text_pad
Inset for text inside a box.
@ k_er_glyph_w
Bundled font cell width.
@ k_er_footer_h
Reading footer band height.
@ k_er_toolbar_h
Library toolbar band height.
@ k_er_card_bar_h
Card progress-bar height.
@ k_er_progress_gap
Gap above the reading progress bar.
@ k_er_nav_h
Library bottom-nav band height.
@ k_er_progress_h
Reading-progress bar height.
@ k_er_line_h
Body line advance.
@ k_er_statusbar_h
Top status-bar band height.
@ k_er_grid_gap
Library grid gap.
@ k_er_tile_gap
Gap between a card's stacked parts.
@ k_er_blank_lines
Blank advance after the heading.
@ k_er_grid_cols
Library grid column count.
@ k_er_margin_x
Reading left/right margin.
@ k_er_body_gap
Gap between band and body text.
@ k_er_hair
Hairline weight.
@ k_er_glyph_h
Bundled font cell height.
display_turn_event_t s_pending_event
Pending refresh event for next flush.
int32_t s_reflow_w
Body width the layout used.
const char k_er_book_title[]
Reading title text.
uint8_t s_img_arena_buf[]
Image-decode bump arena in SDRAM.
@ k_er_page_total
Reading total pages.
@ k_er_pct_full
Percent denominator.
@ k_er_page_current
Reading current page (1-based).
@ k_er_nav_count
Number of bottom-nav destinations.
@ k_er_nav_idx_setting
Index of the "Settings" nav item.
const char k_er_status_right[]
Status-bar right text.
int32_t s_reflow_h
Body height the layout used.
uint32_t s_loc_back_count
Entries used in s_loc_back.
er_loc_t s_loc_back[]
Reading back-stack for link jumps.
uint32_t s_reading_pages
Reading total reflow pages (>= 1).
const char k_er_chapter[]
Bitmap-fallback heading.
const char k_er_wordmark[6]
Wordmark / status text.
uint32_t s_reading_page
Reading current reflow page.
const er_chapter_t k_er_spine[]
Two-chapter mock spine for in-content cross-chapter navigation (#110).
const er_book_t k_er_books[]
Demo shelf (public-domain works).
@ k_er_max_nodes
Upper bound on chrome box nodes.
@ k_er_act_open_book
Library card -> open the reading view.
@ k_er_act_settings
Bottom-nav Settings -> Settings app.
@ k_er_act_search
Toolbar Search -> open the keyboard.
const char k_er_lib_heading[]
Library heading text.
@ k_er_book_count
Number of demo books.
@ k_er_body_line_count
Number of pre-wrapped body lines.
uint32_t s_font_len
Bytes of font read off the card.
static uint8_t s_font_buf[k_pc_font_cap]
Font blob read off the card.
static const char * s_label[k_ch_max_nodes]
Per-node label (NULL = no text), indexed by box-tree node.
static book_node_t s_nodes[k_arena_nodes]
const unsigned int g_ra8_font_literata_latin1_len
Length of g_ra8_font_literata_latin1 in bytes.
const unsigned char g_ra8_font_literata_latin1[]
Baked Latin-1 subset of Literata Regular (TrueType/glyf), in flash.
Bounded, allocation-free box-model layout for e-reader chrome.
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.
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.
@ k_ra8_box_no_colour
Carried fill/border: absent.
@ k_ra8_box_none
No child / no sibling link.
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_box_kind_t
Box layout kind.
@ k_ra8_box_stack_v
Vertical stack: children stack top->bottom.
@ k_ra8_box_grid
Fixed-column grid, row-major.
@ k_ra8_box_leaf
Terminal box (no children laid out).
@ k_ra8_box_stack_h
Horizontal stack: children left->right.
@ k_display_event_chapter
Chapter-boundary turn – wants a clean refresh.
@ k_display_event_turn
Ordinary next/prev page turn.
Error Code Definitions for ra8-firmware.
@ 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.
int memcmp(const void *a, const void *b, size_t n)
Compare bytes in two memory areas.
Software 2D graphics primitives layered on top of a caller-ownedframebuffer (DRW / D/AVE 2D / GLCDC r...
ra8_err_t ra8_gfx_clear(uint32_t color)
Fill the bound framebuffer's clip region with a single colour.
ra8_err_t ra8_gfx_text_size(const char *str, const ra8_gfx_font_t *font, uint32_t *out_w, uint32_t *out_h)
Compute rendered pixel dimensions of a string.
ra8_err_t ra8_gfx_text_out(int32_t x, int32_t y, const char *str, const ra8_gfx_font_t *font, uint32_t fg_color, uint32_t bg_color)
Render a NUL-terminated ASCII string.
ra8_err_t ra8_gfx_rect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color, bool filled)
Draw an axis-aligned rectangle.
Bitmap font descriptor + bundled font handles for ra8_gfx.
const ra8_gfx_font_t ra8_gfx_font_8x16
Bundled 8x16 IBM PC VGA bitmap font, ASCII 0x20..0x7E.
Fixed-RAM-budget glyph cache with LRU eviction (Layer 3, #147).
@ k_ra8_kbd_text_max
Text buffer capacity incl.
Bounded UI interaction core: hit-testing, screen stack, paging.
HTML / CSS reflow + paginate engine for the ra8d2 ereader.
ra8_err_t reflow_hit_test_link(const reflow_t *engine, uint32_t page_idx, int32_t x, int32_t y, uint32_t *out_href_off, uint32_t *out_href_len)
Hit-test a point on a page against the laid-out <a> link rectangles.
ra8_err_t reflow_layout_chapter(reflow_t *engine, const uint8_t *xhtml_buf, size_t xhtml_len, uint32_t *out_total_pages)
Parse + lay out one chapter of XHTML.
ra8_err_t reflow_find_anchor(const reflow_t *engine, const char *id, uint32_t id_len, uint32_t *out_page)
Find the page of a same-chapter id anchor (for #fragment jumps).
ra8_err_t reflow_href_split(const char *href, uint32_t len, reflow_href_kind_t *out_kind, uint32_t *out_path_len, uint32_t *out_frag_off, uint32_t *out_frag_len)
Split + classify an <a href> into a path part and a #fragment.
ra8_err_t reflow_init(uint16_t viewport_w, uint16_t viewport_h, const uint8_t *font_data, size_t font_len, uint16_t font_px, uint32_t body_color, uint32_t link_color, reflow_t *out_engine)
Initialise a reflow engine for a given viewport / font.
ra8_err_t reflow_set_glyph_atlas(reflow_t *engine, ra8_glyph_atlas_t *atlas, const reflow_glyph_atlas_storage_t *storage)
Bind a Layer-3 glyph cache to the engine's render path (#164).
ra8_err_t reflow_set_image_loader(reflow_t *engine, reflow_image_loader_fn loader, void *ctx, ra8_img_arena_t *arena)
Bind an <img> byte loader + decode arena to enable image rendering.
ra8_err_t reflow_close(reflow_t *engine)
Release a previously initialized engine.
ra8_err_t reflow_render_page_at(const reflow_t *engine, uint32_t page_idx, int32_t origin_x, int32_t origin_y)
Render one page offset by (origin_x, origin_y) into the bound framebuffer.
Zero-heap raster image decode + scale + blit for reflow (#106).
reflow_href_kind_t
Classification of an in-content <a href> target.
@ k_reflow_href_fragment
"#id" – same-chapter anchor.
@ k_reflow_href_chapter_fragment
"path#id" – chapter + anchor.
@ k_reflow_href_empty
Empty / whitespace-only href.
@ k_reflow_href_chapter
"path" – another chapter, no frag.
One library entry: title, author, reading progress percent.
const char * title
Book title.
const char * author
Author.
uint16_t pct
Reading progress (0..100).
One mock-spine chapter: its XHTML, length, and resolving href.
uint32_t len
Length of xhtml (excl.
const char * xhtml
Chapter XHTML body.
One node in a box tree (caller-owned).
uint8_t grid_cols
Columns for k_ra8_box_grid (>= 1).
uint8_t kind
ra8_box_kind_t.
uint16_t flex
Flex weight when not fixed.
int16_t fixed
Fixed main-axis extent; 0 => use flex.
uint32_t border
Border colour, or k_ra8_box_no_colour.
int16_t tag
Caller tag (e.g.
int16_t gap
Gap between children.
int16_t border_w
Border width (0 = no border draw).
int16_t pad
Inner padding (all four sides).
ra8_ui_rect_t rect
OUTPUT: computed rectangle.
uint32_t fill
Background colour, or k_ra8_box_no_colour.
Append-only builder over caller-owned node storage.
ra8_box_t * nodes
Caller storage.
uint16_t count
Nodes used.
Glyph-cache state (caller-owned; treat as private).
Per-cell user descriptor: the rendered glyph dimensions.
Identifies one rendered glyph.
Caller-owned bump arena backing a single image decode.
Per-cell link metadata (one caller-owned array entry per cell).
Axis-aligned rectangle in framebuffer pixel coordinates.
int32_t w
Width (pixels, >= 0).
int32_t h
Height (pixels, >= 0).
int32_t x
Left edge (pixels).
int32_t y
Top edge (pixels).
Caller-owned backing storage for the render-path glyph cache (#164).