4 Path Data
These functions parse the d attribute’s path-data mini-language (the
same grammar used by <path>, and by SVG2’s d CSS property) and turn
it into dc-path% objects ready to hand to a dc<%>. They
cover the full grammar —
The parsing is split into two stages, each independently useful:
parse-svg-path turns a d string into a list of path commands —
a small, inspectable, symbolic representation (e.g. '((M (10 20)) (L (30 40)) (Z))) — without touching racket/draw at all. Use this if you want to inspect, transform, or generate path data programmatically. svg-path->dc-paths turns that command list into actual dc-path% objects. Use this once you have commands (whether from parse-svg-path or built by hand) and want something to actually draw.
path-data->dc-paths is the two stages composed, for the common case of going straight from a d string to dc-path%s. All three feed the same downstream geometry, shown here once as a filled triangle:

4.1 The path-command format
parse-svg-path represents each path-data command as a list whose
first element is a symbol naming the command (matching the SVG letter
exactly, including case —
Command(s) |
| Shape |
| Example |
M, m |
| one coordinate pair |
| (M (10 20)) |
L, l |
| one or more coordinate pairs |
| (L (10 20) (30 40)) |
H, h |
| one or more bare numbers (x only) |
| (H 10 30) |
V, v |
| one or more bare numbers (y only) |
| (V 10 30) |
C, c |
| one or more (x1 y1) (x2 y2) (x y) triplets |
| (C (1 2) (3 4) (5 6)) |
S, s |
| one or more (x2 y2) (x y) pairs |
| (S (3 4) (5 6)) |
Q, q |
| one or more (qx qy) (x y) pairs |
| (Q (3 4) (5 6)) |
T, t |
| one or more coordinate pairs |
| (T (5 6)) |
A, a |
| one or more (rx ry rot large-arc sweep x y) |
| (A (10 10 0 0 1 20 20)) |
Z, z |
| no arguments |
| (Z) |
A repeated command (e.g. "L 10 20 30 40") produces one list entry
with all of its repetitions as separate arguments, not one entry per
repetition —
A syntax error partway through a d string does not raise —
> (parse-svg-path "M 10 20 L 30 40 Z") '((M (10 20)) (L (30 40)) (Z))
> (parse-svg-path "M 0 0 L 3 -4 Z # not valid path syntax") '((M (0 0)) (L (3 -4)) (Z))
procedure
(parse-svg-path x) → (listof list?)
x : (or/c string? input-port?)
> (parse-svg-path "M0,0 H100 V100 H0 Z") '((M (0 0)) (H 100) (V 100) (H 0) (Z))
(define paths (svg-path->dc-paths (parse-svg-path "M0,0 L50,0 L25,50 Z"))) (send dc draw-path (first paths) 0 0)
procedure
(path-data->dc-paths d) → (listof (is-a?/c dc-path%))
d : string?
(path-data->dc-paths "M0,0 L50,0 L25,50 Z")
procedure
(elliptical-arc-dc-path x1 y1 x2 y2 rx ry x-axis-rotation-deg large-arc-flag sweep-flag) → (is-a?/c dc-path%) x1 : real? y1 : real? x2 : real? y2 : real? rx : real? ry : real? x-axis-rotation-deg : real? large-arc-flag : (or/c 0 1) sweep-flag : (or/c 0 1)
Degenerate inputs (rx or ry of 0, or an identical
start and end point) are the caller’s responsibility to handle —
(elliptical-arc-dc-path 0 0 50 50 50 50 0 0 1)
