Rendering and painting
The render target
Section titled “The render target”TerminalRenderer draws a session’s screen into a RenderTexture sized exactly
columns * cellWidth by rows * cellHeight. Every quad lands on integer
pixels and the glyph atlas is sampled texel for texel, which is what keeps the
text free of subpixel shimmer. The texture is at session.Renderer.Target; use
it anywhere a texture goes.
The renderer redraws only when something changed: the emulator’s content, the
cursor or text blink, a theme change, or an overlay edit. It exposes
ScrollOffset for scrollback, Selection for the selected region, and
AfterRender and TargetChanged events.
Grid, render, and display size
Section titled “Grid, render, and display size”Three sizes stay separate:
- Grid is columns and rows: how much text fits. Set it on the session or
with
session.SetSize(cols, rows). - Render size is the cell pixel size, and so the texture resolution. It
comes from the theme’s font size;
session.SetFontSize(pixels)changes it and rebuilds the target. The grid is unaffected. - Display size is the surface the texture is shown on, scaled however that surface is scaled.
What to use when lists which control to set for each goal.
A Terminal Screen (3D) measures its surface and keeps the grid’s shape on it,
centered in a border of the terminal background; turn off Preserve Aspect
to stretch it instead. Its Resolution, in pixels across the screen, sets
the session’s font size for you: the largest at which the columns and rows fit.
With Fit Rows on, the rows follow the columns instead, so the grid fills
the screen; change the column count with session.SetSize. Give one screen
per session a resolution. A player measures only meshes imported with
Read/Write on.
A uGUI screen has a scale mode for the flat case:
| Scale mode | The picture | Use it for |
|---|---|---|
| Native Pixels | One texture pixel per display pixel, centered | The sharpest text, in a panel larger than the grid |
| Fit In Parent | Scaled to the parent, the grid’s shape kept | A fixed grid in a panel of any size |
| Stretch To Fill | Stretched to the parent | A screen driven by a viewport fitter |
| Manual | Fills the RectTransform as your layout sets it | A layout group or an animated panel |
SnapToNativeSize() sizes the RectTransform to the texture once, for a
Manual screen.
For a terminal that fills a window the way a real one does, add a Terminal Viewport Fitter: it derives the cell size from a point size scaled by the display DPI, then reflows the grid to fit the viewport at that size, so the text stays crisp and constant in physical size across displays. Cell Point Size is the cell height at 96 DPI, DPI Override stands in for the display’s DPI when it is above zero, and the grid limits bound the columns and rows the fitter picks.
Painting arbitrary textures
Section titled “Painting arbitrary textures”Beyond text, you can composite textures into the terminal, for inline images or a full bitmap display:
var overlay = session.Renderer.AddOverlay(myTexture, new RectInt(x, y, wCells, hCells));overlay.Tint = Color.white;// ...session.Renderer.RemoveOverlay(overlay);An overlay draws over a cell rectangle after the text pass, and setting any of its properties redraws the grid.
| The texture | Set |
|---|---|
| Covers the cells | Nothing more |
| Sits under text that labels it | BehindText |
| Changes every frame: a video, a camera’s RenderTexture | Live |
| Changes now and then | Call session.Renderer.SetDirty() after each change |
| Hides for a while | Visible = false |
Overlays stay with the renderer through a resize or a font change.
Inside an interface, a TextureView places a texture by layout; see
Textures. For freeform drawing, subscribe to
AfterRender, which hands you the RenderTexture after each redraw with its
bound state restored.
Text attributes and the cursor
Section titled “Text attributes and the cursor”Bold and italic draw in the font’s own styles. Faint dims the color, underline and strikethrough draw as lines, inverse swaps the colors, blink blinks, and invisible text holds its cells blank. The cursor draws as a block, an underline, or a bar, whichever the host asked for, and hides while the view is scrolled into history.
Block elements
Section titled “Block elements”The block element runes (U+2580 through U+259F, the halves, eighths, and quadrants) render as exact rectangles from a geometry table rather than font glyphs, so bars, meters, and fills tile edge to edge at any cell size, and adjoining runes meet without seams. The shade characters stay glyphs, since they are textures rather than shapes.
Supported escape sequences
Section titled “Supported escape sequences”The emulator is a VT100, with the VT102 and xterm additions programs rely
on. Every VT100 screen of vttest passes; Tools/vttest/run.sh in the
development project replays them and checks each one, and Vt100Tests in
the Core tests covers the same ground sequence by sequence. A program you
write for it can rely on these:
| Group | Supported |
|---|---|
| Colors and attributes (SGR) | Bold, faint, italic, underline, blink, inverse, invisible, strikethrough; 16 colors, 256 colors, and truecolor |
| Cursor movement | CUU, CUD, CUF, CUB, CNL, CPL, CHA, HPA, VPA, CUP, HVP, save and restore |
| Cursor display | Show and hide (DECTCEM), shape (DECSCUSR) |
| Erase | In line, in display, scrollback, and characters (ECH) |
| Insert and delete | Lines (IL, DL) and characters (ICH, DCH), insert mode (IRM), repeat (REP) |
| Scrolling | Scroll regions (DECSTBM), SU, SD, index, reverse index, next line |
| Tabs | Set, clear, forward, and backward |
| Line size | Double width (DECDWL), double height (DECDHL), single (DECSWL) |
| Screens | The alternate screen (47, 1047, 1049), reverse screen (DECSCNM), alignment pattern (DECALN), full reset (RIS), soft reset (DECSTR) |
| ANSI modes | Keyboard lock (KAM), insert (IRM), local echo (SRM), new line (LNM) |
| DEC modes | Cursor keys (DECCKM), VT52 (DECANM), 132 columns (DECCOLM), origin (DECOM), autowrap (DECAWM), keypad (DECKPAM, DECKPNM), bracketed paste; smooth scroll, auto repeat, interlace, and the printer modes are accepted |
| Keyboard | Keypad application codes, LEDs (DECLL), answerback (ENQ) |
| VT52 mode | Cursor steps and addressing, home, reverse line feed, erases, the graphics set, identify, keypad modes, and the return to ANSI |
| Mouse | Click, button drag, and any motion tracking (1000, 1002, 1003), X10 and SGR (1006) encodings |
| Character sets | ASCII, United Kingdom, and DEC line drawing through G0 and G1 |
| Reports | Device attributes (DA, DECID), device status and cursor position (DSR), terminal parameters (DECREQTPARM) |
| OSC | The window title (0 and 2) |
UTF-8 and wide East Asian characters are handled. A combining mark takes no
cell: it joins its base letter where Unicode has one character for the pair,
as e and an acute accent become é, and is dropped otherwise. Sixel and
ReGIS graphics are parsed and dropped; the overlay API above covers the
bitmap-display need.
DECCOLM clears the screen and homes the cursor. It also switches the
emulator between 80 and 132 columns when AllowColumnChange is on, or when
the host sets xterm’s mode 40; otherwise the width stays with the screen.
ColumnsRequested reports the request either way. Answerback is what ENQ
is answered with, and KeyboardLedsChanged reports the keyboard lights.
TerminalEmulator.Bell and TitleChanged report the bell and the title, for
a sound or a label of your own.
Scripting is the API guide.