|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Coordinate transform + 2x3 affine transform= parsing for SVG (#112). More...
Go to the source code of this file.
Enumerations | |
| enum | svg_xf_kind_t : uint8_t { k_svg_xf_none = 0U , k_svg_xf_translate = 1U , k_svg_xf_scale = 2U , k_svg_xf_rotate = 3U , k_svg_xf_skewx = 4U , k_svg_xf_skewy = 5U , k_svg_xf_matrix = 6U } |
| transform= function kinds recognised by internal_parse_xform. More... | |
| enum | svg_xf_arg_t : uint8_t { k_svg_xf_arg_a = 0U , k_svg_xf_arg_b = 1U , k_svg_xf_arg_c = 2U , k_svg_xf_arg_d = 3U , k_svg_xf_arg_e = 4U , k_svg_xf_arg_f = 5U } |
| Argument indices into a parsed matrix(a,b,c,d,e,f) transform list. More... | |
Functions | |
| static int32_t | internal_ux (const svg_xform_t *t, int32_t sx) |
| Apply the axis-aligned user transform (a/translate) to a user-space x. | |
| static int32_t | internal_uy (const svg_xform_t *t, int32_t sy) |
| Apply the axis-aligned user transform (d/translate) to a user-space y. | |
| bool | priv_ra8_svgp_has_rot (const svg_xform_t *t) |
| Test whether the user transform contains rotation or shear. | |
| void | priv_ra8_svgp_map_point (const svg_xform_t *t, int32_t ux, int32_t uy, int32_t *fx, int32_t *fy) |
| Map a user-space point through the FULL affine, then viewBox->box. | |
| int32_t | priv_ra8_svgp_mx (const svg_xform_t *t, int32_t sx) |
| Map a user-space x coordinate to a framebuffer x coordinate. | |
| int32_t | priv_ra8_svgp_my (const svg_xform_t *t, int32_t sy) |
| Map a user-space y coordinate to a framebuffer y coordinate. | |
| int32_t | priv_ra8_svgp_sx (const svg_xform_t *t, int32_t sw) |
| Scale a user-space length by the user x scale and the viewBox x ratio. | |
| float | priv_ra8_svgp_numf (const uint8_t *s, size_t len, size_t *i) |
Parse one SVG floating-point number at s[*i], skipping leading separators. | |
| static svg_utf_t | internal_utf_identity (void) |
| Return the 2x3 affine identity transform. | |
| static svg_utf_t | internal_utf_compose (svg_utf_t a, svg_utf_t b) |
Compose two 2x3 affines: a (outer) over b (inner). | |
| static bool | internal_is_num_start (const uint8_t *s, size_t len, size_t at) |
| Test whether a byte position starts an SVG number literal. | |
| static float | internal_deg2rad (float deg) |
| Convert an angle from degrees to radians. | |
| static int32_t | internal_xform_read (const uint8_t *v, size_t vlen, size_t *j, float *args) |
| Read up to 6 float arguments from a transform function's '(...)' list. | |
| static svg_utf_t | internal_xform_rotate (const float *args, int32_t na) |
| Build the 2x3 affine for an SVG 'rotate(deg[,cx,cy])' transform. | |
| static svg_utf_t | internal_xform_build (svg_xf_kind_t kind, const float *args, int32_t na) |
| Build the 2x3 affine for one parsed SVG transform function. | |
| static svg_xf_kind_t | internal_xform_kind (const uint8_t *v, size_t vlen, size_t i) |
Identify the SVG transform function keyword starting at v[i]. | |
| static svg_utf_t | internal_parse_xform (const uint8_t *v, size_t vlen) |
| Parse a 'transform=' attribute value into a composed 2x3 affine. | |
| void | priv_ra8_svgp_apply_xform (svg_xform_t *t, const uint8_t *tag, size_t tlen) |
Compose the 'transform=' attribute from tag onto t's user affine. | |
Coordinate transform + 2x3 affine transform= parsing for SVG (#112).
The viewBox->box coordinate map plus the full 2x3 affine transform= machinery (translate / scale / rotate / skewX / skewY / matrix, composed and applied per point). Provides the axis-aligned fast-path mappers (priv_ra8_svgp_mx / priv_ra8_svgp_my / priv_ra8_svgp_sx) and the general priv_ra8_svgp_map_point used by the shape and path stages. No DOM, no heap. See reflow_svg_internal.h for the shared geometry types and helper contracts.
[Ring 4 / Reflow] {World: NS}
Definition in file reflow_svg_xform.c.
| enum svg_xf_arg_t : uint8_t |
Argument indices into a parsed matrix(a,b,c,d,e,f) transform list.
Definition at line 432 of file reflow_svg_xform.c.
| enum svg_xf_kind_t : uint8_t |
transform= function kinds recognised by internal_parse_xform.
Definition at line 418 of file reflow_svg_xform.c.
|
static |
Convert an angle from degrees to radians.
Multiplies deg by the function-local constant ratio pi / 180. Used by the rotate, skewX, and skewY transform builders when converting their single degree argument into the radian angle needed by cosf and sinf.
| [in] | deg | Angle in degrees (any finite float value). |
| n | deg * (pi / 180). |
deg is a finite float value (NaN or infinity produce undefined float arithmetic). deg * (pi / 180.0F). deg is not modified.Definition at line 465 of file reflow_svg_xform.c.
Referenced by internal_xform_build(), and internal_xform_rotate().
|
static |
Test whether a byte position starts an SVG number literal.
A byte position is considered the start of a number when it is a decimal digit ('0'-'9'), a sign character ('-' or '+'), or a decimal point ('.'). Returns false immediately when at >= len to guard against out-of-bounds access. Used by internal_xform_read to decide whether to call priv_ra8_svgp_numf for the next argument in a transform function's argument list.
| [in] | s | Byte buffer containing the transform value; must not be NULL. |
| [in] | len | Total valid bytes in s. |
| [in] | at | Byte offset to test. |
s[at] can begin an SVG number. | true | at < len and s[at] is a digit, sign, or decimal point. |
| false | at >= len, or s[at] is not a number-start character. |
s is a valid pointer to at least len bytes. at is a size_t value (may equal or exceed len).s, len, and at are not modified. Definition at line 405 of file reflow_svg_xform.c.
Referenced by internal_xform_read().
|
static |
Parse a 'transform=' attribute value into a composed 2x3 affine.
Recognises translate/scale/rotate/skewX/skewY/matrix functions, composed left-to-right (the leftmost function becomes the outermost in the affine product, i.e. applied last). Unknown or unrecognised function names are skipped. The accumulator starts at the identity and each parsed function is right-composed via internal_utf_compose. Bounded: the scan advances past at least one '(' per iteration or breaks at end-of-buffer.
| [in] | v | Byte span holding the attribute value text; must not be NULL. |
| [in] | vlen | Total valid bytes in v. |
v. | internal_utf_identity() | v contains no recognised transform functions. |
| svg_utf_t | Composition of all recognised functions, left-to-right. |
v is a valid pointer to at least vlen bytes. vlen accurately reflects the number of valid bytes in v.v is not modified.Definition at line 728 of file reflow_svg_xform.c.
References internal_utf_compose(), internal_utf_identity(), internal_xform_build(), internal_xform_kind(), internal_xform_read(), k_svg_path_args, k_svg_xf_none, and priv_ra8_svgp_ws().
Referenced by priv_ra8_svgp_apply_xform().
Compose two 2x3 affines: a (outer) over b (inner).
Computes the 2x3 matrix product a * b so that a point is first mapped by b and then by a, implementing the standard affine composition rule. The translation components are handled correctly: e and f of the result include the full composite translation. Used to accumulate a series of SVG transform functions (translate, scale, rotate, skew, matrix) into one affine that can be applied per-point in priv_ra8_svgp_map_point.
| [in] | a | Outer (post) affine; applied second. |
| [in] | b | Inner (pre) affine; applied first. |
a * b. | svg_utf_t | The result of composing a over b as 2x3 matrix product. |
a and b are fully initialised svg_utf_t values. a and b are finite.p as a(b(p)). a and b are not modified (passed by value).Definition at line 365 of file reflow_svg_xform.c.
References svg_utf_t::a, svg_utf_t::b, svg_utf_t::c, svg_utf_t::d, svg_utf_t::e, and svg_utf_t::f.
Referenced by internal_parse_xform(), and priv_ra8_svgp_apply_xform().
|
static |
Return the 2x3 affine identity transform.
Constructs and returns an svg_utf_t with a=1, d=1, and all other fields zero. This is the identity element for affine composition: any affine composed with the identity returns the original affine unchanged. Used to initialise the group transform stack and as the starting accumulator in internal_parse_xform.
| svg_utf_t{.a=1,.b=0,.c=0,.d=1,.e=0,.f=0} | Always. |
svg_utf_t type is properly defined in this translation unit.a==1.0F, d==1.0F, and all other fields 0.0F. Definition at line 331 of file reflow_svg_xform.c.
Referenced by internal_parse_xform(), and internal_xform_build().
|
static |
Apply the axis-aligned user transform (a/translate) to a user-space x.
Computes (sx * t->ua) + t->ue as a float, then truncates to int32_t. Valid only on the axis-aligned fast path where the shear components t->ub and t->uc are both zero. When the transform has rotation or shear, use priv_ra8_svgp_map_point instead to apply the full affine.
| [in] | t | Active coordinate transform; must not be NULL. |
| [in] | sx | User-space X coordinate to transform. |
| n | The scaled-and-translated X coordinate, truncated to int32_t. |
t is a valid non-NULL pointer to an initialised svg_xform_t. t->ub == 0.0F and t->uc == 0.0F (axis-aligned fast path).t and sx are not modified.Definition at line 57 of file reflow_svg_xform.c.
References svg_xform_t::ua, and svg_xform_t::ue.
Referenced by priv_ra8_svgp_mx().
|
static |
Apply the axis-aligned user transform (d/translate) to a user-space y.
Computes (sy * t->ud) + t->uf as a float, then truncates to int32_t. Valid only on the axis-aligned fast path where the shear components t->ub and t->uc are both zero. When the transform has rotation or shear, use priv_ra8_svgp_map_point instead to apply the full affine.
| [in] | t | Active coordinate transform; must not be NULL. |
| [in] | sy | User-space Y coordinate to transform. |
| n | The scaled-and-translated Y coordinate, truncated to int32_t. |
t is a valid non-NULL pointer to an initialised svg_xform_t. t->ub == 0.0F and t->uc == 0.0F (axis-aligned fast path).t and sy are not modified.Definition at line 88 of file reflow_svg_xform.c.
References svg_xform_t::ud, and svg_xform_t::uf.
Referenced by priv_ra8_svgp_my().
|
static |
Build the 2x3 affine for one parsed SVG transform function.
Switches on kind to construct the appropriate svg_utf_t: translate fills e/ scale fills f;a/(uniform if na==1); rotate delegates to d internal_xform_rotate; skewX/skewY fill c or b via tanf; matrix copies all six components directly. An unrecognised kind (k_svg_xf_none or default) returns the identity.
| [in] | kind | Transform function identifier; one of the svg_xf_kind_t values. |
| [in] | args | Parsed float arguments; caller guarantees at least na valid entries. |
| [in] | na | Count of valid float arguments in args. |
| svg_utf_t | The computed affine; identity for k_svg_xf_none or unknown kind. |
args is a valid non-NULL pointer to at least na float values. na is consistent with kind (e.g. >= 1 for translate/scale).args and na are not modified.Definition at line 588 of file reflow_svg_xform.c.
References internal_deg2rad(), internal_utf_identity(), internal_xform_rotate(), k_svg_xf_arg_a, k_svg_xf_arg_b, k_svg_xf_arg_c, k_svg_xf_arg_d, k_svg_xf_arg_e, k_svg_xf_arg_f, k_svg_xf_matrix, k_svg_xf_none, k_svg_xf_rotate, k_svg_xf_scale, k_svg_xf_skewx, k_svg_xf_skewy, and k_svg_xf_translate.
Referenced by internal_parse_xform().
|
static |
Identify the SVG transform function keyword starting at v[i].
Tests the byte span at offset i against each recognised keyword ("translate(", "scale(", "rotate(", "skewx(", "skewy(", "matrix(") using priv_ra8_svgp_starts_ci. Returns the first matching svg_xf_kind_t value, or k_svg_xf_none when no keyword matches. Case-insensitive to match the SVG specification (though SVG uses lower case by convention).
| [in] | v | Byte buffer containing the 'transform=' attribute value; must not be NULL. |
| [in] | vlen | Total valid bytes in v. |
| [in] | i | Byte offset at which the keyword scan begins. |
| k_svg_xf_translate | "translate(" matches at v[i]. |
| k_svg_xf_scale | "scale(" matches at v[i]. |
| k_svg_xf_rotate | "rotate(" matches at v[i]. |
| k_svg_xf_skewx | "skewx(" matches at v[i]. |
| k_svg_xf_skewy | "skewy(" matches at v[i]. |
| k_svg_xf_matrix | "matrix(" matches at v[i]. |
| k_svg_xf_none | No recognised keyword matches. |
v is a valid pointer to at least vlen bytes. i is <= vlen.v, vlen, and i are not modified. svg_xf_kind_t enumerator.Definition at line 676 of file reflow_svg_xform.c.
References k_svg_xf_matrix, k_svg_xf_none, k_svg_xf_rotate, k_svg_xf_scale, k_svg_xf_skewx, k_svg_xf_skewy, k_svg_xf_translate, and priv_ra8_svgp_starts_ci().
Referenced by internal_parse_xform().
|
static |
Read up to 6 float arguments from a transform function's '(...)' list.
Advances *j past any leading whitespace/commas, then calls priv_ra8_svgp_numf for each number that begins at the current cursor. The loop terminates when internal_is_num_start returns false or the k_svg_argc_cube limit (6) is reached. On return *j points past all consumed arguments. Used by internal_parse_xform to populate the argument array passed to internal_xform_build.
| [in] | v | Byte buffer containing the transform value text; must not be NULL. |
| [in] | vlen | Total valid bytes in v. |
| [in,out] | j | Parse cursor; updated past all consumed argument bytes. |
| [out] | args | Array of at least k_svg_argc_cube floats; must not be NULL. |
args. | 0..6 | The number of float arguments parsed from v[*j]. |
v is a valid pointer to at least vlen bytes. j is not NULL and *j <= vlen.args[0..return-1] contain the parsed float arguments. *j is advanced past all consumed whitespace, commas, and digits.Definition at line 502 of file reflow_svg_xform.c.
References internal_is_num_start(), k_svg_argc_cube, priv_ra8_svgp_numf(), and priv_ra8_svgp_ws().
Referenced by internal_parse_xform().
|
static |
Build the 2x3 affine for an SVG 'rotate(deg[,cx,cy])' transform.
Converts args[0] from degrees to radians and computes cosf / sinf. When na >= 3, args[1] and args[2] supply the centre of rotation (cx, cy); the translation components e and f are set to keep the centre fixed. When na < 3 the rotation is about the origin (e=f=0).
| [in] | args | Array of at least na float arguments; args[0]=degrees, args[1]=cx (optional), args[2]=cy (optional). |
| [in] | na | Count of valid entries in args (1 or 3). |
| svg_utf_t | Rotation matrix; e and f absorb the (cx,cy) re-centring. |
args is a valid non-NULL pointer to at least na float values. na is 1 (rotate about origin) or 3 (rotate about cx,cy).na < 3. args and na are not modified.Definition at line 546 of file reflow_svg_xform.c.
References internal_deg2rad().
Referenced by internal_xform_build().
| void priv_ra8_svgp_apply_xform | ( | svg_xform_t * | t, |
| const uint8_t * | tag, | ||
| size_t | tlen ) |
Compose the 'transform=' attribute from tag onto t's user affine.
Looks up the "transform" attribute in tag[0..tlen) using priv_ra8_svgp_attr. If absent, returns without modification. If found, parses the value via internal_parse_xform and composes the result over the current user affine in t using internal_utf_compose, then writes the composed components back to t->ua .. t->uf. The viewBox and box fields of t are not touched.
| [in,out] | t | Transform whose user affine is updated in place; must not be NULL. |
| [in] | tag | Byte span of the element tag to search; must not be NULL. |
| [in] | tlen | Total valid bytes in tag. |
t is a valid non-NULL pointer to an initialised svg_xform_t. tag is a valid pointer to at least tlen bytes.t->ua .. t->uf reflect the newly composed affine. t is unchanged.Definition at line 785 of file reflow_svg_xform.c.
References svg_utf_t::a, svg_utf_t::b, svg_utf_t::c, svg_utf_t::d, svg_utf_t::e, svg_utf_t::f, internal_parse_xform(), internal_utf_compose(), priv_ra8_svgp_attr(), svg_xform_t::ua, svg_xform_t::ub, svg_xform_t::uc, svg_xform_t::ud, svg_xform_t::ue, and svg_xform_t::uf.
Referenced by internal_dispatch_shape(), and internal_group_open().
| bool priv_ra8_svgp_has_rot | ( | const svg_xform_t * | t | ) |
Test whether the user transform contains rotation or shear.
Checks whether t->ub or t->uc is non-zero. When either is non-zero, the axis-aligned fast-path primitives (ra8_gfx_rect, ra8_gfx_circle) cannot represent the shape correctly and callers must fall back to the polygon path via priv_ra8_svgp_map_point applied to each vertex.
| [in] | t | Active coordinate transform; must not be NULL. |
| true | t->ub != 0.0F or t->uc != 0.0F. |
| false | Both t->ub and t->uc are 0.0F (axis-aligned). |
t is a valid non-NULL pointer to an initialised svg_xform_t. t->ub and t->uc hold the shear terms of the current affine.t is not modified. t.Definition at line 118 of file reflow_svg_xform.c.
References svg_xform_t::ub, and svg_xform_t::uc.
Referenced by priv_ra8_svgp_draw_circle(), and priv_ra8_svgp_draw_rect().
| void priv_ra8_svgp_map_point | ( | const svg_xform_t * | t, |
| int32_t | ux, | ||
| int32_t | uy, | ||
| int32_t * | fx, | ||
| int32_t * | fy ) |
Map a user-space point through the FULL affine, then viewBox->box.
Generalized point map for rotated/sheared/gradient shapes. When the affine is axis-aligned (ub==0 && uc==0) the result is byte-identical to (priv_ra8_svgp_mx(ux), priv_ra8_svgp_my(uy)), so routing the polygon/path/line emitters through it does not change the untransformed render.
| [in] | t | Active transform; must not be NULL. |
| [in] | ux | User-space X coordinate to map. |
| [in] | uy | User-space Y coordinate to map. |
| [out] | fx | Set to the framebuffer X coordinate; must not be NULL. |
| [out] | fy | Set to the framebuffer Y coordinate; must not be NULL. |
t is a valid non-NULL pointer to an initialised svg_xform_t. fx and fy are valid non-NULL output pointers.*fx and *fy are set to the framebuffer-space coordinates. t, ux, and uy are not modified.Definition at line 148 of file reflow_svg_xform.c.
References svg_xform_t::bh, svg_xform_t::bw, svg_xform_t::bx, svg_xform_t::by, svg_xform_t::ua, svg_xform_t::ub, svg_xform_t::uc, svg_xform_t::ud, svg_xform_t::ue, svg_xform_t::uf, svg_xform_t::vh, svg_xform_t::vw, svg_xform_t::vx, and svg_xform_t::vy.
Referenced by internal_flatten_cubic(), internal_flatten_quad(), internal_parse_path(), internal_parse_points(), priv_ra8_svgp_draw_circle(), priv_ra8_svgp_draw_line(), priv_ra8_svgp_draw_rect(), and priv_ra8_svgp_flatten_arc().
| int32_t priv_ra8_svgp_mx | ( | const svg_xform_t * | t, |
| int32_t | sx ) |
Map a user-space x coordinate to a framebuffer x coordinate.
Applies the axis-aligned user transform via internal_ux, then maps the result through the viewBox-to-box scaling: bx + (ux - vx) * bw / vw. Uses 64-bit intermediate arithmetic to avoid overflow on large coordinates. Valid only when t->ub == 0.0F and t->uc == 0.0F; for the general case use priv_ra8_svgp_map_point.
| [in] | t | Active coordinate transform; must not be NULL. |
| [in] | sx | User-space X coordinate to map. |
sx. | n | The framebuffer pixel column for user-space column sx. |
t is a valid non-NULL pointer to an initialised svg_xform_t. t->vw is non-zero (the viewBox has a positive width).t->bx + (int32_t)(((ux - t->vx) * t->bw) / t->vw). t and sx are not modified.Definition at line 182 of file reflow_svg_xform.c.
References svg_xform_t::bw, svg_xform_t::bx, internal_ux(), svg_xform_t::vw, and svg_xform_t::vx.
Referenced by priv_ra8_svgp_draw_circle(), and priv_ra8_svgp_draw_rect().
| int32_t priv_ra8_svgp_my | ( | const svg_xform_t * | t, |
| int32_t | sy ) |
Map a user-space y coordinate to a framebuffer y coordinate.
Applies the axis-aligned user transform via internal_uy, then maps the result through the viewBox-to-box scaling: by + (uy - vy) * bh / vh. Uses 64-bit intermediate arithmetic to avoid overflow on large coordinates. Valid only when t->ub == 0.0F and t->uc == 0.0F; for the general case use priv_ra8_svgp_map_point.
| [in] | t | Active coordinate transform; must not be NULL. |
| [in] | sy | User-space Y coordinate to map. |
sy. | n | The framebuffer pixel row for user-space row sy. |
t is a valid non-NULL pointer to an initialised svg_xform_t. t->vh is non-zero (the viewBox has a positive height).t->by + (int32_t)(((uy - t->vy) * t->bh) / t->vh). t and sy are not modified.Definition at line 214 of file reflow_svg_xform.c.
References svg_xform_t::bh, svg_xform_t::by, internal_uy(), svg_xform_t::vh, and svg_xform_t::vy.
Referenced by priv_ra8_svgp_draw_circle(), and priv_ra8_svgp_draw_rect().
| float priv_ra8_svgp_numf | ( | const uint8_t * | s, |
| size_t | len, | ||
| size_t * | i ) |
Parse one SVG floating-point number at s[*i], skipping leading separators.
Parse one SVG floating-point number at s[*i], skipping separators.
Advances *i past whitespace and comma separators, reads an optional sign ('+'/'-'), then accumulates integer digit characters into v. If a decimal point follows, fractional digits are accumulated with decreasing place values. On return, *i points one past the last character consumed so subsequent calls parse the next number correctly. Used for all floating-point geometry values including path curve control-point coordinates and arc parameters.
| [in] | s | Byte buffer holding the SVG text; must not be NULL. |
| [in] | len | Total valid bytes in s. |
| [in,out] | i | Current parse cursor; updated to one past the consumed number. |
s[*i]. | 0.0F | No digit characters found after the sign (or no sign/digits at all). |
| n | The parsed value, including integer and fractional parts. |
s is a valid pointer to at least len bytes. i is not NULL, and *i is <= len.*i is advanced past separators, sign, integer digits, and fraction. *i <= len.Definition at line 280 of file reflow_svg_xform.c.
References k_svg_dec, and priv_ra8_svgp_ws().
Referenced by internal_attr_numf(), internal_stop_offset(), and internal_xform_read().
| int32_t priv_ra8_svgp_sx | ( | const svg_xform_t * | t, |
| int32_t | sw ) |
Scale a user-space length by the user x scale and the viewBox x ratio.
Applies the user x scale (t->ua) to the width sw, then scales the result by the viewBox-to-box x ratio (bw / vw). Uses 64-bit intermediate arithmetic to avoid overflow. Returns the framebuffer pixel count corresponding to sw user-space units. Valid only on the axis-aligned fast path.
| [in] | t | Active coordinate transform; must not be NULL. |
| [in] | sw | User-space width (or length) to scale. |
sw user units. | n | The scaled pixel count, truncated to int32_t. |
t is a valid non-NULL pointer to an initialised svg_xform_t. t->vw is non-zero (the viewBox has a positive width).t and sw are not modified.Definition at line 245 of file reflow_svg_xform.c.
References svg_xform_t::bw, svg_xform_t::ua, and svg_xform_t::vw.
Referenced by priv_ra8_svgp_draw_circle(), and priv_ra8_svgp_draw_rect().