libgui 2.01
libgui is a GUI library for the GameCube, Wii, and Wii U
 
Loading...
Searching...
No Matches
GuiTextRenderer.h
1/****************************************************************************
2 * libgui
3 * Daryl Borth 2026
4 * GuiTextRenderer.h
5 ***************************************************************************/
6#pragma once
7
8#include <stdint.h>
9#include <map>
10#include <vector>
11#include <ft2build.h>
12#include FT_FREETYPE_H
13
14#include "Gui.h"
15
16// Legacy Text Styling Constants
17#define GUI_TEXT_NULL 0x0000
18#define GUI_TEXT_JUSTIFY_LEFT 0x0001
19#define GUI_TEXT_JUSTIFY_CENTER 0x0002
20#define GUI_TEXT_JUSTIFY_RIGHT 0x0004
21#define GUI_TEXT_JUSTIFY_MASK 0x000f
22
23#define GUI_TEXT_ALIGN_TOP 0x0010
24#define GUI_TEXT_ALIGN_MIDDLE 0x0020
25#define GUI_TEXT_ALIGN_BOTTOM 0x0040
26#define GUI_TEXT_ALIGN_BASELINE 0x0080
27#define GUI_TEXT_ALIGN_GLYPH_TOP 0x0100
28#define GUI_TEXT_ALIGN_GLYPH_MIDDLE 0x0200
29#define GUI_TEXT_ALIGN_GLYPH_BOTTOM 0x0400
30#define GUI_TEXT_ALIGN_MASK 0x0ff0
31
32#define GUI_TEXT_STYLE_UNDERLINE 0x1000
33#define GUI_TEXT_STYLE_STRIKE 0x2000
34#define GUI_TEXT_STYLE_MASK 0xf000
35
36const PixelColor black = {0, 0, 0, 255};
37
40struct FontOffset {
41 int16_t ascender;
42 int16_t descender;
43 int16_t max;
44 int16_t min;
45};
46
49struct GlyphData {
50 int16_t renderOffsetX;
51 uint16_t glyphAdvanceX;
52 uint16_t glyphAdvanceY;
53 uint32_t glyphIndex;
54
57 uint16_t textureWidth;
58 uint16_t textureHeight;
59
63 uint16_t drawWidth;
64 uint16_t drawHeight;
65
66 int16_t renderOffsetY;
69
70 void* texture;
71};
72
79private:
80 FT_Library ftLibrary;
81 FT_Face ftFace;
82 int16_t currentPixelSize;
83 bool ftKerningEnabled;
84
85 GlyphRenderer* renderer;
86
87 struct ftData {
88 FontOffset align;
89 bool metricsReady;
90 std::map<wchar_t, GlyphData> charMap;
91
92 // Direct index for the first 256 characters, so the common lookup is one array read rather than
93 // two std::map searches. null: not looked up yet; &missingGlyph: the font has no such glyph.
94 GlyphData* fast[256];
95
96 ftData() : metricsReady(false) {
97 align.ascender = align.descender = align.max = align.min = 0;
98 for (int i = 0; i < 256; ++i) fast[i] = nullptr;
99 }
100 };
101
102 std::map<int16_t, ftData> fontData;
103 ftData* current; // fontData[currentPixelSize], or null until it is needed (map nodes never move)
104 std::vector<uint16_t> widthScratch; // scrollWindow()'s running widths, kept so it doesn't allocate
105 std::vector<wchar_t> lineScratch;
106 static GlyphData missingGlyph;
107 static uint32_t metricsGeneration;
108
109 // Internal Calculations
110 int16_t getStyleOffsetWidth(uint16_t width, uint32_t format);
111 int16_t getStyleOffsetHeight(FontOffset* offset, uint32_t format);
112 void drawTextFeature(int16_t x, int16_t y, uint16_t width, FontOffset* offsetData, uint32_t format, const PixelColor& color);
113
114 // Font Management
115 void unloadFont();
116 GlyphData* cacheGlyphData(wchar_t charCode, int16_t pixelSize);
117 // The glyph for a character at the current size: the fast table first, cacheGlyphData() on a miss.
118 // null if the font has none.
119 GlyphData* glyph(wchar_t charCode);
120
121 // Physical-pixels-per-design-pixel glyphs are rasterized at (see
122 // VideoDriver::getUIScale()).
123 float uiScale;
124
125public:
134 GuiTextRenderer(const uint8_t* fontBuffer, FT_Long bufferSize, GlyphRenderer* glyphRenderer, float uiScale = 1.0f);
136
140 void setPixelSize(int16_t pixelSize);
141
143 void clearGlyphCache() { unloadFont(); }
144
145 // Core Drawing Signatures
153 uint16_t drawText(int16_t x, int16_t y, const wchar_t* text, PixelColor color = black, uint32_t renderFlags = 0);
155 uint16_t drawText(int16_t x, int16_t y, const char* text, PixelColor color = black, uint32_t renderFlags = 0);
156
157 // Dimensions & Offsets
159 uint16_t getWidth(const wchar_t* text);
160
164 int fitCount(const wchar_t* text, int maxWidth);
165
171 void scrollWindow(const wchar_t* text, uint32_t textlen, uint32_t pos, int maxWidth, wchar_t* out);
172
175 static uint32_t getMetricsGeneration() { return metricsGeneration; }
177 uint16_t getWidth(const char* text);
179 uint16_t getHeight(const wchar_t* text);
181 uint16_t getHeight(const char* text);
182
185 void getOffset(const wchar_t* text, FontOffset* offset);
186
187 // Utilities
189 static wchar_t* charToWideChar(const char* p);
190};
191
192extern GuiTextRenderer *fontSystem;
Umbrella header for the platform-agnostic libgui core.
Draws glyph textures and solid rectangles on behalf of GuiTextRenderer.
FreeType2-based glyph shaping/caching.
void setPixelSize(int16_t pixelSize)
Selects the pixel size subsequent drawText()/getWidth()/getHeight() calls use.
uint16_t getHeight(const wchar_t *text)
static wchar_t * charToWideChar(const char *p)
uint16_t drawText(int16_t x, int16_t y, const wchar_t *text, PixelColor color=black, uint32_t renderFlags=0)
Draws text at (x, y) using the current pixel size.
static uint32_t getMetricsGeneration()
Changes whenever a measurement made earlier could now come out differently (a renderer was made or it...
int fitCount(const wchar_t *text, int maxWidth)
How many leading characters of text fit in maxWidth (the largest n for which the first n characters m...
void scrollWindow(const wchar_t *text, uint32_t textlen, uint32_t pos, int maxWidth, wchar_t *out)
The part of a horizontally scrolling line that is shown at one scroll position: the text from pos on,...
void getOffset(const wchar_t *text, FontOffset *offset)
uint16_t getWidth(const wchar_t *text)
void clearGlyphCache()
Destroys every cached glyph texture. Glyphs are re-rendered when next used.
GuiTextRenderer(const uint8_t *fontBuffer, FT_Long bufferSize, GlyphRenderer *glyphRenderer, float uiScale=1.0f)
Per-pixel-size font metrics used for text-block alignment/positioning.
int16_t max
Height above the baseline of the tallest glyph in the measured string (see GuiTextRenderer::getOffset...
int16_t min
Depth below the baseline of the lowest glyph in the measured string (see GuiTextRenderer::getOffset()...
int16_t descender
Font descender for the current size (negative: distance below the baseline), in design pixels.
int16_t ascender
Font ascender for the current size (distance above the baseline), in design pixels.
Cached per-glyph metrics and rasterized texture, keyed by (pixel size, char code) in GuiTextRenderer:...
int16_t renderOffsetX
Horizontal offset from the pen position to the bitmap's left edge.
uint16_t glyphAdvanceX
Horizontal pen advance after this glyph.
uint16_t textureWidth
Pixel dims of the rasterized bitmap/texture, at uiScale - always >= drawWidth/drawHeight,...
uint16_t drawWidth
Design-pixel dims to actually draw the quad at (textureWidth/Height divided back down by uiScale) - k...
int16_t renderOffsetMax
Height of the glyph bitmap above the baseline (feeds FontOffset::max)
uint32_t glyphIndex
FreeType glyph index.
int16_t renderOffsetY
Height of the bitmap's top edge above the baseline.
int16_t renderOffsetMin
Depth of the glyph bitmap below the baseline (feeds FontOffset::min)
uint16_t glyphAdvanceY
Vertical pen advance after this glyph.
uint16_t drawHeight
Height counterpart of drawWidth.
uint16_t textureHeight
Height counterpart of textureWidth.
void * texture
Abstracted texture pointer.
8-bit-per-channel RGBA color used by the video interfaces.
Definition Mesh.h:16