|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
SVG <path> d mini-language parser + Bezier flatten (#112). More...
Go to the source code of this file.
Data Structures | |
| struct | path_state_t |
| Running cursor state while parsing a <path> d string. More... | |
Functions | |
| static int32_t | internal_cmd_argc (char u) |
| Return the argument count for a lower-cased SVG path command letter. | |
| static void | internal_path_step (char u, bool rel, const int32_t *args, int32_t na, int32_t *cx, int32_t *cy) |
| Advance the current path point to the endpoint of a line-type command. | |
| static float | internal_bezier1 (float tt, float c0, float c1, float c2, float c3) |
Evaluate one axis of a cubic Bernstein-Bezier polynomial at parameter tt. | |
| static void | internal_flatten_cubic (const svg_xform_t *t, svg_pt_t p0, svg_pt_t p1, svg_pt_t p2, svg_pt_t p3, int32_t *xs, int32_t *ys, int32_t *n) |
| Flatten a cubic Bezier curve (P0..P3, user space) into the vertex array. | |
| static svg_pt_t | internal_arg_pt (bool rel, int32_t cx, int32_t cy, int32_t ax, int32_t ay) |
| Resolve an absolute or relative SVG point from an argument pair. | |
| static float | internal_bezier_q1 (float tt, float c0, float c1, float c2) |
Evaluate one axis of a quadratic Bernstein-Bezier polynomial at parameter tt. | |
| static void | internal_flatten_quad (const svg_xform_t *t, svg_pt_t p0, svg_pt_t p1, svg_pt_t p2, int32_t *xs, int32_t *ys, int32_t *n) |
| Flatten a quadratic Bezier curve (P0..P2, user space) into the vertex array. | |
| static svg_pt_t | internal_reflect (svg_pt_t cur, svg_pt_t ctrl) |
Reflect control point ctrl through current point cur. | |
| static svg_pt_t | internal_smooth_ctrl (svg_pt_t p0, const path_state_t *st, char want) |
| Derive the first control point for a smooth curve command. | |
| static int32_t | internal_emit_cubic (const svg_xform_t *t, svg_pt_t p0, svg_pt_t p1, svg_pt_t p2, svg_pt_t p3, path_state_t *st, int32_t *xs, int32_t *ys, int32_t n) |
| Flatten a cubic Bezier (P0..P3) into the vertex list and advance path state. | |
| static int32_t | internal_emit_quad (const svg_xform_t *t, svg_pt_t p0, svg_pt_t p1, svg_pt_t p2, path_state_t *st, int32_t *xs, int32_t *ys, int32_t n) |
| Flatten a quadratic Bezier (P0..P2) into the vertex list and advance path state. | |
| static int32_t | internal_path_curve (const svg_xform_t *t, char u, bool rel, const int32_t *args, path_state_t *st, int32_t *xs, int32_t *ys, int32_t n) |
| Flatten a cubic/quadratic path curve command into the vertex list. | |
| static char | internal_next_cmd (const uint8_t *d, size_t dlen, size_t *i, char *last) |
Resolve the next path command at d[*i]. | |
| static int32_t | internal_parse_path (const uint8_t *d, size_t dlen, const svg_xform_t *t, int32_t *xs, int32_t *ys) |
| Parse a path 'd' value into framebuffer-space vertices; return count. | |
| void | priv_ra8_svgp_draw_path (const uint8_t *s, size_t len, const svg_xform_t *t) |
| Draw one SVG 'path' element as a filled polygon. | |
SVG <path> d mini-language parser + Bezier flatten (#112).
The <path> d mini-language: M/L/H/V/Z exact, the cubic 'C'/'S' and quadratic 'Q'/'T' Bezier curves flattened to line segments (smooth forms reflect the previous control point), and the elliptical arc 'A' delegated to the shared arc flatten in reflow_svg_shape.c. The resulting vertices are filled by the shared scanline polygon fill. 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_path.c.
|
static |
Resolve an absolute or relative SVG point from an argument pair.
When rel is true, the result is the current point (cx, cy) plus the argument offsets (ax, ay). When rel is false, the result is simply (ax, ay) treated as an absolute user-space coordinate. Used throughout the path parser to interpret command arguments uniformly regardless of the command's case (uppercase = absolute, lowercase = relative).
| [in] | rel | True for relative coordinates; false for absolute. |
| [in] | cx | Current point X (user space); used only when rel is true. |
| [in] | cy | Current point Y (user space); used only when rel is true. |
| [in] | ax | X argument from the parsed path command. |
| [in] | ay | Y argument from the parsed path command. |
| {cx+ax,cy+ay} | When rel is true. |
| {ax,ay} | When rel is false. |
ax and ay are valid int32_t argument values. rel is true, cx and cy reflect the current path position.svg_pt_t. Definition at line 248 of file reflow_svg_path.c.
Referenced by internal_path_curve().
|
static |
Evaluate one axis of a cubic Bernstein-Bezier polynomial at parameter tt.
Computes the standard four-point cubic Bezier formula: (1-tt)^3 * c0 + 3*(1-tt)^2*tt * c1 + 3*(1-tt)*tt^2 * c2 + tt^3 * c3. Used by internal_flatten_cubic to sample x and y independently at each subdivision parameter value tt in (0, 1].
| [in] | tt | Parameter in [0, 1]; 0 returns c0, 1 returns c3. |
| [in] | c0 | Start control point value for this axis. |
| [in] | c1 | First interior control point value. |
| [in] | c2 | Second interior control point value. |
| [in] | c3 | End control point value for this axis. |
tt. | c0 | When tt is exactly 0.0F. |
| c3 | When tt is exactly 1.0F. |
tt is a finite float in [0.0F, 1.0F]. c0, c1, c2, c3 are finite float values.tt. Definition at line 160 of file reflow_svg_path.c.
Referenced by internal_flatten_cubic().
|
static |
Evaluate one axis of a quadratic Bernstein-Bezier polynomial at parameter tt.
Computes the three-point quadratic Bezier formula: (1-tt)^2 * c0 + 2*(1-tt)*tt * c1 + tt^2 * c2. Used by internal_flatten_quad to sample x and y independently at each subdivision parameter.
| [in] | tt | Parameter in [0, 1]; 0 returns c0, 1 returns c2. |
| [in] | c0 | Start control point value for this axis. |
| [in] | c1 | Middle control point value. |
| [in] | c2 | End control point value for this axis. |
tt. | c0 | When tt is exactly 0.0F. |
| c2 | When tt is exactly 1.0F. |
tt is a finite float in [0.0F, 1.0F]. c0, c1, and c2 are finite float values.tt. Definition at line 296 of file reflow_svg_path.c.
Referenced by internal_flatten_quad().
|
static |
Return the argument count for a lower-cased SVG path command letter.
Maps each recognised lower-case path command to the number of numeric arguments it consumes: 'm'/'l'/'t' take 2 (x,y); 'h'/'v' take 1; 'c' takes 6; 's'/'q' take 4; 'a' takes 7; 'z' takes 0. Any unrecognised letter returns -1 so the caller can detect and stop parsing.
| [in] | u | Lower-cased path command letter to look up. |
u, or -1 if unrecognised. | 0 | 'z' (close path, no arguments). |
| 1 | 'h' or 'v' (horizontal/vertical line-to). |
| 2 | 'm', 'l', 't' (move-to, line-to, smooth quadratic). |
| 4 | 's' or 'q' (smooth cubic / quadratic). |
| 6 | 'c' (cubic Bezier). |
| 7 | 'a' (elliptical arc). |
| -1 | Unrecognised command letter. |
u is a lower-case ASCII character or any other char value. u is not modified.Definition at line 60 of file reflow_svg_path.c.
References k_svg_argc_cube, k_svg_argc_quad, k_svg_path_args, and k_svg_path_ep.
Referenced by internal_parse_path().
|
static |
Flatten a cubic Bezier (P0..P3) into the vertex list and advance path state.
Calls internal_flatten_cubic to append sampled framebuffer vertices starting at index n, records P2 as the new smooth-curve control point in st->ctrl, sets st->kind to 'c', and advances st->cx / st->cy to P3. Returns the new vertex count. Used for 'C'/'c' and 'S'/'s' commands.
| [in] | t | Active coordinate transform; must not be NULL. |
| [in] | p0 | Start point in user space. |
| [in] | p1 | First control point in user space. |
| [in] | p2 | Second control point in user space (recorded as ctrl). |
| [in] | p3 | End point in user space (becomes new current point). |
| [in,out] | st | Path cursor state; must not be NULL; updated by this call. |
| [out] | xs | Vertex X array of at least k_svg_poly_max elements; must not be NULL. |
| [out] | ys | Vertex Y array of at least k_svg_poly_max elements; must not be NULL. |
| [in] | n | Vertex count before this call. |
| n..n+k_svg_curve_seg | Depending on how many samples fit before k_svg_poly_max. |
t is a valid non-NULL pointer to an initialised svg_xform_t. st, xs, and ys are valid non-NULL pointers.st->ctrl, st->kind, st->cx, and st->cy are updated. Definition at line 449 of file reflow_svg_path.c.
References path_state_t::ctrl, path_state_t::cx, path_state_t::cy, internal_flatten_cubic(), path_state_t::kind, svg_pt_t::x, and svg_pt_t::y.
Referenced by internal_path_curve().
|
static |
Flatten a quadratic Bezier (P0..P2) into the vertex list and advance path state.
Calls internal_flatten_quad to append sampled framebuffer vertices starting at index n, records P1 as the new smooth-curve control point in st->ctrl, sets st->kind to 'q', and advances st->cx / st->cy to P2. Returns the new vertex count. Used for 'Q'/'q' and 'T'/'t' commands.
| [in] | t | Active coordinate transform; must not be NULL. |
| [in] | p0 | Start point in user space. |
| [in] | p1 | Control point in user space (recorded as ctrl). |
| [in] | p2 | End point in user space (becomes new current point). |
| [in,out] | st | Path cursor state; must not be NULL; updated by this call. |
| [out] | xs | Vertex X array of at least k_svg_poly_max elements; must not be NULL. |
| [out] | ys | Vertex Y array of at least k_svg_poly_max elements; must not be NULL. |
| [in] | n | Vertex count before this call. |
| n..n+k_svg_curve_seg | Depending on how many samples fit before k_svg_poly_max. |
t is a valid non-NULL pointer to an initialised svg_xform_t. st, xs, and ys are valid non-NULL pointers.st->ctrl, st->kind, st->cx, and st->cy are updated. Definition at line 500 of file reflow_svg_path.c.
References path_state_t::ctrl, path_state_t::cx, path_state_t::cy, internal_flatten_quad(), path_state_t::kind, svg_pt_t::x, and svg_pt_t::y.
Referenced by internal_path_curve().
|
static |
Flatten a cubic Bezier curve (P0..P3, user space) into the vertex array.
Samples k_svg_curve_seg equally-spaced parameter values in (0,1] using internal_bezier1 for each axis, maps each sample through the full affine via priv_ra8_svgp_map_point, and appends the framebuffer-space point to xs[*n] / ys[*n], incrementing *n. Stops early when *n reaches k_svg_poly_max to avoid buffer overflow.
| [in] | t | Active coordinate transform; must not be NULL. |
| [in] | p0 | Start point in user space. |
| [in] | p1 | First control point in user space. |
| [in] | p2 | Second control point in user space. |
| [in] | p3 | End point in user space. |
| [out] | xs | Vertex X array of at least k_svg_poly_max elements; must not be NULL. |
| [out] | ys | Vertex Y array of at least k_svg_poly_max elements; must not be NULL. |
| [in,out] | n | Current vertex count; updated by the number of samples appended. |
t is a valid non-NULL pointer to an initialised svg_xform_t. xs, ys are valid arrays of at least k_svg_poly_max elements.*n is increased by at most k_svg_curve_seg. *n <= k_svg_poly_max on exit.Definition at line 198 of file reflow_svg_path.c.
References internal_bezier1(), k_svg_curve_seg, k_svg_poly_max, priv_ra8_svgp_map_point(), svg_pt_t::x, and svg_pt_t::y.
Referenced by internal_emit_cubic().
|
static |
Flatten a quadratic Bezier curve (P0..P2, user space) into the vertex array.
Samples k_svg_curve_seg equally-spaced parameter values in (0,1] using internal_bezier_q1 for each axis, maps each through the full affine via priv_ra8_svgp_map_point, and appends the framebuffer-space point to xs[*n] / ys[*n], incrementing *n. Stops early when *n reaches k_svg_poly_max to avoid buffer overflow.
| [in] | t | Active coordinate transform; must not be NULL. |
| [in] | p0 | Start point in user space. |
| [in] | p1 | Control point in user space. |
| [in] | p2 | End point in user space. |
| [out] | xs | Vertex X array of at least k_svg_poly_max elements; must not be NULL. |
| [out] | ys | Vertex Y array of at least k_svg_poly_max elements; must not be NULL. |
| [in,out] | n | Current vertex count; updated by the number of samples appended. |
t is a valid non-NULL pointer to an initialised svg_xform_t. xs, ys are valid arrays of at least k_svg_poly_max elements.*n is increased by at most k_svg_curve_seg. *n <= k_svg_poly_max on exit.Definition at line 332 of file reflow_svg_path.c.
References internal_bezier_q1(), k_svg_curve_seg, k_svg_poly_max, priv_ra8_svgp_map_point(), svg_pt_t::x, and svg_pt_t::y.
Referenced by internal_emit_quad().
|
static |
Resolve the next path command at d[*i].
Skips leading whitespace and commas, then reads the next character. If it is an ASCII letter ('A'-'Z' or 'a'-'z'), that letter is stored in *last, *i is advanced past it, and the letter is returned. If the next character is not a letter (implicit argument repeat), *last is returned unchanged (the previous command letter). Returns 0 at end-of-buffer.
| [in] | d | Path 'd' attribute byte span; must not be NULL. |
| [in] | dlen | Total valid bytes in d. |
| [in,out] | i | Parse cursor; advanced past the command letter when found. |
| [in,out] | last | Last explicit command letter seen; updated when a new letter is consumed. |
| 'A'..'Z' | or 'a'..'z' The command letter (new or repeated from *last). |
| 0 | *i >= dlen (end of buffer). |
d is a valid pointer to at least dlen bytes. i and last are valid non-NULL pointers.*i is advanced past the command letter when an explicit letter is consumed. *last holds the most recently seen explicit command letter.Definition at line 622 of file reflow_svg_path.c.
References priv_ra8_svgp_ws().
Referenced by internal_parse_path().
|
static |
Parse a path 'd' value into framebuffer-space vertices; return count.
Handles M/L/H/V/Z exactly (absolute + relative, with implicit-L repeats after M); the cubic 'C'/'c', smooth cubic 'S'/'s', quadratic 'Q'/'q', smooth quadratic 'T'/'t', and elliptical arc 'A'/'a' are flattened into the vertex array (smooth forms reflect the previous control point, arcs are centre-parametrised). Multiple subpaths are merged into one polygon. 'Z' is silently accepted and the implicit close is handled by the polygon fill.
| [in] | d | Byte span holding the 'd' attribute value; must not be NULL. |
| [in] | dlen | Total valid bytes in d. |
| [in] | t | Active coordinate transform; must not be NULL. |
| [out] | xs | Vertex X array of at least k_svg_poly_max elements; must not be NULL. |
| [out] | ys | Vertex Y array of at least k_svg_poly_max elements; must not be NULL. |
xs / ys. | 0 | No valid path commands produced any vertices. |
| 1..k_svg_poly_max | Count of framebuffer-space vertices. |
d is a valid pointer to at least dlen bytes. xs and ys are valid arrays of at least k_svg_poly_max elements.xs[0..return-1] and ys[0..return-1] hold framebuffer coordinates. Definition at line 672 of file reflow_svg_path.c.
References path_state_t::cx, path_state_t::cy, internal_cmd_argc(), internal_next_cmd(), internal_path_curve(), internal_path_step(), k_svg_path_args, k_svg_poly_max, path_state_t::kind, priv_ra8_svgp_lc(), priv_ra8_svgp_map_point(), and priv_ra8_svgp_num().
Referenced by priv_ra8_svgp_draw_path().
|
static |
Flatten a cubic/quadratic path curve command into the vertex list.
Handles 'C'/'c', 'S'/'s' (smooth cubic), 'Q'/'q', 'T'/'t' (smooth quadratic), and the elliptical arc 'A'/'a'; 'S'/'T' reflect the previous matching control point via internal_smooth_ctrl, and the arc is centre- parametrised and sampled via priv_ra8_svgp_flatten_arc. Returns -1 for any other command so the caller falls back to the endpoint-chord path (M/L/H/V/Z).
| [in] | t | Active coordinate transform; must not be NULL. |
| [in] | u | Lower-case path command letter. |
| [in] | rel | True for relative coordinates. |
| [in] | args | Parsed integer arguments; must not be NULL. |
| [in,out] | st | Path cursor state; must not be NULL; updated when curve is consumed. |
| [out] | xs | Vertex X array of at least k_svg_poly_max elements; must not be NULL. |
| [out] | ys | Vertex Y array of at least k_svg_poly_max elements; must not be NULL. |
| [in] | n | Vertex count before this call. |
u is not a supported curve command. | -1 | u is not 'q', 't', 'c', 's', or 'a'. |
| n.. | New vertex count after flattening the curve. |
t, args, st, xs, and ys are valid non-NULL pointers. n is in [0, k_svg_poly_max].st is updated with the new current point. Definition at line 552 of file reflow_svg_path.c.
References path_state_t::cx, path_state_t::cy, internal_arg_pt(), internal_emit_cubic(), internal_emit_quad(), internal_smooth_ctrl(), k_svg_arc_ex, k_svg_arc_ey, path_state_t::kind, priv_ra8_svgp_flatten_arc(), svg_pt_t::x, and svg_pt_t::y.
Referenced by internal_parse_path().
|
static |
Advance the current path point to the endpoint of a line-type command.
Handles the endpoint-update logic for 'h' (horizontal line-to), 'v' (vertical line-to), and all other commands that terminate with an (x,y) endpoint pair as the last two args. For relative commands (rel true) the new position is added to the current point; for absolute commands it replaces it. Curve commands should call internal_emit_cubic / internal_emit_quad instead as they carry additional control-point state.
| [in] | u | Lower-case command letter determining the update rule. |
| [in] | rel | True for relative, false for absolute coordinates. |
| [in] | args | Array of at least na parsed integer arguments; must not be NULL. |
| [in] | na | Count of valid entries in args. |
| [in,out] | cx | Current point X; updated by this function. |
| [in,out] | cy | Current point Y; updated by this function. |
args is a valid pointer to at least na int32_t values. cx and cy are valid non-NULL pointers.*cx and *cy reflect the endpoint of the command. args is not modified.Definition at line 114 of file reflow_svg_path.c.
References k_svg_path_ep.
Referenced by internal_parse_path().
Reflect control point ctrl through current point cur.
Computes the point that is the reflection of ctrl across cur: result = (2*cur.x - ctrl.x, 2*cur.y - ctrl.y). This is the SVG rule for deriving the implicit first control point of a smooth cubic ('S'/'s') or smooth quadratic ('T'/'t') curve from the previous command's last control.
| [in] | cur | The current path point (pivot of the reflection). |
| [in] | ctrl | The control point to reflect. |
| {2*cur.x-ctrl.x,2*cur.y-ctrl.y} | Always. |
cur and ctrl are valid svg_pt_t values in user space. ctrl through cur. cur and ctrl are not modified.Definition at line 376 of file reflow_svg_path.c.
References svg_pt_t::x, and svg_pt_t::y.
Referenced by internal_smooth_ctrl().
|
static |
Derive the first control point for a smooth curve command.
Returns the reflection of st->ctrl through p0 when st->kind equals want (i.e. the previous command was a matching curve type); otherwise returns p0 itself (the SVG specification says "assume
the control point coincides with the current point"). This implements the smooth commands 'S'/'s' (want='c') and 'T'/'t' (want='q').
| [in] | p0 | Current path point (used as fallback and pivot for reflection). |
| [in] | st | Current path cursor state; must not be NULL. |
| [in] | want | Expected previous command kind ('c' for S, 'q' for T). |
| internal_reflect(p0,st->ctrl) | When st->kind == want. |
| p0 | Otherwise. |
st is a valid non-NULL pointer to an initialised path_state_t. p0 is the current user-space path position.svg_pt_t. p0, st, and want are not modified.Definition at line 411 of file reflow_svg_path.c.
References path_state_t::ctrl, internal_reflect(), and path_state_t::kind.
Referenced by internal_path_curve().
| void priv_ra8_svgp_draw_path | ( | const uint8_t * | s, |
| size_t | len, | ||
| const svg_xform_t * | t ) |
Draw one SVG 'path' element as a filled polygon.
Resolves the fill (solid or gradient via priv_ra8_svgp_resolve_fill), reads the 'd' attribute, parses it into framebuffer-space vertices via internal_parse_path, and fills the resulting polygon with priv_ra8_svgp_fill_poly or priv_ra8_svgp_fill_poly_grad. Returns without drawing when fill is absent/none or the 'd' attribute is missing.
| [in] | s | Byte span of the element tag; must not be NULL. |
| [in] | len | Total valid bytes in s. |
| [in] | t | Active coordinate transform; must not be NULL. |
s is a valid pointer to at least len bytes. t is a valid non-NULL pointer to an initialised svg_xform_t.Definition at line 753 of file reflow_svg_path.c.
References svg_grads::g, svg_xform_t::grads, internal_parse_path(), k_svg_def_fill, k_svg_no_paint, k_svg_poly_max, priv_ra8_svgp_attr(), priv_ra8_svgp_fill_poly(), priv_ra8_svgp_fill_poly_grad(), and priv_ra8_svgp_resolve_fill().
Referenced by internal_dispatch_shape().