ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
reflow_css_cascade.c
Go to the documentation of this file.
1
22
23#include <stddef.h>
24#include <string.h>
25
26#include "ra8_attributes.h"
27#include "reflow.h" /* k_reflow_tag_unknown, style/align enums */
28#include "reflow_css.h"
29#include "reflow_css_internal.h"
30
31/* ===========================================================================
32 * Internal constants (no magic numbers)
33 * ===========================================================================
34 */
35
51
63typedef enum : uint8_t {
66
67/* ===========================================================================
68 * Public API -- stylesheet scanner
69 * ===========================================================================
70 */
71
73{
74 if (sheet == nullptr) {
75 return k_ra8_err_null_ptr;
76 }
77 sheet->rule_count = 0U;
78 sheet->face_count = 0U;
79 sheet->next_order = 0U;
80 sheet->names_used = 0U;
81 return k_ra8_ok;
82}
83
106static size_t internal_skip_comment(const char* css, size_t len, size_t start)
107{
108 const char open_a = '/';
109 const char open_b = '*';
110 size_t j = start + (size_t)k_priv_cmt_marker;
111 /* Bounded: j strictly increases each pass; capped at len. */
112 while (((j + 1U) < len) && !((css[j] == open_b) && (css[j + 1U] == open_a))) {
113 ++j;
114 }
115 const size_t past = j + (size_t)k_priv_cmt_marker;
116 return (past <= len) ? past : len;
117}
118
144static bool
145internal_find_block(const char* css, size_t len, size_t i, size_t* out_open, size_t* out_close)
146{
147 const char open_c = '{';
148 const char close_c = '}';
149 size_t brace = i;
150 /* Bounded: brace strictly increases each pass; capped at len. */
151 while ((brace < len) && (css[brace] != open_c)) {
152 ++brace;
153 }
154 if (brace >= len) {
155 return false;
156 }
157 size_t close = brace + 1U;
158 /* Bounded: close strictly increases each pass; capped at len. */
159 while ((close < len) && (css[close] != close_c)) {
160 ++close;
161 }
162 *out_open = brace;
163 *out_close = close;
164 return true;
165}
166
167ra8_err_t ra8_css_parse(ra8_css_sheet_t* sheet, const char* css, uint32_t len)
168{
169 if ((sheet == nullptr) || (css == nullptr)) {
170 return k_ra8_err_null_ptr;
171 }
172 const char open_a = '/';
173 const char open_b = '*';
174 size_t i = 0U;
175 /* Bounded: each iteration advances past a block or breaks at EOF. */
176 while (i < (size_t)len) {
177 if (((i + 1U) < (size_t)len) && (css[i] == open_a) && (css[i + 1U] == open_b)) {
178 i = internal_skip_comment(css, (size_t)len, i);
179 continue;
180 }
181 if (priv_reflow_css_is_ws(css[i])) {
182 ++i;
183 continue;
184 }
185 size_t brace = 0U;
186 size_t close = 0U;
187 if (!internal_find_block(css, (size_t)len, i, &brace, &close)) {
188 break; /* no block -> done */
189 }
191 &css[i],
192 brace - i,
193 &css[brace + 1U],
194 close - (brace + 1U));
195 i = (close < (size_t)len) ? (close + 1U) : (size_t)len;
196 }
197 return k_ra8_ok;
198}
199
200/* ===========================================================================
201 * Selector matching + cascade + face lookup
202 * ===========================================================================
203 */
204
232static bool
233internal_class_list_has(const char* list, size_t list_len, const char* name, size_t nlen)
234{
235 size_t i = 0U;
236 /* Bounded: each pass skips >=0 ws then a token, advancing i to list_len. */
237 while (i < list_len) {
238 while ((i < list_len) && priv_reflow_css_is_ws(list[i])) {
239 ++i;
240 }
241 size_t start = i;
242 while ((i < list_len) && !priv_reflow_css_is_ws(list[i])) {
243 ++i;
244 }
245 const size_t tlen = i - start;
246 bool equal = tlen == nlen;
247 for (size_t j = 0U; equal && (j < nlen); ++j) {
248 if (list[start + j] != name[j]) {
249 equal = false;
250 }
251 }
252 if (equal) {
253 return true;
254 }
255 }
256 return false;
257}
258
260 const ra8_css_element_t* el,
261 const ra8_css_sheet_t* sheet)
262{
263 if ((rule == nullptr) || (el == nullptr) || (sheet == nullptr)) {
264 return false;
265 }
266 /* Every present constraint must match (no constraint = universal). */
267 if ((rule->sel_tag != (uint8_t)k_reflow_tag_unknown) && (el->tag != rule->sel_tag)) {
268 return false;
269 }
270 if (rule->class_len != 0U) {
271 const char* nm = (const char*)&sheet->names[rule->class_off];
272 if ((el->class_str == nullptr) ||
274 return false;
275 }
276 }
277 if (rule->id_len != 0U) {
278 const char* nm = (const char*)&sheet->names[rule->id_off];
279 bool equal = (el->id != nullptr) && (el->id_len == rule->id_len);
280 for (uint16_t i = 0U; equal && (i < rule->id_len); ++i) {
281 if (el->id[i] != nm[i]) {
282 equal = false;
283 }
284 }
285 if (!equal) {
286 return false;
287 }
288 }
289 return true;
290}
291
320static bool internal_anc_matches(const ra8_css_anc_t* anc,
321 const ra8_css_element_t* el,
322 const ra8_css_sheet_t* sheet)
323{
324 if ((anc->tag != (uint8_t)k_reflow_tag_unknown) && (el->tag != anc->tag)) {
325 return false;
326 }
327 if (anc->class_len != 0U) {
328 const char* nm = (const char*)&sheet->names[anc->class_off];
329 if ((el->class_str == nullptr) ||
331 return false;
332 }
333 }
334 if (anc->id_len != 0U) {
335 const char* nm = (const char*)&sheet->names[anc->id_off];
336 bool equal = (el->id != nullptr) && (el->id_len == anc->id_len);
337 for (uint16_t i = 0U; equal && (i < anc->id_len); ++i) {
338 if (el->id[i] != nm[i]) {
339 equal = false;
340 }
341 }
342 if (!equal) {
343 return false;
344 }
345 }
346 return true;
347}
348
382 const ra8_css_element_t* el,
383 const ra8_css_element_t* ancestors,
384 uint8_t n_anc,
385 const ra8_css_sheet_t* sheet)
386{
387 if (!ra8_css_rule_matches(rule, el, sheet)) {
388 return false;
389 }
390 if (rule->anc_count == 0U) {
391 return true;
392 }
393 /* Greedy right-to-left: match each ancestor part (innermost first) walking up
394 * the stack from the parent. The descendant combinator allows any depth. */
395 int32_t ai = (int32_t)rule->anc_count - 1;
396 int32_t si = (int32_t)n_anc - 1;
397 /* Bounded: si strictly decreases each pass; ends when si < 0 or ai < 0. */
398 while ((ai >= 0) && (si >= 0)) {
399 if (internal_anc_matches(&rule->anc[ai], &ancestors[si], sheet)) {
400 --ai;
401 }
402 --si;
403 }
404 return ai < 0;
405}
406
433static uint16_t internal_rule_rank(const ra8_css_rule_t* rule)
434{
435 uint16_t spec = 0U;
436 if (rule->sel_tag != (uint8_t)k_reflow_tag_unknown) {
437 spec = (uint16_t)(spec + (uint16_t)k_priv_spec_type);
438 }
439 if (rule->class_len != 0U) {
440 spec = (uint16_t)(spec + (uint16_t)k_priv_spec_class);
441 }
442 if (rule->id_len != 0U) {
443 spec = (uint16_t)(spec + (uint16_t)k_priv_spec_id);
444 }
445 /* Each descendant ancestor part adds to specificity per CSS. */
446 for (uint8_t a = 0U; a < rule->anc_count; ++a) {
447 if (rule->anc[a].tag != (uint8_t)k_reflow_tag_unknown) {
448 spec = (uint16_t)(spec + (uint16_t)k_priv_spec_type);
449 }
450 if (rule->anc[a].class_len != 0U) {
451 spec = (uint16_t)(spec + (uint16_t)k_priv_spec_class);
452 }
453 if (rule->anc[a].id_len != 0U) {
454 spec = (uint16_t)(spec + (uint16_t)k_priv_spec_id);
455 }
456 }
457 return spec;
458}
459
467static const ra8_css_style_t* internal_resolve(uint8_t setbit,
468 const ra8_css_style_t* inherited,
469 const ra8_css_sheet_t* sheet,
470 const bool* matched,
471 const ra8_css_style_t* inl)
472{
473 const ra8_css_style_t* win = nullptr;
474 uint16_t best_rank = 0U;
475 uint16_t best_order = 0U;
476 bool have = false;
477 if ((inherited->set & setbit) != 0U) {
478 win = inherited;
479 best_rank = (uint16_t)k_priv_rank_inherited;
480 have = true;
481 }
482 /* Bounded: rule_count <= k_ra8_css_max_rules; i advances by 1 each step. */
483 for (uint16_t i = 0U; i < sheet->rule_count; ++i) {
484 if (!matched[i] || ((sheet->rules[i].decl.set & setbit) == 0U)) {
485 continue;
486 }
487 const uint16_t rank = internal_rule_rank(&sheet->rules[i]);
488 /* mcdc-deactivated: rules[].order is assigned monotonically in source order (internal_push_rule increments next_order) and this loop scans rules in that same order, so a later same-rank rule always has order > best_order; (order >= best_order) is invariantly true and its false arm is unreachable. */
489 if ((!have) || (rank > best_rank) ||
490 ((rank == best_rank) && (sheet->rules[i].order >= best_order))) {
491 win = &sheet->rules[i].decl;
492 best_rank = rank;
493 best_order = sheet->rules[i].order;
494 have = true;
495 }
496 }
497 if ((inl->set & setbit) != 0U) {
498 win = inl;
499 }
500 return win;
501}
502
532 const ra8_css_sheet_t* sheet,
533 const bool* matched,
534 const ra8_css_style_t* inherited,
535 const ra8_css_style_t* inl)
536{
537 static const struct {
538 uint8_t setbit;
539 uint8_t stylebit;
540 } k_props[3] = {
541 {(uint8_t)k_ra8_css_set_bold, (uint8_t)k_reflow_style_bold},
542 {(uint8_t)k_ra8_css_set_italic, (uint8_t)k_reflow_style_italic},
544 };
545 for (size_t p = 0U; p < (sizeof(k_props) / sizeof(k_props[0])); ++p) {
546 const ra8_css_style_t* win =
547 internal_resolve(k_props[p].setbit, inherited, sheet, matched, inl);
548 if (win != nullptr) {
549 out->set = (uint8_t)(out->set | k_props[p].setbit);
550 if ((win->style & k_props[p].stylebit) != 0U) {
551 out->style = (uint8_t)(out->style | k_props[p].stylebit);
552 }
553 }
554 }
555}
556
586 const ra8_css_sheet_t* sheet,
587 const bool* matched,
588 const ra8_css_style_t* inherited,
589 const ra8_css_style_t* inl)
590{
591 const ra8_css_style_t* awin =
592 internal_resolve((uint8_t)k_ra8_css_set_align, inherited, sheet, matched, inl);
593 if (awin != nullptr) {
594 out->set = (uint8_t)(out->set | (uint8_t)k_ra8_css_set_align);
595 out->align = awin->align;
596 }
597 const ra8_css_style_t* cwin =
598 internal_resolve((uint8_t)k_ra8_css_set_color, inherited, sheet, matched, inl);
599 if (cwin != nullptr) {
600 out->set = (uint8_t)(out->set | (uint8_t)k_ra8_css_set_color);
601 out->color = cwin->color;
602 }
603 /* font-size + display resolve from rules + inline only -- not inherited via
604 * this pure pass (a `%` is applied by the caller against the parent's resolved
605 * px, so seeding `inherited` would double-apply it). */
606 const ra8_css_style_t* fwin =
607 internal_resolve((uint8_t)k_ra8_css_set_fontsize, inherited, sheet, matched, inl);
608 if (fwin != nullptr) {
609 out->set = (uint8_t)(out->set | (uint8_t)k_ra8_css_set_fontsize);
610 out->font_val = fwin->font_val;
611 out->font_unit = fwin->font_unit;
612 }
613 const ra8_css_style_t* dwin =
614 internal_resolve((uint8_t)k_ra8_css_set_display, inherited, sheet, matched, inl);
615 if (dwin != nullptr) {
616 out->set = (uint8_t)(out->set | (uint8_t)k_ra8_css_set_display);
617 out->display = dwin->display;
618 }
619}
620
650 const ra8_css_sheet_t* sheet,
651 const bool* matched,
652 const ra8_css_style_t* inherited,
653 const ra8_css_style_t* inl)
654{
655 const ra8_css_style_t* win =
656 internal_resolve((uint8_t)k_ra8_css_set_family, inherited, sheet, matched, inl);
657 if (win != nullptr) {
658 out->set = (uint8_t)(out->set | (uint8_t)k_ra8_css_set_family);
659 out->family_off = win->family_off;
660 out->family_len = win->family_len;
661 }
662}
663
665 const ra8_css_element_t* el,
666 ra8_css_style_t inherited,
667 ra8_css_style_t inline_decl,
668 const ra8_css_element_t* ancestors,
669 uint8_t n_anc)
670{
671 if ((sheet == nullptr) || (el == nullptr)) {
672 return inherited;
673 }
674 bool matched[k_ra8_css_max_rules] = {};
675 /* Bounded: rule_count <= k_ra8_css_max_rules; i advances by 1 each step. */
676 for (uint16_t i = 0U; i < sheet->rule_count; ++i) {
677 matched[i] = internal_rule_matches_ctx(&sheet->rules[i], el, ancestors, n_anc, sheet);
678 }
679 ra8_css_style_t out = {};
680 internal_cascade_emphasis(&out, sheet, matched, &inherited, &inline_decl);
681 internal_cascade_scalars(&out, sheet, matched, &inherited, &inline_decl);
682 internal_cascade_family(&out, sheet, matched, &inherited, &inline_decl);
683 return out;
684}
685
687 const ra8_css_element_t* el,
688 ra8_css_style_t inherited,
689 ra8_css_style_t inline_decl)
690{
691 return ra8_css_cascade_ctx(sheet, el, inherited, inline_decl, nullptr, 0U);
692}
693
720static bool internal_ci_eq_span(const char* a, size_t alen, const char* b, size_t blen)
721{
722 /* mcdc-deactivated: internal_ci_eq_span is reached only via internal_family_eq from ra8_css_match_face, which rejects a NULL sheet and a NULL family at its entry, so both name pointers are non-NULL here; (a == nullptr) and (b == nullptr) are unreachable, only (alen != blen) varies. */
723 if ((a == nullptr) || (b == nullptr) || (alen != blen)) {
724 return false;
725 }
726 /* Bounded: k < alen (== blen); one byte folded per step. */
727 for (size_t k = 0U; k < alen; ++k) {
728 if (priv_reflow_css_lower(a[k]) != priv_reflow_css_lower(b[k])) {
729 return false;
730 }
731 }
732 return true;
733}
734
760static bool internal_family_eq(const ra8_css_sheet_t* sheet,
761 const ra8_css_fontface_t* f,
762 const char* family,
763 size_t family_len)
764{
765 return internal_ci_eq_span((const char*)&sheet->names[f->family_off],
766 (size_t)f->family_len,
767 family,
768 family_len);
769}
770
772 const char* family,
773 uint16_t family_len,
774 bool want_bold,
775 bool want_italic)
776{
777 if ((sheet == nullptr) || (family == nullptr) || (family_len == 0U)) {
778 return (int16_t)k_ra8_css_no_face;
779 }
780 int16_t fallback = (int16_t)k_ra8_css_no_face;
781 /* Bounded: face_count <= k_ra8_css_max_faces; i advances by 1 each step. */
782 for (uint16_t i = 0U; i < sheet->face_count; ++i) {
783 const ra8_css_fontface_t* f = &sheet->faces[i];
784 if (!internal_family_eq(sheet, f, family, (size_t)family_len)) {
785 continue;
786 }
787 const bool face_bold = f->weight_bold != 0U;
788 const bool face_italic = f->style_italic != 0U;
789 if ((face_bold == want_bold) && (face_italic == want_italic)) {
790 return (int16_t)i;
791 }
792 if ((f->weight_bold == 0U) && (f->style_italic == 0U) && (fallback < 0)) {
793 fallback = (int16_t)i;
794 }
795 }
796 return fallback;
797}
798
800 uint16_t idx,
801 const char** out_src,
802 uint16_t* out_len)
803{
804 if ((sheet == nullptr) || (out_src == nullptr) || (out_len == nullptr) ||
805 (idx >= sheet->face_count)) {
806 return false;
807 }
808 *out_src = (const char*)&sheet->names[sheet->faces[idx].src_off];
809 *out_len = sheet->faces[idx].src_len;
810 return true;
811}
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
Definition ra8_err.h:478
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
HTML / CSS reflow + paginate engine for the ra8d2 ereader.
char priv_reflow_css_lower(char c)
ASCII-fold one byte to lower case.
Definition reflow_css.c:133
bool priv_reflow_css_is_ws(char c)
True for CSS whitespace (space / tab / newline / CR / FF).
Definition reflow_css.c:106
Minimal content-CSS cascade for the reflow ereader engine (#111).
@ k_ra8_css_set_fontsize
font-size was declared.
Definition reflow_css.h:96
@ k_ra8_css_set_underline
text-decoration was declared.
Definition reflow_css.h:93
@ k_ra8_css_set_align
text-align was declared.
Definition reflow_css.h:94
@ k_ra8_css_set_display
display was declared.
Definition reflow_css.h:97
@ k_ra8_css_set_bold
font-weight was declared.
Definition reflow_css.h:91
@ k_ra8_css_set_italic
font-style was declared.
Definition reflow_css.h:92
@ k_ra8_css_set_color
color was declared.
Definition reflow_css.h:95
@ k_ra8_css_set_family
font-family was declared.
Definition reflow_css.h:98
@ k_ra8_css_no_face
No @font-face matched the requested family.
Definition reflow_css.h:79
@ k_ra8_css_max_rules
Max rules kept across all <style> blocks.
Definition reflow_css.h:66
bool ra8_css_rule_matches(const ra8_css_rule_t *rule, const ra8_css_element_t *el, const ra8_css_sheet_t *sheet)
Test whether rule rule's selector matches element el.
static bool internal_find_block(const char *css, size_t len, size_t i, size_t *out_open, size_t *out_close)
Locate the { ... } block beginning at selector offset i.
static bool internal_family_eq(const ra8_css_sheet_t *sheet, const ra8_css_fontface_t *f, const char *family, size_t family_len)
True iff face f's family equals family (case-insensitive).
static size_t internal_skip_comment(const char *css, size_t len, size_t start)
Step over a C-style comment starting at start.
static void internal_cascade_family(ra8_css_style_t *out, const ra8_css_sheet_t *sheet, const bool *matched, const ra8_css_style_t *inherited, const ra8_css_style_t *inl)
Resolve the inherited font-family slice into out.
static void internal_cascade_scalars(ra8_css_style_t *out, const ra8_css_sheet_t *sheet, const bool *matched, const ra8_css_style_t *inherited, const ra8_css_style_t *inl)
Resolve the scalar properties (align / colour / font-size / display).
static bool internal_anc_matches(const ra8_css_anc_t *anc, const ra8_css_element_t *el, const ra8_css_sheet_t *sheet)
True if descendant ancestor part anc matches element el.
ra8_css_style_t ra8_css_cascade_ctx(const ra8_css_sheet_t *sheet, const ra8_css_element_t *el, ra8_css_style_t inherited, ra8_css_style_t inline_decl, const ra8_css_element_t *ancestors, uint8_t n_anc)
Compute an element's cascaded style with descendant-selector context.
ra8_err_t ra8_css_sheet_reset(ra8_css_sheet_t *sheet)
Reset a stylesheet to empty (no rules, no names, order 0).
static bool internal_ci_eq_span(const char *a, size_t alen, const char *b, size_t blen)
Case-insensitive equality of two byte spans.
static bool internal_class_list_has(const char *list, size_t list_len, const char *name, size_t nlen)
True iff a space-separated class list contains name exactly.
static void internal_cascade_emphasis(ra8_css_style_t *out, const ra8_css_sheet_t *sheet, const bool *matched, const ra8_css_style_t *inherited, const ra8_css_style_t *inl)
Resolve the bold / italic / underline emphasis bits into out.
bool ra8_css_face_src(const ra8_css_sheet_t *sheet, uint16_t idx, const char **out_src, uint16_t *out_len)
Read a parsed @font-face entry's src href bytes.
priv_css_scan_t
Token lengths used by the top-level stylesheet scanner.
@ k_priv_cmt_marker
Byte length of a CSS comment delimiter pair.
ra8_err_t ra8_css_parse(ra8_css_sheet_t *sheet, const char *css, uint32_t len)
Parse one <style> block's CSS text, appending rules to sheet.
int16_t ra8_css_match_face(const ra8_css_sheet_t *sheet, const char *family, uint16_t family_len, bool want_bold, bool want_italic)
Pick the @font-face whose family + emphasis best fits a run.
ra8_css_style_t ra8_css_cascade(const ra8_css_sheet_t *sheet, const ra8_css_element_t *el, ra8_css_style_t inherited, ra8_css_style_t inline_decl)
Compute an element's cascaded style.
static uint16_t internal_rule_rank(const ra8_css_rule_t *rule)
Packed specificity (id*10000 + class*100 + type), summing all parts.
static const ra8_css_style_t * internal_resolve(uint8_t setbit, const ra8_css_style_t *inherited, const ra8_css_sheet_t *sheet, const bool *matched, const ra8_css_style_t *inl)
Resolve the winning declaration for one property across all sources.
priv_css_consts_t
Cascade specificity weights (packed id > class > type > universal).
@ k_priv_spec_class
A class constraint adds this.
@ k_priv_spec_id
An id constraint adds this.
@ k_priv_spec_type
A type constraint adds this.
@ k_priv_rank_inherited
Inheritance / universal weight.
static bool internal_rule_matches_ctx(const ra8_css_rule_t *rule, const ra8_css_element_t *el, const ra8_css_element_t *ancestors, uint8_t n_anc, const ra8_css_sheet_t *sheet)
Full match of a (possibly descendant) rule against el + ancestors.
Cross-TU surface for the split content-CSS cascade (#111).
void priv_reflow_css_parse_one_block(ra8_css_sheet_t *sheet, const char *sel, size_t sel_len, const char *block, size_t block_len)
Dispatch one selector|@rule { block }: at-rule vs.
@ k_reflow_tag_unknown
Anything not in this enum.
@ k_reflow_style_italic
Italic face.
@ k_reflow_style_bold
Bold face.
@ k_reflow_style_underline
Underlined run.
One ancestor part of a descendant selector (e.g.
Definition reflow_css.h:145
uint16_t id_off
Id name slice offset (id_len 0 = none).
Definition reflow_css.h:150
uint16_t class_len
Class name slice length, bytes.
Definition reflow_css.h:149
uint16_t id_len
Id name slice length, bytes.
Definition reflow_css.h:151
uint16_t class_off
Class name slice offset (class_len 0 = none).
Definition reflow_css.h:148
uint8_t tag
Type tag, or k_reflow_tag_unknown = no type.
Definition reflow_css.h:146
The identity of one element, used to match selectors.
Definition reflow_css.h:230
uint16_t class_len
Length of class_str, bytes.
Definition reflow_css.h:235
const char * id
id attribute bytes (NULL = none).
Definition reflow_css.h:232
const char * class_str
class attribute bytes (NULL = none).
Definition reflow_css.h:234
uint16_t id_len
Length of id, bytes.
Definition reflow_css.h:233
uint8_t tag
reflow_html_tag_t of the element.
Definition reflow_css.h:231
One parsed @font-face rule: family + weight/style + src href.
Definition reflow_css.h:195
uint16_t src_len
src href slice length.
Definition reflow_css.h:199
uint8_t weight_bold
1 = this face is the bold weight.
Definition reflow_css.h:200
uint16_t family_len
font-family name slice length.
Definition reflow_css.h:197
uint8_t style_italic
1 = this face is italic / oblique.
Definition reflow_css.h:201
uint16_t src_off
src href slice offset.
Definition reflow_css.h:198
uint16_t family_off
font-family name slice offset.
Definition reflow_css.h:196
One selector { ... } rule: a (possibly descendant) selector plus its declarations.
Definition reflow_css.h:173
uint16_t class_off
Class name slice offset (class_len 0 = none).
Definition reflow_css.h:176
uint16_t id_off
Id name slice offset (id_len 0 = none).
Definition reflow_css.h:178
ra8_css_style_t decl
Declared properties.
Definition reflow_css.h:182
ra8_css_anc_t anc[k_ra8_css_max_anc]
Descendant ancestor parts.
Definition reflow_css.h:181
uint16_t class_len
Class name slice length, bytes.
Definition reflow_css.h:177
uint16_t order
Source order (lower = earlier; ties to later).
Definition reflow_css.h:180
uint8_t anc_count
Ancestor parts in anc (0 = simple).
Definition reflow_css.h:175
uint16_t id_len
Id name slice length, bytes.
Definition reflow_css.h:179
uint8_t sel_tag
Type tag, or k_reflow_tag_unknown = no type.
Definition reflow_css.h:174
A parsed stylesheet: rule + @font-face arrays and a name byte pool.
Definition reflow_css.h:212
uint16_t face_count
@font-face rules in use.
Definition reflow_css.h:216
uint16_t rule_count
Rules in use.
Definition reflow_css.h:215
ra8_css_rule_t rules[k_ra8_css_max_rules]
Parsed rules.
Definition reflow_css.h:213
uint16_t next_order
Running source-order ctr.
Definition reflow_css.h:217
uint16_t names_used
Bytes used in names.
Definition reflow_css.h:218
ra8_css_fontface_t faces[k_ra8_css_max_faces]
Parsed @font-face rules.
Definition reflow_css.h:214
uint8_t names[k_ra8_css_name_pool]
class/id/font name bytes.
Definition reflow_css.h:219
A declared or computed style: a presence mask plus property values.
Definition reflow_css.h:122
uint16_t font_val
font-size number: px or % (valid iff set & fontsize).
Definition reflow_css.h:128
uint16_t family_len
font-family name slice length (0 = none).
Definition reflow_css.h:132
uint8_t font_unit
ra8_css_font_unit_t (valid iff set & fontsize).
Definition reflow_css.h:126
uint8_t display
1 = display:none (valid iff set & display).
Definition reflow_css.h:129
uint8_t style
reflow_font_style_t bit VALUES (bold/italic/ul).
Definition reflow_css.h:124
uint8_t set
ra8_css_set_t bitmask: which properties are present.
Definition reflow_css.h:123
uint16_t family_off
font-family name slice offset (valid iff set&family).
Definition reflow_css.h:131
uint32_t color
0xRRGGBB text colour (valid iff set & color).
Definition reflow_css.h:127
uint8_t align
reflow_align_t (valid iff set & align).
Definition reflow_css.h:125