60 return (c ==
' ') || (c ==
'\t') || (c ==
'\n') || (c ==
'\r') || (c ==
'\f');
90 return (
char)(((c >=
'A') && (c <=
'Z')) ? (c + (
'a' -
'A')) : c);
125 const size_t n =
strlen(lit);
126 if ((at + n) > len) {
129 for (
size_t k = 0U; k < n; ++k) {
168 const size_t n =
strlen(lit);
174 while ((i + n) <= len) {
213 if ((c >=
'0') && (c <=
'9')) {
214 const uint32_t code = (uint32_t)(uint8_t)c;
215 return (uint8_t)(code - (uint32_t)(uint8_t)
'0');
218 if ((l >=
'a') && (l <=
'f')) {
219 const uint32_t code = (uint32_t)(uint8_t)l;
220 return (uint8_t)((code - (uint32_t)(uint8_t)
'a') + (uint32_t)
k_svg_hex_a10);
257 while ((*i < len) && (
priv_ra8_svgp_ws((
char)s[*i]) || (s[*i] == (uint8_t)
','))) {
261 if ((*i < len) && ((s[*i] == (uint8_t)
'-') || (s[*i] == (uint8_t)
'+'))) {
262 sign = (s[*i] == (uint8_t)
'-') ? INT32_C(-1) : INT32_C(1);
266 while ((*i < len) && (s[*i] >= (uint8_t)
'0') && (s[*i] <= (uint8_t)
'9')) {
267 v = (v * (int32_t)
k_svg_dec) + ((int32_t)s[*i] - (int32_t)
'0');
271 if ((*i < len) && (s[*i] == (uint8_t)
'.')) {
273 while ((*i < len) && (s[*i] >= (uint8_t)
'0') && (s[*i] <= (uint8_t)
'9')) {
318 const size_t n =
strlen(name);
325 const size_t after = at + n;
367 for (
size_t i = 0U; i < len; ++i) {
371 size_t j = i +
strlen(name);
372 while ((j < len) && (s[j] != (uint8_t)
'=')) {
379 if ((j >= len) || ((s[j] != (uint8_t)
'"') && (s[j] != (uint8_t)
'\''))) {
382 const char q = (char)s[j];
384 const size_t start = j;
385 while ((j < len) && (s[j] != (uint8_t)q)) {
467 for (; (k < len) && (lit[k] !=
'\0'); ++k) {
472 return (k == len) && (lit[k] ==
'\0');
509 for (
size_t i = 0U; i < len; ++i) {
519 for (
size_t i = 0U; i < len; ++i) {
563 static const struct {
567 {
"black", 0x000000U},
568 {
"white", 0xFFFFFFU},
570 {
"green", 0x008000U},
574 {
"silver", 0xC0C0C0U},
575 {
"maroon", 0x800000U},
577 {
"yellow", 0xFFFF00U},
578 {
"orange", 0xFFA500U},
580 for (
size_t k = 0U; k < (
sizeof(k_names) /
sizeof(k_names[0])); ++k) {
582 return k_names[k].rgb;
619 if (s[0] == (uint8_t)
'#') {
670 const size_t idoff =
strlen(
"url(#");
671 size_t idend = idoff;
672 while ((idend < vlen) && (val[idend] != (uint8_t)
')')) {
675 const size_t idlen = idend - idoff;
677 for (int32_t i = 0; i < grads->
n; ++i) {
678 const char* gid = grads->
g[i].
id;
679 bool equal =
strlen(gid) == idlen;
680 for (
size_t k = 0U; (k < idlen) && equal; ++k) {
681 equal = (uint8_t)gid[k] == val[idoff + k];
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
size_t strlen(const char *s)
Calculate string length.
static bool internal_attr_at(const uint8_t *s, size_t len, size_t at, const char *name)
Test whether an attribute keyword begins at s[at] on a word boundary.
uint32_t priv_ra8_svgp_paint(const uint8_t *s, size_t len)
Parse an SVG paint value ('rgb'/'rrggbb'/name/'none') to 0x00RRGGBB.
int32_t priv_ra8_svgp_num(const uint8_t *s, size_t len, size_t *i)
Parse the integer part of one SVG number at s[*i], skipping leading separators (whitespace / commas);...
static uint8_t internal_hex(char c)
Convert a single hexadecimal digit character to its numeric value.
bool priv_ra8_svgp_ws(char c)
Test whether a character is XML whitespace.
bool priv_ra8_svgp_attr(const uint8_t *s, size_t len, const char *name, size_t *voff, size_t *vlen)
Find attribute name in tag span s[0..len); return its value slice.
uint32_t priv_ra8_svgp_resolve_fill(const uint8_t *s, size_t len, const svg_xform_t *t, uint32_t def, int32_t *gi)
Resolve a shape's 'fill': a solid colour, or a gradient index via gi.
uint32_t priv_ra8_svgp_attr_paint(const uint8_t *s, size_t len, const char *name, uint32_t def)
Read an SVG attribute as a paint colour, returning a default when absent.
size_t priv_ra8_svgp_find_ci(const uint8_t *s, size_t len, size_t from, const char *lit)
Find the first case-insensitive occurrence of a literal in a byte span.
static uint32_t internal_named_color(const uint8_t *s, size_t len)
Map a named SVG colour keyword to its 0x00RRGGBB value.
int32_t priv_match_grad(const svg_grads_t *grads, const uint8_t *val, size_t vlen)
Implementation of priv_match_grad() – linear id search over the document gradient set.
bool priv_ra8_svgp_starts_ci(const uint8_t *s, size_t len, size_t at, const char *lit)
Test whether a byte span starts with a literal at a given offset, case-insensitively.
int32_t priv_ra8_svgp_attr_num(const uint8_t *s, size_t len, const char *name, int32_t def)
Read an SVG attribute as a signed integer, returning a default when absent.
char priv_ra8_svgp_lc(char c)
ASCII-fold a character to lower case.
static bool internal_ci_eq(const uint8_t *s, size_t len, const char *lit)
Case-insensitive equality test between a byte span and a NUL-terminated literal.
static uint32_t internal_hex_color(const uint8_t *s, size_t len)
Parse a hex colour from raw digit bytes (no leading '#') into 0x00RRGGBB.
Minimal SVG handling for the reflow ereader (#112).
Cross-TU surface for the split minimal-SVG subset (#112).
struct svg_grads svg_grads_t
Forward decl: the document's gradient set (defined after svg_xform_t).
@ k_svg_hex6
#rrggbb digit count.
@ k_svg_hex_a10
Value of hex 'a'/'A'.
@ k_svg_hex3
#rgb digit count.
@ k_svg_hex_chan
Bits per colour channel.
@ k_svg_no_paint
none / absent paint sentinel.
@ k_svg_hex_base
Hex base / "not a hex digit".
@ k_svg_hex_nib
Bits per hex nibble.
char id[k_svg_grad_id]
NUL-terminated gradient id (for url()).
svg_grad_t g[k_svg_grad_max]
The gradient table.
int32_t n
Number of valid gradients (<= k_svg_grad_max).