Font
FreeType + HarfBuzz font loading, glyph caching, text shaping, and atlas rendering.
The guikit::Font class provides text rendering support using FreeType for glyph rasterization and HarfBuzz for Unicode text shaping. It caches glyph bitmaps and packs them into a GPU atlas texture.
This doc assumes using namespace guikit is set and #include <guikit/font.hpp> is included.
Otherwise, use guikit::Font instead of Font.
ShapedGlyph
The result of text shaping is returned as a vector of ShapedGlyph:
struct ShapedGlyph {
unsigned int codepoint; // glyph ID from HarfBuzz
unsigned int unicode; // original Unicode codepoint
float xAdvance;
float yAdvance;
float xOffset;
float yOffset;
unsigned int bitmapWidth;
unsigned int bitmapHeight;
int bitmapBearingX;
int bitmapBearingY;
unsigned int bitmapAdvanceX;
float texX;
float texY;
};Constructor / Destructor
Font()
Creates an empty font object. No font is loaded until loadFromFile or loadFromMemory is called.
Font();~Font()
Releases FreeType face, HarfBuzz font, and the GPU atlas texture.
~Font();Available methods
loadFromFile(std::string path)
Loads a font from a file on disk. Returns true on success.
bool loadFromFile(const std::string &path);Example:
Font font;
font.loadFromFile("/usr/share/fonts/truetype/DejaVuSans.ttf");loadFromMemory(const void *data, size_t size)
Loads a font from a buffer in memory (e.g. embedded resource). Returns true on success.
bool loadFromMemory(const void *data, size_t size);Example:
Font font;
font.loadFromMemory(embeddedFontData, embeddedFontSize);setFontSize(unsigned int size)
Sets the font size in pixels (points × DPI / 72). This invalidates the glyph cache and atlas.
void setFontSize(unsigned int size);Example:
font.setFontSize(24);getFontSize()
Returns the current font size in pixels.
unsigned int getFontSize() const;shapeText(std::string text)
Shapes a UTF-8 string using HarfBuzz and returns positioned glyphs. Each glyph includes its bitmap metrics and atlas texture coordinates.
std::vector<ShapedGlyph> shapeText(const std::string &text);Example:
auto glyphs = font.shapeText("Hello, world!");
for (auto &g : glyphs) {
// g.texX, g.texY, g.bitmapWidth, g.bitmapHeight
}getAtlasTexture()
Returns the OpenGL texture ID of the glyph atlas. The atlas is lazily built on first access.
unsigned int getAtlasTexture() const;Example:
glBindTexture(GL_TEXTURE_2D, font.getAtlasTexture());getAtlasWidth()
Returns the width of the atlas texture in pixels.
unsigned int getAtlasWidth() const;getAtlasHeight()
Returns the height of the atlas texture in pixels.
unsigned int getAtlasHeight() const;getAscent()
Returns the font ascender in pixels (distance from baseline to top of tallest glyph).
int getAscent() const;Example:
int ascent = font.getAscent(); // e.g. 18getDescent()
Returns the font descender in pixels (distance from baseline to bottom of lowest glyph, typically negative).
int getDescent() const;Example:
int descent = font.getDescent(); // e.g. -4getLineHeight()
Returns the recommended line height (ascent - descent) in pixels.
int getLineHeight() const;Example:
int lineHeight = font.getLineHeight(); // e.g. 22getKerning(unsigned int left, unsigned int right)
Returns the kerning adjustment between two glyph indices. Returns 0.0f if no kerning or if the font does not support it.
float getKerning(unsigned int left, unsigned int right) const;Example:
float kern = font.getKerning(glyphA, glyphB);Full Example
#include <guikit/font.hpp>
#include <guikit/window.hpp>
using namespace guikit;
int main() {
Window window("Font Demo", 800, 600);
window.setBackground(Color(20, 20, 20, 255));
Font font;
font.loadFromFile("/usr/share/fonts/truetype/DejaVuSans.ttf");
font.setFontSize(32);
auto glyphs = font.shapeText("Hello gui-kit!");
// During rendering, bind font.getAtlasTexture() and
// draw each glyph as a textured quad positioned by
// xOffset/yOffset and sized by bitmapWidth/bitmapHeight
// at the current pen position.
window.show();
return 0;
}