Font¶
Descriptor for a bitmap font using 1bpp sprites.
Description¶
A Font contains an array of Sprite structures, one for each character in the font's character set. Each glyph is rendered as a 1bpp sprite, allowing consistent rendering across platforms.
The font uses fixed-width glyphs for simplicity and performance. All glyphs share the same width and height, with spacing between characters controlled by the spacing field.
Namespace¶
Structure¶
const Sprite* glyphs¶
Array of sprites, one per character (indexed by character code - firstChar).
Type: const Sprite*
Access: Read-only
Notes: - Array must contain sprites for all characters from firstChar to lastChar - Each sprite represents one character glyph - Should be stored in flash (const/constexpr) for best performance
Example:
static const Sprite FONT_GLYPHS[] = {
spaceGlyph, // Index 0 = ' ' (firstChar = 32)
exclamationGlyph, // Index 1 = '!'
// ... more glyphs
};
static const Font myFont = {
FONT_GLYPHS,
32, // firstChar
126, // lastChar
5, // glyphWidth
7, // glyphHeight
1, // spacing
8 // lineHeight
};
uint8_t firstChar¶
First character code in the font.
Type: uint8_t
Access: Read-only
Default: Typically 32 (space character)
Notes: - ASCII code of the first character - Common: 32 (space ' ') for ASCII fonts - Glyphs array starts at index 0 for this character
Example:
uint8_t lastChar¶
Last character code in the font.
Type: uint8_t
Access: Read-only
Default: Typically 126 (tilde '~')
Notes: - ASCII code of the last character - Common: 126 (tilde '~') for full ASCII fonts - Glyphs array must contain (lastChar - firstChar + 1) sprites
Example:
uint8_t glyphWidth¶
Fixed width of each glyph in pixels.
Type: uint8_t
Access: Read-only
Notes: - All glyphs must have the same width - Typical values: 5, 6, 8 pixels - Smaller = more characters per line, less readable
Example:
uint8_t glyphHeight¶
Fixed height of each glyph in pixels.
Type: uint8_t
Access: Read-only
Notes: - All glyphs must have the same height - Typical values: 7, 8, 10 pixels - Smaller = more lines, less readable
Example:
uint8_t spacing¶
Horizontal spacing between characters in pixels.
Type: uint8_t
Access: Read-only
Default: Typically 1
Notes: - Space added between characters - 0 = no spacing (characters touch) - 1 = 1 pixel gap (common) - Higher values = more readable but wider text
Example:
uint8_t lineHeight¶
Total line height including vertical spacing.
Type: uint8_t
Access: Read-only
Notes: - Should be glyphHeight + verticalSpacing - Used for line breaks and multi-line text - Typical: glyphHeight + 1 or glyphHeight + 2
Example:
Built-in Fonts¶
FONT_5X7¶
Standard 5x7 pixel font (built-in).
Properties: - Width: 5 pixels - Height: 7 pixels - Characters: Typically ASCII 32-126 - Spacing: 1 pixel - Line height: 8 pixels
Usage:
Creating Custom Fonts¶
Step 1: Create Glyph Sprites¶
// Space character (ASCII 32)
static const uint16_t SPACE_GLYPH[] = {
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000
};
// 'A' character (ASCII 65)
static const uint16_t A_GLYPH[] = {
0b00100,
0b01010,
0b10001,
0b11111,
0b10001,
0b10001,
0b00000
};
// ... more glyphs
Step 2: Create Glyph Array¶
static const Sprite FONT_GLYPHS[] = {
{SPACE_GLYPH, 5, 7}, // Index 0 = ' ' (32)
// ... more glyphs
{A_GLYPH, 5, 7}, // Index 33 = 'A' (65)
// ... more glyphs
};
Step 3: Create Font Structure¶
static const Font MY_FONT = {
FONT_GLYPHS, // glyphs array
32, // firstChar (space)
126, // lastChar (tilde)
5, // glyphWidth
7, // glyphHeight
1, // spacing
8 // lineHeight
};
Step 4: Use Font¶
Usage Example¶
#include "graphics/Font.h"
#include "graphics/Renderer.h"
// Using built-in font
void draw(Renderer& renderer) override {
// Default font
renderer.drawText("Score: 100", 10, 10, Color::White, 1);
// Explicit font
renderer.drawText("Score: 100", 10, 30, Color::White, 1, &FONT_5X7);
// Centered text with font
renderer.drawTextCentered("Game Over", 64, Color::Yellow, 2, &FONT_5X7);
}
// Custom font example
static const uint16_t CUSTOM_GLYPHS[][7] = {
// Space, A, B, C, etc.
};
static const Sprite CUSTOM_SPRITES[] = {
{CUSTOM_GLYPHS[0], 6, 8}, // Space
{CUSTOM_GLYPHS[1], 6, 8}, // A
// ... more
};
static const Font CUSTOM_FONT = {
CUSTOM_SPRITES,
32, // firstChar
90, // lastChar (A-Z only)
6, // width
8, // height
1, // spacing
9 // lineHeight
};
void draw(Renderer& renderer) override {
renderer.drawText("CUSTOM", 10, 10, Color::White, 1, &CUSTOM_FONT);
}
Text Sizing¶
Calculate text dimensions:
int getTextWidth(const Font* font, const char* text) {
if (!font || !text) return 0;
int width = 0;
for (int i = 0; text[i] != '\0'; i++) {
if (text[i] >= font->firstChar && text[i] <= font->lastChar) {
width += font->glyphWidth + font->spacing;
}
}
return width - font->spacing; // Remove last spacing
}
int getTextHeight(const Font* font) {
return font ? font->lineHeight : 8;
}
Performance Considerations¶
- Font storage: Store fonts in flash (const/constexpr) for best performance
- Glyph lookup: Fast array access (character code - firstChar)
- Fixed width: Fixed-width fonts are faster than variable-width
- Font switching: Changing fonts is fast (just pointer assignment)
ESP32 Considerations¶
- Memory: Store font data in flash, not RAM
- Font size: Larger fonts use more flash memory
- Character range: Limit character range to save memory if not needed
See Also¶
- Renderer - Rendering system that uses fonts
- Sprite - Sprite structure used for glyphs
- Manual - Basic Rendering
- API Overview