The ctx text format is a direct serialization of the canvas API. This protocol permits sending rendering commands over serial, ptys and other forms of network - enabling remote and/or sandboxed rendering.
When used in the ctx terminal, the ctx rendering mode is entered by issuing the escape sequence \e[?200h this makes the terminal interpret commands for a ctx context created for the line the cursor currently is in. To end ctx mode transmit X or DONE .
The bash example ctx-clock.sh, renders an analog clock that scales with the terminal window.
#!/bin/bash echo -ne "\e[?1049h" # alt-screen on echo -ne "\e[?25l" # text-cursor off function cleanup { echo -ne " X " # leave ctx mode; in case we're there echo -ne "\e[?1049l" # alt-screen off echo -ne "\e[?25h" # text-cursor on } trap cleanup EXIT # restore terminal state on ctrl+c and regular exit for a in b{1..1000}; do hour_radians=`bc <<<"scale=3;(($(date +%H|sed 's/^0//')+($(date +%M|sed s'/^6//')/60.0))/12.0+0.75)*3.14152*2"` minute_radians=`bc <<<"scale=3;($(date +%M|sed 's/^0//')/60.0+0.75)*3.14152*2"` second_radians=`bc <<<"scale=3;($(date +%S|sed 's/^0//')/60.0+0.75)*3.14152*2"` radius=45 echo -ne "\e[2J\e[H" # clear screen and go to top left corner echo -e "\e[?200h" # enter ctx mode rgba 1 1 1 0.5 arc 50% 50% $radius% 0.0 6.4 0 lineWidth $((radius/10))% stroke lineCap round moveTo 50% 50% arc 50% 50% $(($radius * 70 / 100))% $minute_radians $minute_radians 0 moveTo 50% 50% arc 50% 50% $(($radius * 50 / 100))% $hour_radians $hour_radians 0 stroke lineWidth $((radius/40))% moveTo 50% 50% arc 50% 50% $((radius * 90 / 100))% $second_radians $second_radians 0 rgba 1 0.1 0.1 1 stroke done "; sleep 0.1; done
This format maps to the C API if you turn camelCase into snake_case, and prefix each command with ctx_.
When a keyword is parsed the parser expects a series of commands of the same type, following arguments will be consumed in chunks as the number of arguments fill up, until a command change. Each command also has a short one-byte long name, where applicable these match the SVG path data format.
gray | gray | sets gray source, and color model |
graya | gray alpha | sets gray alpha source, and color model |
rgb | r g b | sets rgb source |
rgba | r g b a | rgb alpha color source |
cmyk | c m y k | cmyk color source |
cmyka | c m y k a | cmyk alpha color source |
drgb | r g b | sets rgb source, in device space |
drgba | r g b a | rgb alpha color source, in device space |
dcmyk | c m y k | cmyk color source, in device space |
dcmyka | c m y k a | cmyk alpha color source, in device space |
a relArcTo | 5 | |
b clip | ||
c relCurveTo | 6 | |
d lineDash | 1-N | specify stroke dashing pattern, empty to reset |
e translate | x y | |
f linearGradient | x0 y0 x1 y1 | |
g save | ||
h relHorLine | x | |
ka globalAlpha | alpha | |
kb textBaseline | alphabetic | top | bottom | middle | hanging | ideographic | |
kB blendMode | normal | multiply | screen | overlay | darken | lighten | colorDodge | colorBurn | hardLight | softLight | difference | exclusion | hue | saturation | color | luminosity | divide | addition | subtract | |
kc lineCap cap | none | round | square | |
kf fontSize | font_size | |
kj lineJoin join | bevel | round | miter | 0 1 or 2 are also valid values |
kl miterLimit | miter_limit | |
km compositingMode | sourceOver | copy | clear | sourceIn | sourceOut | sourceAtop | destinationOver | destination | destinationIn | destination_out | destinationAtop | xor | |
kt textAlign | start | end | center | left | right | |
kw lineWidth | line_width | |
l relLineTo | x y | |
m relMoveTo | x y | |
n font | "font name" | |
o radialGradient | 6 | |
p gradientAddStop addStop | pos R G B A | arguments depend on current color model, you can change the color model without setting a color by specifying a color without arguments. |
q relQuadTo | cx cy x y | |
r rectangle rect | x y width height | |
s relSmoothTo | cx cy x y | |
t relSmoothQuadTo | x y | |
u strokeText | "utf8-string" | |
v relVerLine | y | |
w glyph | unichar | draws a single unicode character, the character no is currently passed in as decimal. (might be made internal), since a text string duplicates the API. |
x text | "utf8-string" | kerning | Interspersed with utf8 sequences of text numbers can appear that shift the horizontal position. |
y identity | ||
z closePath | ||
A arcTo | x1 y1 x2 y2 radius | |
B arc | x y radius angle1 angle2 direction | |
C curveTo | cx1 cy1 cx2 cy2 x y | |
E stroke | ||
F fill | ||
G restore | ||
H horLineTo | x | |
J rotate | radians | |
L lineTo | x y | |
M moveTo | x y | |
N beginPath | ||
O scale | scale_x scale_y | |
Q quadTo | cx cy x y | |
S smoothTo | cx cy x y | |
T smoothQuadTo | x y | |
U reset | ||
V verLineTo | y | |
W transform | a b c d e f | applies the transformation matrix |
X exit | ||
X done | ||
Y roundRectangle | x y width nheight radius | |
Z closePath | ||
] colorSpace | icc_slot ~a85encoded icc profile~ | sets the color space of a given space in rasterizer. |
{ startGroup | starts a compositing group | |
} endGroup | ends a compositing group, and blends and composites it with the content before the group using the now current compositing mode, blending mode and global alpha. |
The language consists of a stream of words, numbers and strings, optionally separated by white space. The characters ,=(); are also treated as white-space. Words are substrings consisting of one or more characters in the ranges a-z and A-Z. Numbers are sequences of 0-9. Numbers can be followed by the suffixes % or @, indicating that units of percent canvas width/height should be used or a global em / cell-size. ^ is equivalent to CSS vh, and ~ vw, this can be used to override the automatic choice done by %, which favors height for dimensions that are independent of x/y like lineWidth and shadowBlur. Strings are raw binary UTF8 contained in ' or " pairs. "\n\r" etc from C are available for escaping newlines, though they can also be directly included in the string. # introduces a comment and the rest of the line is ignored.
Blobs can also be represented as a85