Check out my first novel, midnight's simulacra!

Spriteful TErminal GrAphics Protocol: Difference between revisions

From dankwiki
(Created page with "STEGAP is my proposal for a terminal graphics protocol facilitating bitmapped sprites combined with terminal glyphs and styling. Just being able to blit a bitmap into a termin...")
 
No edit summary
Line 4: Line 4:
Ideally, I want to be able to:
Ideally, I want to be able to:


* provide a given bitmap in as few bytes as possible
* associate a bitmap with an identifier. this bitmap might not be wholly opaque--transparent pixels are of critical important, translucency less so. i ought be able to reload the bitmap (keeping the size constant), and have it redrawn without flicker.
* associate a bitmap with an identifier. this bitmap might not be wholly opaque--transparent pixels are of critical important, translucency less so. i ought be able to reload the bitmap (keeping the size constant), and have it redrawn without flicker.
* draw text atop the bitmap without a background color, so that the graphic is not obscured except where the glyph is defined
* draw text atop the bitmap without a background color, so that the graphic is not obscured except where the glyph is defined
Line 17: Line 18:


* require me to render text myself
* require me to render text myself
==Bulk data format==
At a minimum, we should accept 32-bit 8bpc BGRA pixels, in row-major order. Our BGRA is byte-oriented, not word-oriented, and thus there ought be no question of endianness: the 8 bits of the Blue channel must be the first byte of each pixel. Assuming a 32-bit BGRA pixel to be natively composed via <tt>((A << 24) | (R << 16) | (G << 8) | B)</tt>, a little-endian machine is storing BGRA, and a big-endian machine is storing ARGB; the big-endian machine would thus need a swizzle to properly output this wire format (alternately, it could work on individual 8-bit units stored as BGRA). This definition corresponds to <tt>PIX_FMT_RGB32</tt> as emitted by FFmpeg. We cannot simply use the native ordering, because the terminal emulator and application might exist in different endianness domains.
If the terminal emulator cannot fully implement RGBA for some reason (perhaps it has only 256 colors at its disposal), it ought itself sensibly quantize the graphic. Likewise, in the absence of composed translucency, the Alpha channel can be partitioned into a wholly transparent range and a wholly opaque range. <b>It is mandatory that a pixel with an Alpha value of 0 not obscure an existing pixel</b>.

Revision as of 20:36, 7 June 2021

STEGAP is my proposal for a terminal graphics protocol facilitating bitmapped sprites combined with terminal glyphs and styling. Just being able to blit a bitmap into a terminal is of little use for libraries like Notcurses. Unfortunately, that's about all that Sixel gives you. Useful background reading might include my Theory and Practice of Sprixels.

Goals as a toolkit developer

Ideally, I want to be able to:

  • provide a given bitmap in as few bytes as possible
  • associate a bitmap with an identifier. this bitmap might not be wholly opaque--transparent pixels are of critical important, translucency less so. i ought be able to reload the bitmap (keeping the size constant), and have it redrawn without flicker.
  • draw text atop the bitmap without a background color, so that the graphic is not obscured except where the glyph is defined
  • move the bitmap in a flicker-free way elsewhere in the visible area
  • update glyphs (partially-)obscured by a bitmap without disturbing the bitmap
  • destroy the bitmap with a single escape, ideally yielding whatever had been obscured by said bitmap

I do not require the ability to:

  • stack text atop text within a cell, with or without intermediate graphics

A solution must not:

  • require me to render text myself

Bulk data format

At a minimum, we should accept 32-bit 8bpc BGRA pixels, in row-major order. Our BGRA is byte-oriented, not word-oriented, and thus there ought be no question of endianness: the 8 bits of the Blue channel must be the first byte of each pixel. Assuming a 32-bit BGRA pixel to be natively composed via ((A << 24) | (R << 16) | (G << 8) | B), a little-endian machine is storing BGRA, and a big-endian machine is storing ARGB; the big-endian machine would thus need a swizzle to properly output this wire format (alternately, it could work on individual 8-bit units stored as BGRA). This definition corresponds to PIX_FMT_RGB32 as emitted by FFmpeg. We cannot simply use the native ordering, because the terminal emulator and application might exist in different endianness domains.

If the terminal emulator cannot fully implement RGBA for some reason (perhaps it has only 256 colors at its disposal), it ought itself sensibly quantize the graphic. Likewise, in the absence of composed translucency, the Alpha channel can be partitioned into a wholly transparent range and a wholly opaque range. It is mandatory that a pixel with an Alpha value of 0 not obscure an existing pixel.