Files
dusk/.claude/display-text.md
T
2026-06-16 12:29:36 -05:00

2.8 KiB

Display -- Text Rendering

Source: src/dusk/display/text/

See also: .claude/display-spritebatch.md, .claude/display-texture.md


Overview

Text rendering is layered on top of the SpriteBatch. Each character maps to a glyph tile in a bitmap font atlas; textDraw builds the corresponding spritebatchsprite_t values and pushes them to the global SPRITEBATCH. The caller is responsible for flushing the batch.


Font type (font.h)

typedef struct {
  texture_t *texture;   // glyph atlas texture
  tileset_t *tileset;   // grid describing glyph size + UV layout
} font_t;

Both pointers are caller-owned. The text system does not allocate or free them.

extern font_t FONT_DEFAULT;

FONT_DEFAULT is the engine's built-in bitmap font. It is initialised during textInit() and available for the engine lifetime.


Character range

#define TEXT_CHAR_START '!'   // ASCII 33

The glyph atlas begins at '!' (ASCII 33). Characters below this value -- space, control characters -- are handled specially:

  • ' ' (space) advances the cursor by one tile width without drawing.
  • Characters below TEXT_CHAR_START other than space are skipped.

API (text.h)

// Initialises the text system and FONT_DEFAULT.
errorret_t textInit(void);

// Disposes of the text system.
errorret_t textDispose(void);

// Draw a null-terminated string at (x, y) in screen/world space.
// Pushes sprites to SPRITEBATCH. Caller must call spriteBatchFlush()
// after all text has been drawn.
errorret_t textDraw(
  const float_t x,
  const float_t y,
  const char_t *text,
  const color_t color,
  font_t *font
);

// Measure the bounding box of a string without drawing it.
void textMeasure(
  const char_t *text,
  const font_t *font,
  int32_t *outWidth,
  int32_t *outHeight
);

// Low-level: build a single glyph sprite at position pos.
// Returns a spritebatchsprite_t ready for spriteBatchBuffer.
spritebatchsprite_t textGetSprite(
  const vec2 pos,
  const char_t c,
  const font_t *font
);

Typical usage

// Inside a render callback:
errorChain(textDraw(10.0f, 10.0f, "Hello", COLOR_WHITE, &FONT_DEFAULT));
errorChain(spriteBatchFlush());

If you are also drawing UI frames or other sprites in the same pass, batch all the textDraw and spriteBatchBuffer calls first, then call spriteBatchFlush() once at the end.


Notes

  • Text coordinates are in the same space as the scene render (screen space for UI, or world space if placed in the scene).
  • textMeasure returns pixel dimensions based on the font's tileset.tileWidth and tileset.tileHeight. Use it to centre or right-align text before drawing.
  • For UI-attached text (dialogue, labels), prefer the uitextbox_t system which handles word-wrap and paging automatically (see .claude/ui.md).