Renderovací pipeline
TUIX renderuje terminálové UI přes vícestupňový pipeline: výpočet geometrie, tvorbu obsahu, kompozici a delta renderování. Všechny fáze běží v C pro maximální výkon.
Fáze pipeline
- Výpočet geometrie — vynásobit proporční modifikátory rozměry terminálu
- Tvorba obsahu — build_content každého widgetu vytváří pixelový buffer
- Kompozice — vrstvení bufferů scén do finálního framebufferu (pořadí malíře)
- Delta renderování — hashování řádků, přeskočení nezměněných, výstup pouze změněného ANSI
Výpočet geometrie
Před tvorbou obsahu přepočítá řešič geometrie plovoucí modifikátory widgetů na absolutní pixelové souřadnice podle aktuální velikosti terminálu. To běží každý snímek, takže widgety se automaticky přizpůsobují změně velikosti terminálu.
buffer.width = terminal_width × width_mod
buffer.height = terminal_height × height_mod
buffer.margin_left = terminal_width × margin_left_mod
buffer.margin_top = terminal_height × margin_top_modPokud sestavovač widgetu definuje callback on_resize, zavolá se po výpočtu geometrie s novou šířkou a výškou.
Model pixelu
Každá buňka v bufferu je TuixPixel obsahující: 8bajtový UTF-8 symbol, RGB barvy popředí a pozadí, stylové příznaky (tučné, kurzíva, podtržení, ztlumení) a pole cache kvantizace.
| Pole | Velikost | Popis |
|---|---|---|
| sym | 8 bytes | UTF-8 znak (vyplněný nulovými bajty) |
| styles.fg | 3 bytes | RGB popředí (0–255 na kanál) |
| styles.bg | 3 bytes | RGB pozadí (0–255 na kanál) |
| styles.bold | 1 byte | Příznak tučného textu |
| styles.italic | 1 byte | Příznak kurzívy |
| styles.underlined | 1 byte | Příznak podtržení |
| styles.dim | 1 byte | Příznak ztlumeného textu |
| q_fg, q_bg | 6 bytes | Cache kvantizovaných barev (RGB565) |
| q_cached | 1 byte | Zda je kvantizační cache platná |
Kompozice
Kompozitor alokuje finální framebuffer o velikosti terminal_width × (terminal_height - 1). Spodní řádek je rezervovaný pro log výstup. Buffer vyplní prázdnými pixely (bílá mezera na černém pozadí), poté projde buffery aktivní scény v pořadí vytvoření. Pro každý buffer ořízne obsah na hranice obrazovky a zkopíruje pixely do finálního bufferu pomocí memcpy.
Delta renderování
Renderer porovnává aktuální snímek s předchozím, aby přeskočil nezměněný obsah:
- Hashovat každý řádek pomocí FNV-1a nad surovými (nekvantizovanými) daty pixelů
- Porovnat s hashi řádků z předchozího snímku
- Zpracovat pouze řádky se změněným hashem
- Pro změněné řádky kvantizovat barvy (RGB → RGB565 pomocí předpočítané 128KB LUT)
- Seskupit sousední pixely se stejným stylem do jedné SGR escape sekvence
- Vysílat nastavení kurzoru (\e[Y;XH) jen když je potřeba (přeskočit pro sekvenční buňky)
- Streamovat výstup po 256KB blocích
Režimy barevného výstupu
LUT pro kvantizaci barev mapuje hodnoty RGB565 na nejbližší dostupnou terminálovou barvu. Automaticky se používají tři režimy podle nejlepší shody:
| Režim | Formát | Barvy |
|---|---|---|
| ANSI16 | \e[30-37m / \e[90-97m | 16 základních terminálových barev |
| ANSI256 | \e[38;5;Nm | Paleta 256 barev |
| Truecolor | \e[38;2;R;G;Bm | Plné 24-bit RGB (16,7 M barev) |
Halfblock renderování (volitelný modul)
Zdrojová distribuce obsahuje halfblock renderer (rendering_halfblocks.c), který používá znak Unicode horního půlbloku (▀ U+2580) pro dosažení 2× vertikálního rozlišení. Dva řádky pixelů jsou zabaleny do jednoho terminálového řádku tak, že se barva popředí použije pro horní polovinu a barva pozadí pro dolní polovinu.
Zpracování změny velikosti
Rozměry terminálu se čtou v každém snímku pomocí API specifických pro platformu (ReadConsoleScreenBufferInfo na Windows, ioctl TIOCGWINSZ na POSIX). Při detekci změny velikosti kompozitor realokuje svůj statický finální buffer, přepočítají se geometrie všech widgetů a spustí se kompletní překreslení.