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 - RESVD free last used path
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 - RESVD
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 .. 0xBF - RESVD
5.96
0xC0 .. 0xCF - RESVD
5.97
0xD0 - d <id> (u8)
5.98
0xD1 - d <id> (u16)
5.99
0xD2 - d2d <id> (u8)
5.100
0xD3 - d3d <id> (u8)
5.101
0xD4 - d2d <id> (u16)
5.102
0xD5 - d3d <id> (u16)
5.103
0xD6 .. 0xDF - RESVD
5.104
0xE0 - end of stream (EOS)
5.105
0xE1 - geo <w> <h> (u16)
5.106
0xE2 - geo <w> <h> (u8)
5.107
0xE3 - pal12 [idx:]#rgb
5.108
0xE4 - RESVD pal16 [idx:]#rrggbb
5.109
0xE5 - pal24 [idx:]#rrggb
5.110
0xE7 - fb <w> <h>
5.111
0xE8 - <matrices_2d>
5.112
0xE9 - <matrices_3d>
5.113
0xEA - RESVD num_consts <n>
5.114
0xEB - RESVD num_vars <n>
5.115
0xEC - RESVD stack <size>
5.116
0xED - RESVD call_stack <size>
5.117
0xEE - RESVD max_ops <n>
5.118
0xEF - RESVD programs
5.119
0xF0 .. 0xFD - RESVD
5.120
0xFE - y (end open path)
5.121
0xFF - z (end closed path)
6
Render backends
7
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
- RESVD free last used path
- w2/w2p pushes clip path on LRU stack
- d* pushes path on LRU stack
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
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 .. 0xBF
5.96 0xC0 .. 0xCF
5.97 0xD0
- draw path at cursor pos (no transformation)
d <id>
- unsigned byte pathIdx follows
5.98 0xD1
- draw path at cursor pos (no transformation)
d <id>
- unsigned short pathIdx follows
5.99 0xD2
- draw path at cursor pos and apply current transform_2d matrix
d2d <id>
- unsigned byte pathIdx follows
5.100 0xD3
- draw path at cursor pos and apply current transform_3d matrix
d3d <id>
- unsigned byte pathIdx follows
5.101 0xD4
- draw path at cursor pos and apply current transform_2d matrix
d2d <id>
- unsigned short pathIdx follows
5.102 0xD5
- draw path at cursor pos and apply current transform_3d matrix
d3d <id>
- unsigned short pathIdx follows
5.103 0xD6 .. 0xDF
5.104 0xE0
5.105 0xE1
- set canvas size
- u16 width / height
geo <w> <h>
5.106 0xE2
- set canvas size (/8, e.g. 40x25 ⇒ 320x200, 240x150 ⇒ 1920x1200)
geo <w> <h>
5.107 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.108 0xE4
- RESVD set 16bit palette (and #colors)
- (num_colors-1) byte followed by tightly packed 16bit color array
5.109 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.110 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.111 0xE8
- define 2D matrices
- u16 <num_matrices_2d> - 1
- float16 2x3 matrices follow
- row major (m11, m12, m21, m22)
5.112 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.113 0xEA
- RESVD define VM constants
- num constants short follows
- constant data follows
5.114 0xEB
- RESVD allocate global VM variables
- num vars short follows
- (note) initialized to 0
5.115 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.116 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.117 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.118 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.119 0xF0 .. 0xFD
5.120 0xFE
y
end path definition (open)
- reset cursor to (0;0)
5.121 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)
7 License
Distributed under terms of the MIT license (https://opensource.org/licenses/MIT)
Copyright 2018-2025 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 38ms on 04-Aug-2025 23:02:36