ctx is a media-rich terminal and a vector graphics stack, built
around a textual serialization protocol. The
textual serialization has a corresponding binary representation that
is used by the core rasterizer as well as sharing data among threads.
The ctx protocol is available as an extension to ANSI escape sequences
in the ctx terminal - the terminal launched when running the ctx
binary with no arguments. This extension allows scripts in any
language to output vector graphics in addition to or instead of
monospace text in each tab/window, and also provides network
The clock in the above screenshot is a shellscript.
Ctx is usable as a single header library, to be dropped into a source
tree, ctx header/library, it can also be installed
Applications written using the C library can run either inside the
ctx terminal, or stand-alone using SDL2, fbdev/DRM or in-terminal
braille as output.
Mouse and touch events are registered for the currently active path,
with propagation control to earlier registered interactions.
Running directly with the SDL2 or framebuffer backends
has higher performance than going through the terminal abstraction,
reducing this gap through tuning and refactoring is a work in progress,
for applications the difference between 12fps and 120fps is smaller
and small rather than global updates are done.
The self-contained static builds are sufficient to run minimalistic
desktop+shells only sessions with low RAM requirements. The rasterizer
which for multi-core use is used in parallell for multiple threads,
started off written to fit on microntrollers, with the
right defines a RGBA 8bit rasterizer can be made to fit in 32kb of code
also for 64bit x86.
- 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 - and a growing subset of vt420 and other relevant terminal escape sequences.
- The ctx terminal tries to re-render as
little as possible, as fast as posisble using multiple
threads, and SIMD when possible (AVX2 ands 64-bit-pseudo-SIMD
implemented). Results of running typometer measuring latency under
a composited GNOME3, numers are average milliseconds per update, lower
The terminals 16 color palette called ametameric is optimized for legibility for both main varieties dichromats as well as trichromats.
- 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 interactive
backends, the ctx backend renders the
ctx protocol to stdout, and reads input, this
provides the client interface for interactive vector
clients running in the ctx terminal.
DRM and fbdev backend takes
take keyboard input from stdin and tries to read mouse events are
The SDL2 backend permits using ctx clients
under wayland/X11 and probably other platforms.
- RGB and CMYK, 8pc and 32bit floating point
Supporting RGB332, RGB565 and grayscale + 1bit mode render targets.
ICC based color management of RGB user/device spaces through babl as an optional dependency. CMYK colors can be generated on the fly
from RGB or set and retained in CMYK mode - when set in CMYK mode the
colors correspond directly to the device colors in CMYK mode.
- deferred rendering
These drawlist representations are used for scanline/chunk-based
rendering on microcontrollers where framebuffer is to large to fit in
RAM and tiles and threaded rendering on multi-core systems
with SDL2 and /dev/fb0 backends and network transparent rendering
inside ctx terminal. Another way to drive larger than RAM
is to re-render the frame for each segment instead of buffering it,
buffering is however useful when doing networked rendering, ctx
can be configured and adapted to deal with a wide range of scenarios.
- text rendering
- Three font loading backends, stb_truetype, native-ctx and ctx-fs. The ctx.h header ships with a built-in native-ctx font.
In following screenshot a text-file with the commands for the @ glyph
is being edited in vim, with instant update across all clients. This
massively slows down the UI but not enough to be unusuable. With
a simple visual vector editor working directly with the ctx-protocol
this provides for an almost complete live font-editor.
The text-shaping is currently limited to horizontal advances +
horizontal kerning, no ligatures, RTL or vertical glyph advances -
interacting directly with harfbuzz could give us wider support.
- DEC terminal family standard for raster graphics transfer
- kitty graphics
- kitty style raster graphics transfer
- iterm2 inline images
- iterm2 style raster grarphics transfer
- audio recording and playback (only raw pcm for now, opus codec NYI)
- If the declarations for stb_truetype are
included before ctx.h - functions to load fonts from TTF/OTF files
- Optional backend and support code that that gets build when SDL.h is included before ctx.h
- support code to render to cairo contexts if cairo.h is included before ctx.h, useful for conformance verfication and SVG and PDF output.
downloads / sources
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.|
$ git clone https://ctx.graphics/.git
The repository contains the sources for
examples and tests, and the
implementation of 2D vector rasterization
and protocl parser and serializer.
|ctx-font-regular.h||128K||Example font to use with ctx, to be a true single header solution - the ascii subset of this is already defined in ctx.h|
|ctx-x86_64-static||64bit static linux binary - should work in many distros on framebuffer /dev/fb0 and braille backends|
|ctx-i486-static||32bit static linux binary - should work in many distros on framebuffer, /dev/fb0 and braille backends.|
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
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.
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.
- configure fonts
- use separate configured fonts for mono/italic/bold
(keeping current fallback synthesizing code)
- fonts with color emoji
- clip does not clip event boxes/shapes
- some low-level rasterizer glitches
- in_fill is using bounding box
- radial gradient is only using one center
- dimensions of drop-shadow are incorrectly transformed
- changes in texture transform incorrectly picked up by hash-cache
- miter limit (unless round joins are used, all corners are mitered now)
- square line ends
- palm supression during typing in drm/fbdev backend
- cursor keys incorrect (not passing vttest) in vt52 mode
- missing terminal content rewrapping on resize
- hyperlink escape sequences
- performance, there always seem to be room for improvement.
- continued code clean-ups and refactoring, making non-amalgated build work
- glyph fallbacks between fonts
- analytical instead of raster clipping.
- double-width glyphs (terminal) - for non-terminal use this works, for emoji and asian scripts
- multi-head, both for DRM when plugging in HDMI/VGA and networked
connect to ESP32 / html5 canvas clients.
- swap some uses of cairo in GEGL with ctx, pass ctx data
as buffers, or have ctx backed 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
- 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 and spectral 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.)
- 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 like NanoVg.