ctx is an audio-capable 2D vector graphics terminal. A protocol serializing HTML5 canvas 2D context
as SVG path data. And a minimal application development platform, the
terminal itself is written in ctx and can be self-hosted.
The self-contained static builds are sufficient to run minimalistic
desktop+shells only sessions with very low RAM requirements.
Features and references
- HTML5 Canvas 2D Context
- Easily bindable C API and protocol builds directly on this standard.
Compositing and blending is according to Compositing and Blending
Level 2; ctx goes further than the standard and permits all blending modes
to be combined with all compositing modes.
- backends: ctx, DRM, fbdev, SDL2, braille
-
- ctx comes with 5 main backends, the ctx backend renders the
ctx protocol to stdout, and reads input - it is meant to
be used from the ctx terminal. DRM and fbdev are available
without any dependencies in the static builds, this
backend - like the braille backend, take keyboard input
from stdin; mouse events are read from /dev/input/mice.
The SDL2 backend permits using ctx clients under wayland/X11.
- RGB and CMYK, 8pc and 32bit floating point
-
Supporting RGB332, RGB565 and grayscale + 1bit mode render targets.
ICC based management of RGB user/device spaces is supported through babl.
- deferred rendering
- Tokenizing the rasterization as a protocol is core to ctx' operation. Issuing a draw command prepares a token that is either appended to a drawlist or acted upon immediately; depending on the configuration of the context. Drawlists can be converted to both compact and verbose textual representation with little overhead.
These drawlist representations are used for scanline/chunk-based
rendering on microcontrollers where framebuffer is to large to fit in
RAM and threaded cached rendering
through SDL2 and /dev/fb0 backends and network transparent rendering
inside ctx terminal.
.
- text rendering
- UTF8 native, there is three font backends
driven by stb_trutetype reading glyph paths on demand from
a TTF/OTF file loaded in RAM/ROM.
Using binary ctx drawlist representation, separated by '@'
define-glyph commands.
And an experimental backend permits rendering each glyph loaded
on-the fly from the filesystem as ctx ascii protocol, combined
with a UI shape editor, ctx would have a live font-editor.
The text-shaping is currently limited to horizontal advances +
horizontal kerning, no ligatures - interacting directly with
harfbuzz could give us wider support.
- Small footprint
- Can be tuned for microcontrollers down to ~7kb of RAM + 30kb
of code + 12kb of fontdata, combined with immediate mode UI that can
be re-run, it is sufficient to have a framebuffer covering one
or a few scanlines. More RAM permits more flexible arrangement
of more components using the CTX protocol.
- Portable
- The core rasterizer is C99 code that also
compiles as C++, with simple make basd build system and only
optional dependencies, and thus should run on most CPU
architectures.
- VT4xx, ECMA-48
- Almost full vt100 and vt220 escape sequence handling, scrollback, like xterm, dterm window manipulation (among tabs/clients), bracketed paste, 256 and 24bit colors are supported - as well as a growing subset of vt420 and other relevant terminal escape sequences.
- ametameric palette
- The terminal 16 color palette is optimized for legibility for both main varieties dichromats as well as trichromats.
- sixels
- DEC terminal family standard for raster graphics transfer
- kitty graphics
- kitty style raster graphics transfer
- iterm2 inline images
- iterm2 style raster grarphics transfer
- atty
- audio recording and playback (only raw pcm for now, opus codec NYI)
- stb_truetype.h
- If the declarations for stb_truetype are
included before ctx.h - functions to load fonts from TTF/OTF files
become available.
- SDL2
- Optional backend that works better than the framebuffer that gets included when SDL.h is included before ctx.h
- cairo
- support code to render to cairo contexts if cairo.h is included before ctx.h, useful for conformance verfication and SVG and PDF output.
git
Development of ctx happens in a mono-repo, which contains a split up source-tree for the rasterizer/protocol that ends up in the single-header ctx.h files, a tool to generate ctx format subsetted fonts from TTF/OTF files, the sources for a client/terminal multi-plexer - as well as demo applications for the platform.
$ git clone https://ctx.graphics/.git
$ cd ctx.graphics
$ make
Downloads
The single header and static binaries for download are autogenerated
together with this website each time the git repository is synched.
ctx.h | 760K | The singleheader library ctx. |
ctx-font-regular.h | 128K | Example font to use with ctx, to be a true single header solution - the ascii subset of this is included by default. |
ctx-x86_64-static | 64bit static linux binary - should work in mant distros, but has only DRM, /dev/fb0 and braille rendering not SDL2 |
ctx-i486-static | 32bit static linux binary - should work in mant distros, but has only DRM, /dev/fb0 and braille rendering not SDL2 |
license and funding
The terminal is available under GPLv3+, and
ctx.h is available under LGPLv3+ you
can encourage continued development of ctx and dissimilar technologies by
financially supporting me, Øyvind Kolås who is doing independent pro-bono R&D through
patreon and
similar. If my income through such sources is above 4000USD per
month for a year, or a similar amount in shorter time I want
to relicense the rasterizer and protocol parts of ctx
under the ISC license.
bugs
The current status of ctx is beyond proof of concept - but still
does not fully realize a minimal system demonstrating it's capabilities
- some features are also broken and need repair - and for third party
use probably more urgently than the following wishlist. When this list
is nearing 0 it is time for a tarball/versioned release of ctx. The
single header ctx.h linked from this page is a rolling release.
- clip does not clip event boxes/shapes
- some low-level rasterizer glitches
- arcs doesn't fmod >2PI values well
- in_fill is using bounding box
- radial gradient is only using one center
- dimensions of drop-shadow are not transformed
- miter limit (unless round joins are used, all corners are mitered now)
- square line ends
- cursor keys incorrect (not passing vttest) in vt52 mode
- palm supression during typing in drm/fbdev backend
- terminal rewrap on resize
directions
- performance, there always seem to be room for improvement.
- continued code refactoring
- glyph fallbacks between fonts
- texture upload as part of terminal protocol
- swap some uses of cairo in GEGL with ctx, pass ctx data
as buffers, or have ctx backend buffers in GEGL.
- binary search for glyphs in ctxf font backend, making it scale well for wide unicode coverage.
- websockets + js + HTML5 Canvas renderer/client for protocols
- wayland/libinput support
- analytical instead of raster clipping
- bindings to a javascript engine like quickjs, for running canvas js content as apps.
- (optional) use of floating point instead of fixed point in rasterizer.
- faster and correctly transformed 1d-gaussian blur for shadow blur
- PDF/SVG generation (in addition to existing cairo integration)
- Add API for integrating device-N with RGB/CMYK through coloritto
- 32bit float coverage from rasterizer - right now we support 32f images/color; but composite using 8bit alpha masks.
- More SIMD code (the common RGBA8 cases for handled as manual
simulated 64bit SIMD and AVX2 are the only bits covered thus
far, for the floating point formats making the existing code more
autovectorizer friendly is a priority.)
- A GPU renderer, the information needed for precomputation and
spatial organization in many GPU rendering approaches is already
present - alternatively backends sitting on top of exisitng
libraries.