Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .mailmap
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
IOleg <124497826+IOleg-crypto@users.noreply.github.com> <iolegworkplace@gmail.com>
IOleg <124497826+IOleg-crypto@users.noreply.github.com> <guchkooleg7@gmail.com>
IOleg <124497826+IOleg-crypto@users.noreply.github.com> unknown <iolegworkplace@gmail.com>
IOleg <124497826+IOleg-crypto@users.noreply.github.com> unknown <guchkooleg7@gmail.com>
IOleg <124497826+IOleg-crypto@users.noreply.github.com> IOleg-sus <guchkooleg7@gmail.com>
IOleg <124497826+IOleg-crypto@users.noreply.github.com> IOleg <guchkooleg7@gmail.com>
IOleg <124497826+IOleg-crypto@users.noreply.github.com> I Oleg <guchkooleg7@gmail.com>
135 changes: 51 additions & 84 deletions engine/graphics/freetype_gl_atlas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,62 +7,61 @@ namespace Chained
Shutdown();
}

// ── helpers ──────────────────────────────────────────────────────────────
static std::string CodepointToUTF8(uint32_t cp)
std::string FreeTypeGLAtlas::CodepointToUTF8(uint32_t cp) const
{
std::string s;
if (cp < 0x80)
if (cp < 128)
{
s += static_cast<char>(cp);
return std::string(1, static_cast<char>(cp));
}
else if (cp < 0x800)
{
s += static_cast<char>(0xC0 | (cp >> 6));
s += static_cast<char>(0x80 | (cp & 0x3F));
}
else if (cp < 0x10000)

if (cp < 0x800)
{
s += static_cast<char>(0xE0 | (cp >> 12));
s += static_cast<char>(0x80 | ((cp >> 6) & 0x3F));
s += static_cast<char>(0x80 | (cp & 0x3F));
char bytes[3] = {static_cast<char>(0xC0 | (cp >> 6)), static_cast<char>(0x80 | (cp & 0x3F)), '\0'};
return std::string(bytes);
}
else

char bytes[4] = {static_cast<char>(0xE0 | (cp >> 12)), static_cast<char>(0x80 | ((cp >> 6) & 0x3F)),
static_cast<char>(0x80 | (cp & 0x3F)), '\0'};
return std::string(bytes);
}

bool FreeTypeGLAtlas::SetupFont(ftgl::texture_font_t* font)
{
if (!font)
{
s += static_cast<char>(0xF0 | (cp >> 18));
s += static_cast<char>(0x80 | ((cp >> 12) & 0x3F));
s += static_cast<char>(0x80 | ((cp >> 6) & 0x3F));
s += static_cast<char>(0x80 | (cp & 0x3F));
CH_CORE_ERROR("FreeTypeGLAtlas: font creation failed");
Shutdown();
return false;
}
return s;

font->hinting = 1;
font->kerning = 1;

PreloadRange(32, 96);
PreloadRange(0x0400, 256);
return true;
}

// ── init ─────────────────────────────────────────────────────────────────
bool FreeTypeGLAtlas::Init(const std::string& path, float ptSize, uint32_t atlasW, uint32_t atlasH)
{
Shutdown();
m_AtlasWidth = atlasW;
m_AtlasHeight = atlasH;
m_PtSize = ptSize;

m_Atlas = ftgl::texture_atlas_new(atlasW, atlasH, 1); // depth 1 = alpha only
m_Atlas = ftgl::texture_atlas_new(atlasW, atlasH, 1);
if (!m_Atlas)
{
CH_CORE_ERROR("FreeTypeGLAtlas: texture_atlas_new failed ({}x{})", atlasW, atlasH);
return false;
}

m_Font = ftgl::texture_font_new_from_file(m_Atlas, ptSize, path.c_str());
if (!m_Font)
if (!SetupFont(m_Font))
{
CH_CORE_ERROR("FreeTypeGLAtlas: texture_font_new_from_file failed '{}'", path);
return false;
}
m_Font->hinting = 1;
m_Font->kerning = 1;

// Preload ASCII (32–127) and Cyrillic (0x0400–0x04FF)
PreloadRange(32, 96);
PreloadRange(0x0400, 256);

CH_CORE_INFO("FreeTypeGLAtlas: loaded '{}' pt={} atlas={}x{}", path, ptSize, atlasW, atlasH);
return true;
Expand All @@ -84,16 +83,11 @@ namespace Chained
}

m_Font = ftgl::texture_font_new_from_memory(m_Atlas, ptSize, data, dataSize);
if (!m_Font)
if (!SetupFont(m_Font))
{
CH_CORE_ERROR("FreeTypeGLAtlas: texture_font_new_from_memory failed");
return false;
}
m_Font->hinting = 1;
m_Font->kerning = 1;

PreloadRange(32, 96);
PreloadRange(0x0400, 256);

CH_CORE_INFO("FreeTypeGLAtlas: loaded from memory pt={} atlas={}x{}", ptSize, atlasW, atlasH);
return true;
Expand All @@ -115,73 +109,46 @@ namespace Chained
m_Glyphs.clear();
}

// ── glyph access ─────────────────────────────────────────────────────────
const AtlasGlyphMetrics* FreeTypeGLAtlas::GetGlyph(uint32_t codepoint)
{
auto it = m_Glyphs.find(codepoint);
return (it != m_Glyphs.end()) ? &it->second : CacheGlyph(codepoint);
}

const AtlasGlyphMetrics* FreeTypeGLAtlas::CacheGlyph(uint32_t codepoint)
{
if (!m_Font)
{
return nullptr;
}
auto it = m_Glyphs.find(codepoint);
if (it != m_Glyphs.end())
{
return &it->second;
}
CacheGlyph(codepoint);
auto it2 = m_Glyphs.find(codepoint);
return (it2 != m_Glyphs.end()) ? &it2->second : nullptr;
}

void FreeTypeGLAtlas::CacheGlyph(uint32_t codepoint)
{
std::string utf8 = CodepointToUTF8(codepoint);
// texture_font_get_glyph renders + packs if not already present
ftgl::texture_glyph_t* g = ftgl::texture_font_get_glyph(m_Font, utf8.c_str());
if (!g)
{
return;
return nullptr;
}
AtlasGlyphMetrics m;
m.codepoint = codepoint;
m.width = static_cast<uint32_t>(g->width);
m.height = static_cast<uint32_t>(g->height);
m.offsetX = g->offset_x;
m.offsetY = g->offset_y;
m.advanceX = g->advance_x;
m.s0 = g->s0;
m.t0 = g->t0;
m.s1 = g->s1;
m.t1 = g->t1;
m_Glyphs[codepoint] = m;

AtlasGlyphMetrics m{codepoint,
static_cast<uint32_t>(g->width),
static_cast<uint32_t>(g->height),
g->offset_x,
g->offset_y,
g->advance_x,
g->s0,
g->t0,
g->s1,
g->t1};

auto [it, inserted] = m_Glyphs.insert_or_assign(codepoint, m);
return &it->second;
}

void FreeTypeGLAtlas::PreloadRange(uint32_t first, uint32_t count)
{
if (!m_Font)
{
return;
}
for (uint32_t i = 0; i < count; ++i)
{
uint32_t cp = first + i;
std::string utf8 = CodepointToUTF8(cp);
ftgl::texture_glyph_t* g = ftgl::texture_font_get_glyph(m_Font, utf8.c_str());
if (!g)
{
continue;
}
AtlasGlyphMetrics m;
m.codepoint = cp;
m.width = static_cast<uint32_t>(g->width);
m.height = static_cast<uint32_t>(g->height);
m.offsetX = g->offset_x;
m.offsetY = g->offset_y;
m.advanceX = g->advance_x;
m.s0 = g->s0;
m.t0 = g->t0;
m.s1 = g->s1;
m.t1 = g->t1;
m_Glyphs[cp] = m;
CacheGlyph(first + i);
}
}

Expand Down
4 changes: 3 additions & 1 deletion engine/graphics/freetype_gl_atlas.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ namespace Chained
}

private:
void CacheGlyph(uint32_t codepoint);
const AtlasGlyphMetrics* CacheGlyph(uint32_t codepoint);
bool SetupFont(ftgl::texture_font_t* font);
std::string CodepointToUTF8(uint32_t codepoint) const;

ftgl::texture_atlas_t* m_Atlas = nullptr;
ftgl::texture_font_t* m_Font = nullptr;
Expand Down
Loading