PathLib — Vector Path Shape Library
Paths are complex shapes defined by a series of drawing commands — move, line, curve, arc — using SVG-like path data syntax or programmatic construction. Paths are ideal for custom shapes, icons, logos, diagrams, and complex vector graphics. Supports cubic and quadratic Bézier curves, elliptical arcs, predefined shape helpers, and path transformations. 107 functions.
| Category | Count | Description |
|---|---|---|
| Error Handling | 4 | path_error, errormsg$, strerror$, clearerror |
| Creation & Destruction | 4 | path# (3 overloads), path_free |
| Path Data (String) | 2 | path_data$ (get), path_data# (set from SVG string) |
| Drawing Commands | 9 | moveto, lineto, hlineto, vlineto, curveto, smoothcurveto, quadcurveto, closepath, clear |
| Predefined Shapes | 3 | addrectangle#, addellipse#, addarc# |
| Transformations | 3 | scale#, translate#, rotate# |
| Path Information | 7 | pointcount, lastx, lasty, boundsx, boundsy, boundswidth, boundsheight |
| Wrap Mode | 2 | wrapmode (get/set) |
| Fill | 3 | fill$ (get), fill# (set), fillnone# |
| Stroke | 11 | stroke$ / stroke# / strokenone#, thickness, dash, cap, join (get/set) |
| Position & Size | 11 | x, y, width, height (get/set), bounds#, move#, size# |
| Alignment & Margins | 12 | align (get/set), margin#, margins#, marginleft/top/right/bottom (get/set) |
| Visibility & State | 8 | visible, enabled, opacity, hittest (get/set) |
| Tag, Rotation & Parent | 9 | tag, rotation (get/set), parent# (get/set), bringtofront#, sendtoback#, invalidate# |
| Events | 19 | 9 event types × set/get + clearcallbacks# |
Cross-Platform Support
| Platform | Status | Notes |
|---|---|---|
| Windows | ✅ Full Support | Win32/Win64 |
| Linux | ✅ Full Support | GTK-based |
| Android | ✅ Full Support | Hardware-accelerated |
Error Handling
| Function | Signature | Description |
|---|---|---|
path_error() | path_error@ | Last error code (0 = no error) |
path_errormsg$() | path_errormsg$@ | Last error message as string |
path_strerror$(code) | path_strerror$@n | Description for a given error code |
path_clearerror() | path_clearerror@ | Clear the error state |
SVG Path Data Syntax
The path_data#() function accepts SVG-like path data strings. Each command is a letter followed by coordinates:
| Command | Parameters | Description |
|---|---|---|
M x,y | Move to | Start a new subpath at (x, y) |
L x,y | Line to | Draw a straight line to (x, y) |
H x | Horizontal line | Draw horizontal line to x |
V y | Vertical line | Draw vertical line to y |
C x1,y1 x2,y2 x,y | Cubic bézier | Curve with two control points |
S x2,y2 x,y | Smooth cubic | Smooth continuation of previous curve |
Q x1,y1 x,y | Quadratic bézier | Curve with single control point |
T x,y | Smooth quadratic | Smooth continuation of previous quadratic |
A rx,ry rot large,sweep x,y | Elliptical arc | Arc segment of an ellipse |
Z | Close path | Close current subpath back to last M |
' Square using SVG path data path_data#(pth#, "M 10,10 L 190,10 L 190,190 L 10,190 Z") ' Triangle path_data#(pth#, "M 100,0 L 200,173 L 0,173 Z") ' Smooth curve path_data#(pth#, "M 0,100 C 50,0 100,0 150,100 S 250,200 300,100")
Path Data (String-Based)
| Function | Signature | Description |
|---|---|---|
path_data$(path#) | path_data$@# | Get current path data as SVG string |
path_data#(path#, data$) | path_data#@#$ | Set path data from SVG string |
path_data# replaces all existing path data. To append to existing data, use the programmatic drawing commands instead.Drawing Commands (Programmatic)
Build paths step by step using programmatic commands. These commands append to the current path data.
| Function | Signature | Description |
|---|---|---|
path_moveto#(path#, x, y) | path_moveto#@#nn | Move pen to point (M command) |
path_lineto#(path#, x, y) | path_lineto#@#nn | Draw line to point (L command) |
path_hlineto#(path#, x) | path_hlineto#@#n | Horizontal line to x (H command) |
path_vlineto#(path#, y) | path_vlineto#@#n | Vertical line to y (V command) |
path_curveto#(path#, x1, y1, x2, y2, x, y) | path_curveto#@#nnnnnn | Cubic bézier curve (C command) |
path_smoothcurveto#(path#, x2, y2, x, y) | path_smoothcurveto#@#nnnn | Smooth cubic bézier (S command) |
path_quadcurveto#(path#, x1, y1, x, y) | path_quadcurveto#@#nnnn | Quadratic bézier curve (Q command) |
path_closepath#(path#) | path_closepath#@# | Close current subpath (Z command) |
path_clear#(path#) | path_clear#@# | Clear all path data |
' Build a house shape programmatically path_moveto#(pth#, 150, 0) path_lineto#(pth#, 300, 100) path_lineto#(pth#, 300, 200) path_lineto#(pth#, 0, 200) path_lineto#(pth#, 0, 100) path_closepath#(pth#)
Predefined Shapes
Helper functions that add common shapes to the current path. These append to existing path data, allowing multiple shapes in one path.
| Function | Signature | Description |
|---|---|---|
path_addrectangle#(path#, x, y, w, h, rx, ry) | path_addrectangle#@#nnnnnn | Add rounded rectangle (rx, ry = corner radii) |
path_addellipse#(path#, x, y, w, h) | path_addellipse#@#nnnn | Add ellipse at position with size |
path_addarc#(path#, x, y, w, h, start, sweep) | path_addarc#@#nnnnnn | Add arc (start/sweep in degrees) |
' Rounded rectangle with 10px radius corners path_addrectangle#(pth#, 0, 0, 150, 100, 10, 10) ' Ellipse path_addellipse#(pth#, 200, 0, 100, 80) ' Arc: 90-degree sweep starting at 0 degrees path_addarc#(pth#, 50, 150, 100, 100, 0, 90)
Path Transformations
Transform the path data itself (not the control bounds). These modify the actual point coordinates in the path.
| Function | Signature | Description |
|---|---|---|
path_scale#(path#, scaleX, scaleY) | path_scale#@#nn | Scale path data by factors |
path_translate#(path#, dx, dy) | path_translate#@#nn | Translate (shift) path data |
path_rotate#(path#, angle) | path_rotate#@#n | Rotate path data in degrees |
path_x#/path_y# or path_rotation# to transform the control’s visual position on screen.Path Information
| Function | Signature | Description |
|---|---|---|
path_pointcount(path#) | path_pointcount@# | Number of points in the path |
path_lastx(path#) | path_lastx@# | X coordinate of the last point |
path_lasty(path#) | path_lasty@# | Y coordinate of the last point |
path_boundsx(path#) | path_boundsx@# | X of path data bounding box |
path_boundsy(path#) | path_boundsy@# | Y of path data bounding box |
path_boundswidth(path#) | path_boundswidth@# | Width of path data bounding box |
path_boundsheight(path#) | path_boundsheight@# | Height of path data bounding box |
Wrap Mode
Controls how the path data is rendered within the control’s bounds:
| Value | Mode | Description |
|---|---|---|
| 0 | Original | Render at original path size, positioned at top-left |
| 1 | Fit | Scale to fit within bounds, maintaining aspect ratio |
| 2 | Stretch | Stretch to fill bounds (default) |
| 3 | Tile | Repeat path to fill the area |
| Function | Signature | Description |
|---|---|---|
path_wrapmode(path#) | path_wrapmode@# | Get current wrap mode |
path_wrapmode#(path#, mode) | path_wrapmode#@#n | Set wrap mode (0–3) |
' Fit path within bounds keeping aspect ratio path_wrapmode#(pth#, 1) ' Use original size (no scaling) path_wrapmode#(pth#, 0)
Numeric Values Reference
Control Alignment path_align#
| Value | Description |
|---|---|
| 0 | None (absolute positioning) |
| 1 | Top |
| 2 | Left |
| 3 | Right |
| 4 | Bottom |
| 9 | Client (fill parent) |
Stroke Dash Style path_strokedash#
| Value | Style |
|---|---|
| 0 | Solid |
| 1 | Dash |
| 2 | Dot |
| 3 | DashDot |
| 4 | DashDotDot |
Stroke Cap Style path_strokecap#
| Value | Style |
|---|---|
| 0 | Flat |
| 1 | Round |
Stroke Join Style path_strokejoin#
| Value | Style |
|---|---|
| 0 | Miter |
| 1 | Round |
| 2 | Bevel |
Creation & Destruction
| Function | Signature | Description |
|---|---|---|
path#(parent#) | path#@# | Create with default size |
path#(parent#, w, h) | path#@#nn | Create with specified size |
path#(parent#, x, y, w, h) | path#@#nnnn | Create with position and size |
path_free(path#) | path_free@# | Destroy path shape |
' Triangle using SVG path data let pth# = path#(frm#, 50, 50, 200, 200) path_data#(pth#, "M 100,0 L 200,173 L 0,173 Z") path_fill#(pth#, "#3498db") path_stroke#(pth#, "#2c3e50") path_strokethickness#(pth#, 2)
Fill Properties
| Function | Signature | Description |
|---|---|---|
path_fill$(path#) | path_fill$@# | Get fill color as hex string |
path_fill#(path#, color$) | path_fill#@#$ | Set fill color ("#RRGGBB" or "#AARRGGBB") |
path_fillnone#(path#) | path_fillnone#@# | Remove fill (transparent) |
path_fillnone# for stroke-only outlines. This is common for icons, wireframe shapes, and decorative curves.Stroke Properties
| Function | Signature | Description |
|---|---|---|
path_stroke$(path#) | path_stroke$@# | Get stroke color |
path_stroke#(path#, color$) | path_stroke#@#$ | Set stroke color |
path_strokenone#(path#) | path_strokenone#@# | Remove stroke (no border) |
path_strokethickness(path#) | path_strokethickness@# | Get stroke thickness |
path_strokethickness#(path#, n) | path_strokethickness#@#n | Set stroke thickness |
path_strokedash(path#) | path_strokedash@# | Get dash style (0–4) |
path_strokedash#(path#, n) | path_strokedash#@#n | Set dash style |
path_strokecap(path#) | path_strokecap@# | Get cap style (0=Flat, 1=Round) |
path_strokecap#(path#, n) | path_strokecap#@#n | Set cap style |
path_strokejoin(path#) | path_strokejoin@# | Get join style (0=Miter, 1=Round, 2=Bevel) |
path_strokejoin#(path#, n) | path_strokejoin#@#n | Set join style |
path_strokejoin#(pth#, 1)) look significantly better on paths with sharp angles. For smooth curves, round stroke caps (path_strokecap#(pth#, 1)) improve the visual endpoints.Position & Size
| Function | Signature | Description |
|---|---|---|
path_x(path#) | path_x@# | Get X position |
path_x#(path#, x) | path_x#@#n | Set X position |
path_y(path#) | path_y@# | Get Y position |
path_y#(path#, y) | path_y#@#n | Set Y position |
path_width(path#) | path_width@# | Get width |
path_width#(path#, w) | path_width#@#n | Set width |
path_height(path#) | path_height@# | Get height |
path_height#(path#, h) | path_height#@#n | Set height |
path_bounds#(path#, x, y, w, h) | path_bounds#@#nnnn | Set position and size |
path_move#(path#, x, y) | path_move#@#nn | Set position only |
path_size#(path#, w, h) | path_size#@#nn | Set size only |
Alignment & Margins
| Function | Signature | Description |
|---|---|---|
path_align(path#) | path_align@# | Get alignment |
path_align#(path#, n) | path_align#@#n | Set alignment |
path_margin#(path#, n) | path_margin#@#n | Set uniform margin on all four sides |
path_margins#(path#, l, t, r, b) | path_margins#@#nnnn | Set individual margins |
path_marginleft(path#) | path_marginleft@# | Get left margin |
path_marginleft#(path#, n) | path_marginleft#@#n | Set left margin |
path_margintop(path#) | path_margintop@# | Get top margin |
path_margintop#(path#, n) | path_margintop#@#n | Set top margin |
path_marginright(path#) | path_marginright@# | Get right margin |
path_marginright#(path#, n) | path_marginright#@#n | Set right margin |
path_marginbottom(path#) | path_marginbottom@# | Get bottom margin |
path_marginbottom#(path#, n) | path_marginbottom#@#n | Set bottom margin |
Visibility & State
| Function | Signature | Description |
|---|---|---|
path_visible(path#) | path_visible@# | Get visibility (0/1) |
path_visible#(path#, n) | path_visible#@#n | Set visibility |
path_enabled(path#) | path_enabled@# | Get enabled state (0/1) |
path_enabled#(path#, n) | path_enabled#@#n | Set enabled state |
path_opacity(path#) | path_opacity@# | Get opacity (0.0–1.0) |
path_opacity#(path#, n) | path_opacity#@#n | Set opacity |
path_hittest(path#) | path_hittest@# | Get hit-test state (0/1) |
path_hittest#(path#, n) | path_hittest#@#n | Enable/disable mouse hit testing |
path_hittest#(path#, 1) before assigning mouse event handlers. Without hit testing, the path will not receive mouse events.Tag, Rotation & Parent
| Function | Signature | Description |
|---|---|---|
path_tag(path#) | path_tag@# | Get user-defined integer tag |
path_tag#(path#, n) | path_tag#@#n | Set user-defined integer tag |
path_rotation(path#) | path_rotation@# | Get rotation angle in degrees |
path_rotation#(path#, angle) | path_rotation#@#n | Set rotation angle |
path_parent#(path#) | path_parent#@# | Get parent control pointer |
path_parent#(path#, parent#) | path_parent#@## | Move to a different parent |
path_bringtofront#(path#) | path_bringtofront#@# | Bring to front of Z-order |
path_sendtoback#(path#) | path_sendtoback#@# | Send to back of Z-order |
path_invalidate#(path#) | path_invalidate#@# | Force the path to redraw |
path_rotation# rotates the entire control visually around its center. This is different from path_rotate#, which transforms the path data geometry itself. Use path_rotation# for visual rotation and path_rotate# to permanently modify path coordinates.Events
Each event has a setter (path_onXXX#) and a getter (path_onXXX$). Use path_clearcallbacks#(path#) to disconnect all callbacks at once.
Mouse Events
| Event Setter | Getter | Callback Signature |
|---|---|---|
path_onclick#(path#, func$) | path_onclick$(path#) | function name(sender#) |
path_ondblclick#(path#, func$) | path_ondblclick$(path#) | function name(sender#) |
path_onmousedown#(path#, func$) | path_onmousedown$(path#) | function name(sender#, button, x, y, shift$) |
path_onmouseup#(path#, func$) | path_onmouseup$(path#) | function name(sender#, button, x, y, shift$) |
path_onmousemove#(path#, func$) | path_onmousemove$(path#) | function name(sender#, x, y, shift$) |
path_onmouseenter#(path#, func$) | path_onmouseenter$(path#) | function name(sender#) |
path_onmouseleave#(path#, func$) | path_onmouseleave$(path#) | function name(sender#) |
path_onmousewheel#(path#, func$) | path_onmousewheel$(path#) | function name(sender#, delta) |
Other Events
| Event Setter | Getter | Callback Signature |
|---|---|---|
path_onresize#(path#, func$) | path_onresize$(path#) | function name(sender#) |
path_clearcallbacks#(path#) | — | Disconnect all event callbacks |
Complete Examples
Triangle
let frm# = form#("Triangle", 300, 300) form_position#(frm#, 4) let pth# = path#(frm#, 50, 50, 200, 200) path_data#(pth#, "M 100,0 L 200,173 L 0,173 Z") path_fill#(pth#, "#e74c3c") path_stroke#(pth#, "#c0392b") path_strokethickness#(pth#, 2) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Star Shape
let frm# = form#("Star", 300, 300) form_position#(frm#, 4) let pth# = path#(frm#, 50, 50, 200, 200) path_data#(pth#, "M 100,0 L 130,70 L 200,70 L 145,115 L 165,190 L 100,145 L 35,190 L 55,115 L 0,70 L 70,70 Z") path_fill#(pth#, "#f1c40f") path_stroke#(pth#, "#f39c12") path_strokethickness#(pth#, 2) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Programmatic House Shape
let frm# = form#("House", 400, 300) form_position#(frm#, 4) let pth# = path#(frm#, 50, 30, 300, 230) ' Build house shape step by step path_moveto#(pth#, 150, 0) path_lineto#(pth#, 300, 100) path_lineto#(pth#, 300, 230) path_lineto#(pth#, 0, 230) path_lineto#(pth#, 0, 100) path_closepath#(pth#) path_fill#(pth#, "#3498db") path_stroke#(pth#, "#2980b9") path_strokethickness#(pth#, 3) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Bézier Curves
let frm# = form#("Bezier Curves", 400, 300) form_position#(frm#, 4) let pth# = path#(frm#, 50, 50, 300, 200) path_data#(pth#, "M 0,100 C 50,0 100,0 150,100 S 250,200 300,100") path_fillnone#(pth#) path_stroke#(pth#, "#9b59b6") path_strokethickness#(pth#, 4) path_strokecap#(pth#, 1) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Combined Shapes
let frm# = form#("Combined Shapes", 400, 350) form_position#(frm#, 4) let pth# = path#(frm#, 20, 20, 360, 300) ' Rounded rectangle path_addrectangle#(pth#, 0, 0, 150, 100, 10, 10) ' Ellipse path_addellipse#(pth#, 200, 0, 100, 80) ' Custom triangle path_moveto#(pth#, 50, 150) path_lineto#(pth#, 150, 150) path_lineto#(pth#, 100, 230) path_closepath#(pth#) path_fill#(pth#, "#2ecc71") path_stroke#(pth#, "#27ae60") path_strokethickness#(pth#, 2) form_show(frm#) while form_visible(frm#) = 1 processmessages() end while
Interactive Path with Click Events
let frm# = form#("Click the Star", 300, 350) form_position#(frm#, 4) let clicks = 0 let star# = path#(frm#, 50, 30, 200, 200) path_data#(star#, "M 100,0 L 130,70 L 200,70 L 145,115 L 165,190 L 100,145 L 35,190 L 55,115 L 0,70 L 70,70 Z") path_fill#(star#, "#f1c40f") path_stroke#(star#, "#f39c12") path_strokethickness#(star#, 2) path_hittest#(star#, 1) path_onclick#(star#, "OnStarClick") let lbl# = label#(frm#, "Clicks: 0") label_bounds#(lbl#, 100, 260, 100, 25) label_textalign#(lbl#, 0) form_show(frm#) function OnStarClick(sender#) clicks = clicks + 1 label_text#(lbl#, "Clicks: " + str$(clicks)) ' Rotate star on each click path_rotation#(star#, clicks * 15) endfunction while form_visible(frm#) = 1 processmessages() end while
Best Practices
| Practice | Why |
|---|---|
Use path_data# for static shapes | SVG strings are compact and easy to copy from design tools |
| Use programmatic commands for dynamic shapes | moveto/lineto allow building paths from computed data |
Call path_clear# before rebuilding a path | Programmatic commands append; clear first to avoid accumulation |
Use path_strokejoin#(pth#, 1) for round joins | Much better visual on sharp-angled paths (stars, arrows) |
Use path_fillnone# for stroke-only outlines | Common for icons, wireframes, and decorative curves |
Set hittest = 1 for interactive paths | Required for mouse events to fire on the path |
Prefer wrapmode = 1 (Fit) for scalable icons | Maintains aspect ratio when control bounds change |
Use path_rotation# for visual rotation | Rotates the control visually; path_rotate# modifies geometry permanently |
Combine shapes with addrectangle#/addellipse# | Multiple sub-shapes in one path are more efficient than separate controls |
Quick Reference
| Function | Signature | Description |
|---|---|---|
path_error / errormsg$ / strerror$ / clearerror | various | Error handling (4) |
path#(parent#[, w, h] | [, x, y, w, h]) | various | Create (3 overloads) |
path_free(path#) | path_free@# | Destroy |
path_data$ / path_data# | various | Path data string (get/set) (2) |
path_moveto# / lineto# / hlineto# / vlineto# / curveto# / smoothcurveto# / quadcurveto# / closepath# / clear# | various | Programmatic drawing (9) |
path_addrectangle# / addellipse# / addarc# | various | Predefined shapes (3) |
path_scale# / translate# / rotate# | various | Transformations (3) |
path_pointcount / lastx / lasty / boundsx / boundsy / boundswidth / boundsheight | various | Path info (7) |
path_wrapmode (get/set) | various | Wrap mode (2) |
path_fill$ / fill# / fillnone# | various | Fill (3) |
path_stroke$ / stroke# / strokenone# / strokethickness / strokedash / strokecap / strokejoin | various | Stroke (11) |
path_x/y/width/height (get/set) / bounds# / move# / size# | various | Position & size (11) |
path_align / margin# / margins# / margin[left/top/right/bottom] | various | Alignment & margins (12) |
path_visible / enabled / opacity / hittest | various | Visibility & state (8) |
path_tag / rotation / parent# / bringtofront# / sendtoback# / invalidate# | various | Tag, rotation & parent (9) |
path_onclick/ondblclick/onmousedown/up/move/enter/leave/onmousewheel/onresize | various | Events set+get (18) |
path_clearcallbacks# | path_clearcallbacks#@# | Disconnect all events |
107 functions. Part of the Plan9Basic GUI shape library system.