Introduction
The sdl2_ttf plugin is a thin adapter around the SDL2_ttf library (which brings FreeType along): one plugin, one library. It initialises itself: TTF_Init runs in the plugin’s Ready hook when the plugin is loaded and TTF_Quit at shutdown, so there is no init or quit verb — sdl2ttf.OpenFont works from the first statement, headless too. Text leaves this plugin as pixels, never as a window or a texture: RenderText returns the same OMVF RGBA8 packet that sdl2image.Load and image.Load build and that sdl2.DrawPixels, sdl2.TextureFromPixels, sdl2.UpdateTexture and gl.UpdateTexture accept. The blob is the interface between the plugins.
Two ways onto the screen
For a line that changes every frame — a score, a counter, a status — render on demand and draw at once: sdl2.DrawPixels($Win, 10, 10, sdl2ttf.RenderText($Font, "Score 12", 255, 255, 255)). For a label that stays, render once, keep it as a texture (sdl2.TextureFromPixels) and draw the texture each frame like any sprite. And for text that belongs inside a picture — a caption on a photo, a watermark on a frame that goes to a file — DrawText blends the text into an existing packet in place.
Libraries and fonts at run time
SDL2_ttf and SDL2 (for the surface functions) are opened when the plugin loads, before the script starts; if either is missing the script does not start, and the message names the file to copy into the runtime folder. No window and no sdl2.Init are needed to render text. DominScript ships no font: the script names a font file of the system (/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf on Linux, C:\Windows\Fonts\arial.ttf on Windows) or its own TTF/OTF next to the script; FileExists is there to choose one.
Fonts
Opening a font file at a size, and its metrics.
sdl2ttf.OpenFont
sdl2ttf.OpenFont(path, pt) -> intOpens a TrueType or OpenType font file at pt points and returns a font id (1–32). Up to 32 fonts may be open at once; a size is a separate font.
| Name | Type | Description |
|---|---|---|
| path | string | the .ttf / .otf file |
| pt | int | point size, 1–1024 |
The font id. A missing or unreadable file is a runtime error naming the file.
i32 $Font = sdl2ttf.OpenFont("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 24);
sdl2ttf.CloseFont
sdl2ttf.CloseFont(fontId) -> intCloses the font and frees its slot. Fonts still open at shutdown are closed by the plugin. Closing an id that is not open is a runtime error.
| Name | Type | Description |
|---|---|---|
| fontId | int | from OpenFont |
1.
sdl2ttf.SetStyle
sdl2ttf.SetStyle(fontId, bold, italic, underline) -> intSets the synthetic style of the font for everything measured or rendered afterwards; 0 for all three is the plain face.
| Name | Type | Description |
|---|---|---|
| fontId | int | from OpenFont |
| bold | int | 0 or 1 |
| italic | int | 0 or 1 |
| underline | int | 0 or 1 |
1.
sdl2ttf.FontHeight
sdl2ttf.FontHeight(fontId) -> intThe height of the font in pixels: what every rendered line of this font is tall.
| Name | Type | Description |
|---|---|---|
| fontId | int | from OpenFont |
Pixels.
sdl2ttf.LineSkip
sdl2ttf.LineSkip(fontId) -> intThe recommended distance between the tops of two consecutive lines, in pixels (at least FontHeight).
| Name | Type | Description |
|---|---|---|
| fontId | int | from OpenFont |
Pixels.
i32 $Y = 20; sdl.DrawPixels($Win, 20, $Y, sdl2ttf.RenderText($Font, "first line", 255, 255, 255)); $Y += sdl2ttf.LineSkip($Font); sdl.DrawPixels($Win, 20, $Y, sdl2ttf.RenderText($Font, "second line", 255, 255, 255));
Measuring
The size a string will have, before rendering it.
sdl2ttf.TextWidth
sdl2ttf.TextWidth(fontId, text) -> intThe width in pixels the UTF-8 text renders to with this font and style — equal to the width of the packet RenderText returns for it. The empty string is 0 wide.
| Name | Type | Description |
|---|---|---|
| fontId | int | from OpenFont |
| text | string | UTF-8 |
Pixels.
/* centre a title */ i32 $X = (800 - sdl2ttf.TextWidth($Font, "Game over")) / 2;
sdl2ttf.TextHeight
sdl2ttf.TextHeight(fontId, text) -> intThe height in pixels the text renders to; for a single line this is the font height.
| Name | Type | Description |
|---|---|---|
| fontId | int | from OpenFont |
| text | string | UTF-8 |
Pixels.
Rendering
From text to pixels — a new packet, or into an existing one.
sdl2ttf.RenderText
sdl2ttf.RenderText(fontId, text, r, g, b) -> blobRenders the UTF-8 text anti-aliased (blended) in the colour r, g, b and returns it as an OMVF RGBA8 pixel packet: a 64-byte header, then width × height × 4 bytes. The glyph coverage becomes the alpha channel, so the packet composes over any background when drawn. The packet is exactly TextWidth × TextHeight pixels; the empty string gives a 1×1 transparent pixel.
| Name | Type | Description |
|---|---|---|
| fontId | int | from OpenFont |
| text | string | UTF-8, up to 64 KiB |
| r, g, b | int | text colour, 0–255 each |
The pixel packet, ready for sdl2.DrawPixels (draw now), sdl2.TextureFromPixels (keep as a texture), gl.UpdateTexture, a file or a socket.
/* every frame: the one-line form for changing text */ sdl.DrawPixels($Win, 10, 10, sdl2ttf.RenderText($Font, "Score " + str.FromInt($Score), 255, 220, 120)); /* once: a label kept as a texture, drawn like a sprite */ i32 $Title = sdl.TextureFromPixels($Win, sdl2ttf.RenderText($Big, "DominScript", 255, 255, 255));
Any text on an SDL2 or OpenGL surface. Render on demand for text that changes; keep a texture for text that stays — rendering is a FreeType pass plus a texture upload, cheap for a few lines a frame, wasteful for a hundred static ones.
sdl2ttf.DrawText
sdl2ttf.DrawText(ref blob $Pixels, fontId, x, y, text, r, g, b) -> intRenders the text and alpha-blends it into the RGBA8 pixel packet $Pixels at (x, y), in place and clipped to the packet — the packet keeps its size. The target may be a sdl2image.Load result, an image packet, or an earlier RenderText: this is how a caption goes onto a picture before it becomes a texture, or onto a frame on its way to a file.
| Name | Type | Description |
|---|---|---|
| $Pixels | ref blob | an OMVF RGBA8 packet; modified in place |
| fontId | int | from OpenFont |
| x, y | int | top-left of the text in the packet; may be negative or beyond the edge (clipped) |
| text | string | UTF-8 |
| r, g, b | int | text colour, 0–255 each |
The number of text pixels that landed inside the packet (0 when fully clipped or for the empty string). A blob that is not an RGBA8 packet is a runtime error.
blob $Photo[1] = sdl2image.Load("holiday.jpg"); sdl2ttf.DrawText(ref $Photo, $Font, 16, 16, "Lake Balaton, 2026", 255, 255, 255); i32 $Tex = sdl.TextureFromPixels($Win, $Photo); /* the caption is part of the picture now */
Text that belongs to an image rather than to the screen: captions, watermarks, labels on a frame that is written out or sent on. For text on the window itself, RenderText + sdl2.DrawPixels is the shorter path.
Files
Choosing a font that is actually there.
sdl2ttf.FileExists
sdl2ttf.FileExists(path) -> int1 if the file can be opened for reading, else 0. A convenience for picking a system font before opening it — the usual places differ per OS and no font ships with DominScript.
| Name | Type | Description |
|---|---|---|
| path | string | the file to test |
1 or 0.
string $Path[260] = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"; if (sdl2ttf.FileExists($Path) == 0) { $Path = "C:\\Windows\\Fonts\\arial.ttf"; }