1 About
minnie is a 2D / 2.5D vector graphics API with a simplified OpenVG / SVG like feature subset, distributed under terms of the
MIT license.
The renderer processes a size optimized byte stream (.mib) which is either generated on-the-fly in RAM, read from flash / mass storage, or converted from a human-readable ASCII file format (.min), which in turn can be converted from SVG files.
The core target runtime consists of a single C++ header file (minnie.h) which can optionally be linked with the SGI tesselator to support complex concave paths with holes (even-odd fill rule).
Triangle rendering is performed with an antialiased software rasterizer which can be replaced by GPU acceleration as required.
2 Table of Contents
1
About
2
Table of Contents
3
Formats
4
Features
5
Opcode reference
5.1
Stream header byte
5.2
0x01 - RESVD x <program>
5.3
0x02 - n <mat2x3> (u8)
5.4
0x03 - q <mat4x4> (u8)
5.5
0x04 - n <mat2x3> (u16)
5.6
0x05 - q <mat4x4> (u16)
5.7
0x0E - h <join> <cap>
5.8
0x0F - RESVD
5.9
0x10 .. 0x1F - i <palIdx> (0..15)
5.10
0x20 - i <palIdx> (16..255)
5.11
0x21 - m <x> <y> f32
5.12
0x22 - M <x> <y> f32
5.13
0x23 - c <c1x> <c1y> <c2x> <c2y> <x> <y> (f32)
5.14
0x24 - RESVD select logic op
5.15
0x25 - s <c2x> <c2y> <x> <y> (f32)
5.16
0x26 - l <x> <y> (f32)
5.17
0x27 - ml <miterlimit> (u8)_
5.18
0x28 - m <x> <y> signed 6.2
5.19
0x29 - m <x> <y> signed 14.2
5.20
0x2A - m <x> <y> signed 8.0
5.21
0x2B - m <x> <y> unsigned 8.0
5.22
0x2C - M <x> <y> unsigned 8.0
5.23
0x2D - M <x> <y> unsigned 8.0 even
5.24
0x2E - M <x> <y> unsigned 8.0 mul4
5.25
0x2F - M <x> <y> signed 14.2
5.26
0x30 .. 0x36 - t <fbIdx> (0..6)
5.27
0x37 - t <fbIdx> (7..255)
5.28
0x38 .. 0x3E - u <fbIdx> (0..6)
5.29
0x3F - u <fbIdx> (7..255)
5.30
0x40 .. 0x4D - f <palIdx> (0..13)
5.31
0x4E - f <palIdx> (14..255)
5.32
0x4F - f aa
5.33
0x50 - disable 2D / 3D clip paths
5.34
0x51 - clip to framebuffer
5.35
0x52 - w2p <pathIdx> (u8)
5.36
0x53 - w2p <pathIdx> (u16)
5.37
0x54 - w2 <pathIdx> (u8)
5.38
0x55 - w2 <pathIdx> (u16)
5.39
0x56 - w3fb
5.40
0x57 .. 0x5D - RESVD
5.41
0x5E - RESVD free path <idx>
5.42
0x5F - free last used path data
5.43
0x60 - RESVD b <dstX> <dstY>
5.44
0x61 - RESVD b <dstX> <dstY> <w> <h> <srcX> <srcY>
5.45
0x62 - RESVD b <dstX> <dstY> <w> <h> <srcX> <srcY>
5.46
0x63 - RESVD b <dstX> <dstY> <w> <h> <srcX> <srcY>
5.47
0x64 - RESVD b <dstX> <dstY> <w> <h> <srcX> <srcY>
5.48
0x65 .. 0x6F - RESVD
5.49
0x70 .. 0x7F - a <palIdx> (0..15)
5.50
0x80 - a <palIdx> (16..255)
5.51
0x81 - a off
5.52
0x82 - k <stroke_w>
5.53
0x83 - k 0
5.54
0x84 - p <id>
5.55
0x85 - pt <id>
5.56
0x86 - psub
5.57
0x87 - ph <id>
5.58
0x88 - l <x> <y> (unsigned 6.2)
5.59
0x89 - l <x> <y> (signed 14.2)
5.60
0x8A - l <x> <y> (unsigned 8.0)
5.61
0x8B - l <x> <y> (signed 6.2)
5.62
0x8C - l <x> <y> (signed 10.2 packed)
5.63
0x8D - pi
5.64
0x8E - j <num_seg> (u8)
5.65
0x8F - j <num_seg> (u16)
5.66
0x90 - c <c1x> <c1y> <c2x> <c2y> <x> <y> (signed 6.2)
5.67
0x91 - c <c1x> <c1y> <c2x> <c2y> <x> <y> (signed 8.0)
5.68
0x92 - c <c1x> <c1y> <c2x> <c2y> <x> <y> (unsigned 8.0)
5.69
0x93 - c <c1x> <c1y> <c2x> <c2y> <x> <y> (signed 14.2)
5.70
0x94 - c <c1x> <c1y> <c2x> <c2y> <x> <y> (signed 10.2 packed)
5.71
0x95 - m <x> <y> -(unsigned 8.0)
5.72
0x96 - m <x> <y> (unsigned 8.0*2)
5.73
0x97 - RESVD
5.74
0x98 - s <c2x> <c2y> <x> <y> (signed 6.2)
5.75
0x99 - s <c2x> <c2y> <x> <y> (signed 8.0)
5.76
0x9A - s <c2x> <c2y> <x> <y> (unsigned 8.0)
5.77
0x9B - s <c2x> <c2y> <x> <y> (signed 14.2)
5.78
0x9C .. 0x9D - RESVD
5.79
0x9E - arc <rx> <ry> <xrot> <flags> <dx> <dy> (s14.2)
5.80
0x9F - arc <rx> <ry> <xrot> <flags> <dx> <dy> (f32)
5.81
0xA0 - r <w> <h> (unsigned 6.2)
5.82
0xA1 - r <w> <h> (unsigned 14.2)
5.83
0xA2 - r <w> <h> (unsigned 8.0)
5.84
0xA3 - r <w> <h> (unsigned 8.0 even)
5.85
0xA4 - r <w> <h> <rx> <ry> (f32)
5.86
0xA5 - r <w> <h> <rx> <ry> (u14.2)
5.87
0xA6 - r <w> <h> <rx> <ry> (u8*2)
5.88
0xA7 - RESVD
5.89
0xA8 - RESVD procedural path ext
5.90
0xA9 .. 0xAF - RESVD
5.91
0xB0 - e <rx> <ry> (unsigned 6.2)
5.92
0xB1 - e <rx> <ry> (unsigned 14.2)
5.93
0xB2 - e <rx> <ry> (unsigned 8.0)
5.94
0xB3 - e <rx> <ry> (unsigned 8.0 even)
5.95
0xB4 - circle <r> (unsigned 14.2)
5.96
0xB5 .. 0xBF - RESVD
5.97
0xC0 .. 0xCF - RESVD
5.98
0xD0 - d <id> (u8)
5.99
0xD1 - d <id> (u16)
5.100
0xD2 - d2d <id> (u8)
5.101
0xD3 - d3d <id> (u8)
5.102
0xD4 - d2d <id> (u16)
5.103
0xD5 - d3d <id> (u16)
5.104
0xD6 .. 0xDF - RESVD
5.105
0xE0 - end of stream (EOS)
5.106
0xE1 - geo <w> <h> (u16)
5.107
0xE2 - geo <w> <h> (u8)
5.108
0xE3 - pal12 [idx:]#rgb
5.109
0xE4 - RESVD pal16 [idx:]#rrggbb
5.110
0xE5 - pal24 [idx:]#rrggb
5.111
0xE7 - fb <w> <h>
5.112
0xE8 - <matrices_2d>
5.113
0xE9 - <matrices_3d>
5.114
0xEA - RESVD num_consts <n>
5.115
0xEB - RESVD num_vars <n>
5.116
0xEC - RESVD stack <size>
5.117
0xED - RESVD call_stack <size>
5.118
0xEE - RESVD max_ops <n>
5.119
0xEF - RESVD programs
5.120
0xF0 .. 0xFD - RESVD
5.121
0xFE - y (end open path)
5.122
0xFF - z (end closed path)
6
Render backends
7
API reference manuals
8
GitHub
9
License
- human readable text format (
.min)
- compiled to size-optimized
.mib binary format via offline preprocessor
- can be converted from
.svg files via offline preprocessor
- host-side pseudo ops / directives
- build matrices via rotate / translate / scale / skew / frustum functions
- path transformations (
geo_scale / gs, geo_transform / gxf, gxfs)
- tesselation resolution scaling (
seg_scale)
- select palette index by closest matching #rgb / #rrggbb color (
color / i)
- post-process palette colors (
pal_hsv / pal_brightness / pal_contrast)
- reverse paths and drawing order when targeting coverage-AA software rasterizer (
aa)
- example:
geo 640 480
aa on
pal #eee #6db #547 #7cb #fff #9dc #779 #498
; clear screen
f 0
; define path
p mypath
M -75 -75
r 150 150
z
; set 2D transform
n rotate(30) translate(320 240)
; draw filled path
i 1
k fill
d2 mypath
; draw stroked path
i 6
h miter
k 6
d2 mypath
test016_aa.min
geo 800 600
aa on
pal #e8e8e8 #b9d5e2 #000000
; clear screen
f 0
; translate / scale geometry
gxf 16 3 6 6
; define svg path 'path6968'
ph path6968
svg M 16.928616,67.341255 \
C 17.977291,66.142769 59.924304,6.6678972 59.924304,6.6678972 \
L 87.189862,89.063815 50.186604,71.386145 58.426196,22.547838 \
21.72256,78.577061 32.508935,84.26987 53.632252,48.465099 \
16.628994,31.985915 10.786375,50.862071 \
38.051933,64.045418 30.561395,75.580846 Z
z
; draw filled path
i 1
k fill
d path6968
; draw stroked path
i 2
k 0.25
h miter butt
d path6968
test046_evenodd.min
- example:
geo 640 480 ; set canvas size
pal #eee #247 ; define palette
ps 64 ; set default tesselation depth
p mypath ; define path
m -200 -200 ; move to left / top corner
r 400 400 40 30 ; add rounded and centered rectangle
z ; end of path
f 0 ; clear with color 0
i 1 ; select color 1
m 320 240 ; move cursor to screen center
d mypath ; draw path
test079_minimal.min
⇒
01 e2 50 3c e3 01 ee 2e 74 84 8e 40 95 c7 c7 a6
c8 c8 14 0f ff 84 40 96 9f 77 d0 01 e0
test079_minimal.mib
⇒ 
- generated on-the-fly in RAM
- or converted from
.min file
- variable-sized ops / display-list instructions control VM-like state machine
- implementations
debug viewer
- can display the stream in a desktop window
- can disassemble the stream in
.min format
- used for prototyping / debugging
minnie.h C++ header file / library
- single file
- resource-optimized implementation
- supports custom memory allocators
- no 3rd party dependencies
- optional extension: SGI tesselator (even-odd paths with holes)
- optional extension: Antialiased software rasterizer
- e.g. for running on an embedded target
3.3 SVG file size comparison
| size | SVG name | size | minnie name | size factor |
| 4189 | cake.svg | 622 | test018_cake_aa.mib | 1:7 |
| 31681 | wild-boar.svg | 5284 | test039_wildboar.mib | 1:6 |
| 6828 | valentines.svg | 1514 | test033_valentines.mib | 1:5 |
| 1478 | bicycle.svg | 358 | test035_bicycle.mib | 1:4 |
| 42352 | crab.svg | 6425 | test036_crab.mib | 1:7 |
| 96719 | tiger.svg | 17135 | test040_tiger.mib | 1:6 |
| 20743 | elefant.svg | 1811 | test043_elefant.mib | 1:11 |
SVG file size comparison
4 Features
4.1 Fill / clear
- clear current draw-buffer with current color
4.2 Paths
- path types
- convex
- concave
- concave with holes
HAVE_VGTESSELATE build option (SGI tesselator that supports even-odd fill rule)

- sub paths
- per (sub-)path spline / arc / ellipse tesselation granularity
- open and closed paths
4.2.1 Path elements
- lines

- horizontal lines (
h / H in SVG)
- vertical lines (
v / V in SVG)
- rectangles
- rounded rectangles
- ellipses
- cubic and quadratic splines / bezier curves
- mirrored cubic and quadratic splines
- elliptic arcs
4.2.2 SVG paths
- full support for SVG path definition syntax (
.min format)
4.3 Path instancing
Once declared, paths may be rendered an arbitrary number of times.
Paths are always translated to the current cursor position, and may optionally be transformed by the current 2D or 3D matrix beforehand.
Each path instance can be assigned an individual stroke width and line join / cap style and stroke or fill color.
- simply translate to cursor position

- apply 2D matrix (2x3)
- translate to cursor position

- apply projective 3D matrix (4x4)
- translate to cursor position

4.4 Clipping
4.4.1 Clip to framebuffer
4.4.2 Clip to path
- pre tesselation
- post tesselation
4.5 Filled and stroked rendering
- color
- stroke width
- butt, round, square line caps
- miter, round, bevel line joins

4.6 Color palettes
4.7 Stencil masking
- stencil color

4.8 Framebuffers
- implicit main framebuffer
- up to 255 auxiliary buffers
4.9 Blits
- target draw-buffer select op (
t <fbIdx>)
- source read-buffer select op (
u <fbIdx>)
- blit ops (
b <dstX> <dstY> <w> <h> <srcX> <srcY>)
5 Opcode reference
Binary stream format for .mib files and procedural buffers.
The first byte in a .mib stream is the header byte (def=0x01)
- bits 0..5: version (LSB6, 1..63)
- bit 6: 1=reverse drawing order (
aa / rev)
|
in AA mode, the main path drawops are reversed (e.g. for the coverage AA software rasterizer) |
- bit 7: endianness (1=big endian)
5.2 0x01
5.3 0x02
- select 2D transformation matrix
- u8 mat_idx byte follows
5.4 0x03
- select 3D transformation matrix
- u8 mat_idx byte follows
5.5 0x04
- select 2D transformation matrix
- u16 mat_idx byte follows
5.6 0x05
- select 3D transformation matrix
- u16 mat_idx byte follows
5.7 0x0E
- select line join and cap types
h <join> <cap>
- join types:
none, miter, round, bevel
- cap types:
none, butt, round, square
- join / cap byte follows (MSB4=join, LSB4=cap)
5.8 0x0F
5.9 0x10 .. 0x1F
- select color by palette index
i <palIdx> (0..15)
- select palette index 0..15
5.10 0x20
- select color by palette index
i <palIdx> (16..255)
- palette index byte follows
5.11 0x21
- move pen relative to current position
m <x> <y>
- dx / dy 32bit floats follow
- note: force 32 bit float moves with
m_f32 on
5.12 0x22
- move pen to absolute position
m <x> <y>
- dx / dy 32bit floats follow
- note: force 32 bit float moves with
m_f32 on
5.13 0x23
- add cubic spline segment to current (sub-)path
c <c1x> <c1y> <c2x> <c2y> <x> <y>
- 32bit floats follow
- (note) c1 is relative to last cursor pos
- (note) c2 is relative to dst (new cursor pos) (c2Abs = dstAbs - c2)
- (note) enable with
c_f32 on or f32 on
5.14 0x24
5.15 0x25
- add mirrored cubic spline segment to current (sub-)path
s <c2x> <c2y> <x> <y>
- (implicit) c1 is mirrored version of previous c2 (
s in SVG)
- 32bit floats follow
- (note) c2 is relative to dst (c2Abs = dstAbs - c2)
- (note) enable with
c_f32 on or f32 on
5.16 0x26
- add line segment to current (sub-)path
l <x> <y>
- 32bit floats follow
- (note) enable with
l_f32 on or f32 on
5.17 0x27
- set miter limit (def=32.0)
- u8 byte follows
5.18 0x28
- move pen relative to current position
m <x> <y>
- dx / dy bytes follow
5.19 0x29
- move pen relative to current position
m <x> <y>
- dx / dy shorts follow
5.20 0x2A
- move pen relative to current position
m <x> <y>
- dx / dy bytes follow
5.21 0x2B
- move pen relative to current position
m <x> <y>
- dx / dy bytes follow
5.22 0x2C
- move pen to absolute position
M <x> <y>
- dx / dy bytes follow
5.23 0x2D
- move pen to absolute position
M <x> <y>
- dx / dy bytes follow (scaled by 2.0)
5.24 0x2E
- move pen to absolute position
M <x> <y>
- dx / dy bytes follow (scaled by 4.0)
5.25 0x2F
- move pen to absolute position
M <x> <y>
- dx / dy shorts follow
5.26 0x30 .. 0x36
- select current draw-buffer
t <fbIdx> (0..6)
5.27 0x37
- select current draw-buffer
t <fbIdx> (7..255)
- draw-buffer index byte follows
5.28 0x38 .. 0x3E
- select current read-buffer
u <fbIdx> (0..6)
5.29 0x3F
- select current read-buffer
u <fbIdx> (7..255)
- read-buffer index byte follows
5.30 0x40 .. 0x4D
- fill / clear current draw-buffer with palette index
- (no logic ops)
f <palIdx> (0..13)
5.31 0x4E
- fill / clear current draw-buffer with palette index
- (no logic ops)
f <palIdx> (14..255)
- palette index byte follows
5.32 0x4F
- clear coverage alpha (AA rasterizer)
f aa
5.33 0x50
- disable 2D / 3D clip paths
w2off / w3off / woff
5.34 0x51
- set 2D clip to framebuffer (clip tesselated vertices)
5.35 0x52
- set 2D clip to path (clip pre-tesselated vertices)
w2p <pathIdx> (u8)
- pathIdx-1 unsigned byte follows
5.36 0x53
- set 2D clip to path (clip pre-tesselated vertices)
w2p <pathIdx> (u16)
- pathIdx-1 unsigned short follows
5.37 0x54
- set 2D clip to path (clip tesselated vertices)
w2 <pathIdx> (u8)
- pathIdx-1 unsigned byte follows
5.38 0x55
- set 2D clip to path (clip tesselated vertices)
w2 <pathIdx> (u16)
- pathIdx-1 unsigned short follows
5.39 0x56
- set 3D clip viewport to framebuffer (znear=0.01)
w3fb
5.40 0x57 .. 0x5D
5.41 0x5E
- RESVD free path <idx>
- unsigned short <pathIdx> follows
5.42 0x5F
- free last used path data
- d* sets last used path
5.43 0x60
- RESVD
b <dstX> <dstY>
- blit rectangular region (entire srcBuf)
- signed 14.2 short (dst*)
5.44 0x61
- RESVD
b <dstX> <dstY> <w> <h> <srcX> <srcY>
- blit rectangular region
- signed 14.2 short (dst*)
- unsigned byte (src*/w/h)
5.45 0x62
- RESVD
b <dstX> <dstY> <w> <h> <srcX> <srcY>
- blit rectangular region
- signed 14.2 short (dst) ⇒ 62 = 12 bytes
- unsigned short (src*/w/h)
5.46 0x63
- RESVD
b <dstX> <dstY> <w> <h> <srcX> <srcY>
- blit rectangular region
- signed 10.2 shorts (dst*)
- unsigned 12 bit shorts (src*/w/h)
- ⇒ 6*12=72bit = 9 bytes + 1 pad byte = 10 bytes
5.47 0x64
- RESVD
b <dstX> <dstY> <w> <h> <srcX> <srcY>
- blit rectangular region
- signed 14.2 short (dst*)
- unsigned byte (src/w/h) 4
5.48 0x65 .. 0x6F
5.49 0x70 .. 0x7F
- RESVD
a <palIdx> (0..15)
- 0x70..0x7F: enable mask palIdx=0..15
- (note) uses stencil buffer on GPU
5.50 0x80
a <palIdx> (16..255)
- palIdx byte follows
5.51 0x81
5.52 0x82
- set stroke width
k <stroke_w>
- <stroke_w> unsigned 6.2 byte (2 fractional bits). 0.25 (int 1) = draw (non-extruded) polyline (pseudo w "line")
- this is the radius (effective line width = 2*stroke_w)
5.53 0x83
- disable stroke / enable fill
k 0 / k fill
5.54 0x84
- begin convex or stroked path definition
p <id>
5.55 0x85
- begin concave path definition (no holes)
- will be tesselated using simple ear-clipping tesselator, not the SGI tesselator
pt <id>
5.56 0x86
- begin sub-path definition
5.57 0x87
- begin concave even-odd path definition (with holes)
ph <id>
- will be tesselated using te SGI tesselator (even-odd fill rule)
5.58 0x88
- add line segment to current (sub-)path
l <x> <y>
- unsigned 6.2 bytes follow
5.59 0x89
- add line segment to current (sub-)path
l <x> <y>
- signed 14.2 shorts follow
5.60 0x8A
- add line segment to current (sub-)path
l <x> <y>
- unsigned 8.0 bytes follow
5.61 0x8B
- add line segment to current (sub-)path
l <x> <y>
- signed 6.2 bytes follow
5.62 0x8C
- add line segment to current (sub-)path
l <x> <y>
- signed 10.2 packed 12bits follow
- must sign extend during decoding
5.63 0x8D
- begin immediate path (rect, roundrect, ellipse, circle)
pi
- will be rendered via specialized draw functions
5.64 0x8E
- set num segments for following spline / arc / ellipse ops (def=8)
- unsigned byte follows
5.65 0x8F
- set num segments for following spline / arc / ellipse ops (def=8)
j <num_seg> (must occur within path declaration)
- unsigned short follows
5.66 0x90
- add cubic spline segment to current (sub-)path
c <c1x> <c1y> <c2x> <c2y> <x> <y>
- delta < abs(32) (signed 6.2 bytes)
- (note) c1 is relative to last cursor pos
- (note) c2 is relative to dst (new cursor pos) (c2Abs = dstAbs - c2)
5.67 0x91
- add cubic spline segment to current (sub-)path
c <c1x> <c1y> <c2x> <c2y> <x> <y>
- delta < abs(128) (signed 8.0 bytes)
- (note) c1 is relative to last cursor pos
- (note) c2 is relative to dst (new cursor pos) (c2Abs = dstAbs - c2)
5.68 0x92
- add cubic spline segment to current (sub-)path
c <c1x> <c1y> <c2x> <c2y> <x> <y>
- 0 ⇐ delta < 256 (unsigned 8.0 bytes)
- (note) c1 is relative to last cursor pos
- (note) c2 is relative to dst (new cursor pos) (c2Abs = dstAbs - c2)
5.69 0x93
- add cubic spline segment to current (sub-)path
c <c1x> <c1y> <c2x> <c2y> <x> <y>
- delta >= abs(32) (signed 14.2 words)
- (note) c1 is relative to last cursor pos
- (note) c2 is relative to dst (new cursor pos) (c2Abs = dstAbs - c2)
5.70 0x94
- add cubic spline segment to current (sub-)path
c <c1x> <c1y> <c2x> <c2y> <x> <y>
- delta >= abs(512) (signed 10.2 12bits) (must sign extend during decode)
- (note) c1 is relative to last cursor pos
- (note) c2 is relative to dst (new cursor pos) (c2Abs = dstAbs - c2)
5.71 0x95
- move pen relative to current position
m <x> <y>
- dx-1 / dy-1 bytes follow
5.72 0x96
- move pen relative to current position
m <x> <y>
- dx-1 / dy-1 bytes follow (scaled by 2.0)
5.73 0x97
5.74 0x98
- add mirrored cubic spline segment to current (sub-)path
s <c2x> <c2y> <x> <y>
- (implicit) c1 is mirrored version of previous c2 (
s in SVG)
- delta < abs(32) (signed 6.2 bytes)
- (note) c2 is relative to dst (c2Abs = dstAbs - c2)
5.75 0x99
- add mirrored cubic spline segment to current (sub-)path
s <c2x> <c2y> <x> <y>
- (implicit) c1 is mirrored version of previous c2 (
s in SVG)
- delta < abs(128) (signed 8.0 bytes)
- note) c2 is relative to dst (c2Abs = dstAbs - c2)
5.76 0x9A
- add mirrored cubic spline segment to current (sub-)path
s <c2x> <c2y> <x> <y>
- (implicit) c1 is mirrored version of previous c2 (
s in SVG)
- 0 ⇐ delta < 256 (unsigned 8.0 bytes)
- (note) c2 is relative to dst (c2Abs = dstAbs - c2)
5.77 0x9B
- add mirrored cubic spline segment to current (sub-)path
s <c2x> <c2y> <x> <y>
- (implicit) c1 is mirrored version of previous c2 (
s in SVG)
- delta >= abs(32) (signed 14.2 words)
- (note) c2 is relative to dst (c2Abs = dstAbs - c2)
5.78 0x9C .. 0x9D
5.79 0x9E
- add elliptic arc segment to current (sub-)path
arc <rx> <ry> <xrot> <flags> <dx> <dy>
- s14.2 rx
- s14.2 ry
- u9.5:1:1 xrot
- bits 15..7: 0..512 ⇒ 0..360 degrees
- bits 6..2: angle fractional bits (0..32 ⇒ 0..1)
- bit 1: arc_sweep flag
- bit 0: large_arc flag
- s14.2 dx
- s14.2 dy
5.80 0x9F
- add elliptic arc segment to current (sub-)path
arc <rx> <ry> <xrot> <flags> <dx> <dy>
- f32 rx
- f32 ry
- u9.5:1:1 xrot
- bits 15..7: 0..512 ⇒ 0..360 degrees
- bits 6..2: angle fractional bits (0..32 ⇒ 0..1)
- bit 1: arc_sweep flag
- bit 0: large_arc flag
- f32 x
- f32 y
- (note) enable 32bit float arcs with
arc_f32 on or f32 on
5.81 0xA0
- add rectangle segment to current (sub-)path
r <w> <h>
- unsigned 6.2 bytes
5.82 0xA1
- add rectangle segment to current (sub-)path
r <w> <h>
- unsigned 14.2 shorts
5.83 0xA2
- add rectangle segment to current (sub-)path
r <w> <h>
- unsigned 8.0 bytes
5.84 0xA3
- add rectangle segment to current (sub-)path
r <w> <h>
- unsigned 8.0 bytes (*2, even coordinates)
5.85 0xA4
- add rounded rectangle segment to current (sub-)path
r <w> <h> <rx> <ry>
- 32 bit floats
5.86 0xA5
- add rounded rectangle segment to current (sub-)path
r <w> <h> <rx> <ry>
- unsigned 14.2 shorts
5.87 0xA6
- add rounded rectangle segment to current (sub-)path
r <w> <h> <rx> <ry>
- unsigned byte * 2.0
5.88 0xA7
5.89 0xA8
- RESVD procedural path ext
5.90 0xA9 .. 0xAF
5.91 0xB0
- add ellipse segment to current (sub-)path
e <rx> <ry>
- unsigned 6.2 bytes
5.92 0xB1
- add ellipse segment to current (sub-)path
e <rx> <ry>
- unsigned 14.2 shorts
5.93 0xB2
- add ellipse segment to current (sub-)path
e <rx> <ry>
- unsigned 8.0 bytes
5.94 0xB3
- add ellipse segment to current (sub-)path
e <rx> <ry>
- unsigned 8.0 bytes (*2, even coordinates)
5.95 0xB4
- add circle segment to current (sub-)path
- `circle <r>
- unsigned 14.2 shorts
5.96 0xB5 .. 0xBF
5.97 0xC0 .. 0xCF
5.98 0xD0
- draw path at cursor pos (no transformation)
d <id>
- unsigned byte pathIdx follows (relative to end of path array)
5.99 0xD1
- draw path at cursor pos (no transformation)
d <id>
- unsigned short pathIdx follows (relative to end of path array)
5.100 0xD2
- draw path at cursor pos and apply current transform_2d matrix
d2d <id>
- unsigned byte pathIdx follows (relative to end of path array)
5.101 0xD3
- draw path at cursor pos and apply current transform_3d matrix
d3d <id>
- unsigned byte pathIdx follows (relative to end of path array)
5.102 0xD4
- draw path at cursor pos and apply current transform_2d matrix
d2d <id>
- unsigned short pathIdx follows (relative to end of path array)
5.103 0xD5
- draw path at cursor pos and apply current transform_3d matrix
d3d <id>
- unsigned short pathIdx follows (relative to end of path array)
5.104 0xD6 .. 0xDF
5.105 0xE0
5.106 0xE1
- set canvas size
- u16 width / height
geo <w> <h>
5.107 0xE2
- set canvas size (/8, e.g. 40x25 ⇒ 320x200, 240x150 ⇒ 1920x1200)
geo <w> <h>
5.108 0xE3
- set 12bit palette (and #colors)
- e.g.
pal #ecb #fff #000 #c72 #e73 #e84 #e96 #ea7 #fb8 #fb9 #fcb #fdc #fed #ffe #ccc #e68 #b35 #a24 #f77 #ffc #c34 #a12 #bbb #eeb #e85 #ea7 #fca #fed #9c3 #690 #e95 #fb9 #fdc #333 #666 #999 #920 #400 #e99 #b66
- (num_colors-1) byte followed by tightly packed 12bit color array (word-aligned at the end)
5.109 0xE4
- RESVD set 16bit palette (and #colors)
- (num_colors-1) byte followed by tightly packed 16bit color array
5.110 0xE5
- set 24bit palette (and #colors)
- e.g.
pal #e1cdb7 #ffffff #000000 #cc7226 #e87f3a #ea8c4d #ec9961 #eea575 #f1b288 #f3bf9c #f5ccb0 #f8d8c4 #fae5d7 #fcf2eb #cccccc #e5668c #b23259 #a5264c #ff727f #ffffcc #cc3f4c #a51926 #b2b2b2 #e5e5b2 #ea8e51 #efaa7c #f4c6a8 #f9e2d3 #99cc32 #659900 #eb955c #f2b892 #f8dcc8 #323232 #666666 #999999 #992600 #4c0000 #e59999 #b26565
- (num_colors-1) byte followed by (R,G,B) 8bit tuples
5.111 0xE7
- define additional draw buffers
fb <w> <h>
- num_draw_bufs unsigned byte follows
- w h unsigned byte pairs follow (/8, 0=use canvas geo)
5.112 0xE8
- define 2D matrices
- u16 <num_matrices_2d> - 1
- float16 2x3 matrices follow
- row major (m11, m12, m21, m22)
5.113 0xE9
- define 3D matrices
- u16 <num_matrices_3d> - 1
- float16 4x4 matrices follow
- row major (m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44)
5.114 0xEA
- RESVD define VM constants
- num constants short follows
- constant data follows
5.115 0xEB
- RESVD allocate global VM variables
- num vars short follows
- (note) initialized to 0
5.116 0xEC
- RESVD set VM data stack size (def=8 ⇒ 128 bytes)
- (stack size / 16) byte follows
- 0..254. 255 is reserved for future extensions
5.117 0xED
- RESVD set VM call stack size (def=2 ⇒ 32 return addresses)
- (stack size / 16) byte follows
- 0..254. 255 is reserved for future extensions
5.118 0xEE
- RESVD abort VM after <n>*1024 ops (def=64 ⇒ 64k ops)
- (max_ops/1024) byte follows
- 0..254. 255 is reserved for future extensions
- (note) used for infinite loop detection
5.119 0xEF
- RESVD define VM programs
- (numPrograms-1) byte follows
- program data follows
- first word is program data size in bytes (excluding the size word)
5.120 0xF0 .. 0xFD
5.121 0xFE
y end path definition (open)
- reset cursor to (0;0)
5.122 0xFF
z end path definition (closed)
- reset cursor to (0;0)
6 Render backends
- antialiased software rasterizer
tri_aa or tri_aa_fx (portable C code)
- portable to GPU-accelerated APIs
- screenshots from OpenGL (ES) 2.0 edge-AA shader
- Ghostscript Tiger (@640x480) runs at..
- 247 mio tris/sec (~17240 fps) on a 1398MHz Apple M2pro GPU (19 cores * 16 execution units * 8 ALUs = 2432 ALUs)
- 1195 mio tris/sec (~83330 fps) on a 1582Mhz NVidia 1080 TI GPU (28 streaming multiprocessors * 128 cores = 3584 CUDA cores)
- ..or, clock + ALU-complexity adjusted, approximately 0.29..0.84 mio tris/sec (~20..58 fps) on a comparatively tiny 250MHz embedded GPU (2 shader units * 8 ALUs = 16 ALUs)
6.1 Analytical Anti-Aliasing codepaths (GL backend)
The following code paths / feature combinations support high-quality analytical antialiasing (no MSAA required):
- flat shaded lines
- lines with pattern paint
- gouraud shaded lines (per control-point color)
- flat shaded polylines
- flat shaded polylines with bevel line joints
- flat shaded polylines with miter line joints
- polylines with conic paint
- polylines with radial paint
- polylines with linear paint
- polylines with pattern paint
- polylines with alpha pattern paint
- polylines with decal pattern paint
- polylines with bevel joints and pattern paint
- polylines with bevel joints and decal pattern paint
- dashed polylines
- dashed polylines with bevel line joints
- decal dashed polylines
- decal dashed polylines with bevel line joints
- polygons (via polyline stroke. all paint types)
- square and round points
- square and rounds points with per-point color
- flat shaded, stroked rectangles
- stroked rectangles with conic paint
- stroked rectangles with radial paint
- stroked rectangles with linear paint
- stroked rectangles with pattern paint
- stroked rectangles with alpha pattern paint
- stroked rectangles with decal pattern paint
- flat shaded, filled rectangles
- filled rectangles with conic paint
- filled rectangles with radial paint
- filled rectangles with linear paint
- filled rectangles with pattern paint
- filled rectangles with alpha pattern paint
- filled rectangles with decal pattern paint
- flat shaded, filled + stroked rectangles
- flat shaded, stroked rounded rectangles
- stroked rounded rectangles with conic paint
- stroked rounded rectangles with radial paint
- stroked rounded rectangles with linear paint
- stroked rounded rectangles with pattern paint
- stroked rounded rectangles with alpha pattern paint
- stroked rounded rectangles with decal pattern paint
- flat shaded, filled rounded rectangles
- filled rounded rectangles with conic paint
- filled rounded rectangles with radial paint
- filled rounded rectangles with linear paint
- filled rounded rectangles with pattern paint
- filled rounded rectangles with alpha pattern paint
- filled rounded rectangles with decal pattern paint
- flat shaded filled + stroked rounded rectangles
- flat shaded, stroked ellipses
- stroked ellipses with conic paint
- stroked ellipses with radial paint
- stroked ellipses with linear paint
- stroked ellipses with pattern paint
- stroked ellipses with alpha pattern paint
- stroked ellipses with decal pattern paint
- flat shaded, filled ellipses
- filled ellipses with conic paint
- filled ellipses with radial paint
- filled ellipses with linear paint
- filled ellipses with pattern paint
- filled ellipses with alpha pattern paint
- filled ellipses with decal pattern paint
- flat shaded, filled + stroked ellipses
In addition, almost all of these render paths have dedicated FixPoint14:2 and FloatingPoint32 versions.
7 API reference manuals
8 GitHub
- TKS (main repository)
- Minnie (standalone Minnie, copied from TKS repo)
9 License
Distributed under terms of the MIT license (https://opensource.org/licenses/MIT)
Copyright 2018-2026 by bsp
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
MIT license
Document created in 40ms on 08-Jan-2026 09:46:44