Repository navigation
Expand file tree
/
Copy pathtruetype.h
More file actions
184 lines (147 loc) · 6.27 KB
/
Copy pathtruetype.h
File metadata and controls
184 lines (147 loc) · 6.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#pragma once
// TrueType Font API for FastLED
//
// Minimal example:
//
// #include "fl/font/truetype.h"
// #include "fl/font/truetype.cpp.hpp" // Include ONCE in your project
//
// // Option 1: Use default embedded font (Covenant5x5 - 9.9KB, 5x5 pixel)
// auto font = fl::Font::loadDefault();
// fl::FontRenderer renderer(font, 10.0f); // 10px height
//
// // Option 2: Load custom font
// auto font = fl::Font::load(fl::span<const uint8_t>(ttf_data, ttf_size));
// fl::FontRenderer renderer(font, 14.0f); // 14px height
//
// // Render a character
// fl::GlyphBitmap glyph = renderer.render('A');
// for (int y = 0; y < glyph.height; ++y) {
// for (int x = 0; x < glyph.width; ++x) {
// uint8_t alpha = glyph.getPixel(x, y); // 0-255
// // Draw to LED at (screenX + glyph.xOffset + x, screenY + glyph.yOffset + y)
// }
// }
//
// // String measurement and kerning
// float width = renderer.measureString("Hello");
// float kern = renderer.getKerning('A', 'V');
#include "fl/stl/vector.h"
#include "fl/stl/shared_ptr.h"
#include "fl/stl/span.h"
#include "fl/stl/stdint.h"
#include "fl/stl/noexcept.h"
namespace fl {
// Forward declarations
class FontImpl; // IWYU pragma: keep
class FontRendererImpl; // IWYU pragma: keep
// Font metrics returned by Font::getMetrics()
struct FontMetrics {
i32 ascent; // Units above baseline
i32 descent; // Units below baseline (typically negative)
i32 lineGap; // Additional spacing between lines
i32 x0, y0; // Bounding box min
i32 x1, y1; // Bounding box max
};
// Glyph (single character) metrics
struct GlyphMetrics {
i32 advanceWidth; // Horizontal advance after glyph
i32 leftSideBearing; // Left side bearing
i32 x0, y0; // Bounding box min
i32 x1, y1; // Bounding box max
bool isEmpty; // True if glyph has no visual representation
};
// Rendered glyph data
struct GlyphBitmap {
fl::vector<u8> data; // Grayscale bitmap (0=transparent, 255=opaque)
i32 width; // Bitmap width in pixels
i32 height; // Bitmap height in pixels
i32 xOffset; // X offset from origin to top-left of bitmap
i32 yOffset; // Y offset from origin to top-left of bitmap (typically negative)
GlyphBitmap() FL_NO_EXCEPT : width(0), height(0), xOffset(0), yOffset(0) {}
// Returns true if this bitmap has valid data
bool valid() const { return !data.empty() && width > 0 && height > 0; }
// Get pixel value at (x, y) - returns 0 if out of bounds
u8 getPixel(i32 x, i32 y) const {
if (data.empty() || x < 0 || y < 0 || x >= width || y >= height) {
return 0;
}
return data[y * width + x];
}
};
// Font class - represents a loaded TrueType font
class Font {
public:
// Load the default embedded font (Covenant5x5 - 9.9KB, 5x5 pixel font)
// Returns nullptr if loading fails
static fl::shared_ptr<Font> loadDefault();
// Load a font from raw TrueType data (.ttf file contents)
// Returns nullptr if the font data is invalid
static fl::shared_ptr<Font> load(fl::span<const u8> fontData);
// Load a specific font from a TrueType collection (.ttc file)
// fontIndex: 0-based index of the font in the collection
static fl::shared_ptr<Font> load(fl::span<const u8> fontData, i32 fontIndex);
virtual ~Font() FL_NO_EXCEPT = default;
// Get the number of fonts in this file (1 for .ttf, possibly more for .ttc)
virtual i32 getNumFonts() const = 0;
// Get overall font metrics (unscaled)
virtual FontMetrics getMetrics() const = 0;
// Get scale factor to achieve a specific pixel height
virtual float getScaleForPixelHeight(float pixelHeight) const = 0;
// Get glyph metrics for a unicode codepoint (unscaled)
virtual GlyphMetrics getGlyphMetrics(i32 codepoint) const = 0;
// Get kerning adjustment between two characters (unscaled)
// Returns the adjustment to add to advance width
virtual i32 getKerning(i32 codepoint1, i32 codepoint2) const = 0;
// Render a single character to a grayscale bitmap
// Returns an empty GlyphBitmap if the character doesn't exist
virtual GlyphBitmap renderGlyph(i32 codepoint, float scale) const = 0;
// Render with antialiasing control
// oversampleX/Y: 1 = no oversampling, 2+ = oversample for smoother edges
virtual GlyphBitmap renderGlyph(i32 codepoint, float scale,
i32 oversampleX, i32 oversampleY) const = 0;
protected:
Font() FL_NO_EXCEPT = default;
};
using FontPtr = fl::shared_ptr<Font>;
// FontRenderer - convenient wrapper for rendering at a specific size
class FontRenderer {
public:
// Create a renderer for the given font at the specified pixel height
FontRenderer(FontPtr font, float pixelHeight);
~FontRenderer() FL_NO_EXCEPT;
// Check if renderer is valid
bool valid() const { return mFont != nullptr; }
// Get the pixel height this renderer was created with
float pixelHeight() const { return mPixelHeight; }
// Get the scale factor being used
float scale() const { return mScale; }
// Get scaled font metrics
struct ScaledMetrics {
float ascent;
float descent;
float lineGap;
float lineHeight() const { return ascent - descent + lineGap; }
};
ScaledMetrics getScaledMetrics() const;
// Render a character at the current size
// Uses 2x2 oversampling by default for smooth edges on LED displays
GlyphBitmap render(i32 codepoint) const;
// Render with custom oversampling
GlyphBitmap render(i32 codepoint, i32 oversampleX, i32 oversampleY) const;
// Render without antialiasing (1x1 oversampling)
GlyphBitmap renderNoAA(i32 codepoint) const;
// Get the advance width for a character (in pixels)
float getAdvance(i32 codepoint) const;
// Get kerning between two characters (in pixels)
float getKerning(i32 codepoint1, i32 codepoint2) const;
// Calculate the width of a string (in pixels)
// Includes kerning between characters
float measureString(const char* str) const;
float measureString(fl::span<const char> str) const;
private:
FontPtr mFont;
float mPixelHeight;
float mScale;
};
} // namespace fl