9 , m_pixel_size(pixel_size)
10 , m_atlas_size(atlas_size)
12 m_texture = std::make_unique<Kakshya::TextureContainer>(
18 auto it =
m_cache.find(glyph_index);
27 return &
m_cache.at(glyph_index);
34 "GlyphAtlas::get_or_rasterize -- FontFace not loaded");
38 const FT_UInt idx = FT_Get_Char_Index(
m_face.
get_face(), codepoint);
41 "GlyphAtlas: no glyph for codepoint U+{:04X}",
static_cast<uint32_t
>(codepoint));
51 if (!face || face->size ==
nullptr) {
54 const int32_t
h = (face->size->metrics.ascender - face->size->metrics.descender) >> 6;
62 if (
const FT_Error err = FT_Set_Pixel_Sizes(face, 0,
m_pixel_size); err != 0) {
64 "FT_Set_Pixel_Sizes({}) failed: {}",
m_pixel_size,
static_cast<int>(err));
68 if (
const FT_Error err = FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER); err != 0) {
70 "FT_Load_Glyph({}) failed: {}", glyph_index,
static_cast<int>(err));
74 const FT_Bitmap& bmp = face->glyph->bitmap;
75 const uint32_t gw = bmp.width;
76 const uint32_t gh = bmp.rows;
78 constexpr uint32_t k_pad = 1;
88 "GlyphAtlas full at pixel_size={} atlas_size={}. "
89 "Construct with a larger atlas_size.",
97 "GlyphAtlas: TextureContainer pixel_bytes returned empty span");
103 for (uint32_t row = 0; row < gh; ++row) {
104 const uint8_t* src = bmp.buffer +
static_cast<size_t>(row *
static_cast<uint32_t
>(std::abs(bmp.pitch)));
106 std::memcpy(dst, src, gw);
109 const float inv = 1.F /
static_cast<float>(
m_atlas_size);
120 m.
advance_x =
static_cast<int32_t
>(face->glyph->advance.x >> 6);
122 m_cache.emplace(glyph_index, m);
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
const std::vector< float > * pixels
FT_Face get_face() const
Raw FT_Face handle for use by GlyphAtlas.
bool is_loaded() const
Returns true after a successful load() call.
Owns a single FT_Face loaded from a file path.
std::unique_ptr< Kakshya::TextureContainer > m_texture
uint32_t line_height() const
Line advance in pixels for this atlas's pixel_size.
const GlyphMetrics * get_or_rasterize(FT_UInt glyph_index)
Return metrics for a glyph, rasterizing it into the atlas if needed.
bool rasterize(FT_UInt glyph_index)
std::unordered_map< FT_UInt, GlyphMetrics > m_cache
uint32_t atlas_size() const
Atlas texture dimension (width == height == atlas_size).
GlyphAtlas(FontFace &face, uint32_t pixel_size, uint32_t atlas_size=512)
Construct an atlas for a specific face and pixel size.
@ API
API calls from external code.
@ Portal
High-level user-facing API layer.
@ R8
Single channel 8-bit.
int32_t bearing_x
Horizontal bearing in pixels (from FT_GlyphSlot).
float uv_x0
Left UV edge in atlas texture.
float uv_x1
Right UV edge in atlas texture.
uint32_t height
Glyph bitmap height in pixels.
int32_t advance_x
Horizontal advance in pixels (26.6 fixed-point >> 6).
uint32_t width
Glyph bitmap width in pixels.
float uv_y0
Top UV edge in atlas texture.
int32_t bearing_y
Vertical bearing in pixels (from FT_GlyphSlot).
float uv_y1
Bottom UV edge in atlas texture.
Per-glyph layout and UV data produced by GlyphAtlas.