diff --git a/.mailmap b/.mailmap new file mode 100644 index 000000000..f55af15cd --- /dev/null +++ b/.mailmap @@ -0,0 +1,7 @@ +IOleg <124497826+IOleg-crypto@users.noreply.github.com> +IOleg <124497826+IOleg-crypto@users.noreply.github.com> +IOleg <124497826+IOleg-crypto@users.noreply.github.com> unknown +IOleg <124497826+IOleg-crypto@users.noreply.github.com> unknown +IOleg <124497826+IOleg-crypto@users.noreply.github.com> IOleg-sus +IOleg <124497826+IOleg-crypto@users.noreply.github.com> IOleg +IOleg <124497826+IOleg-crypto@users.noreply.github.com> I Oleg diff --git a/engine/graphics/freetype_gl_atlas.cpp b/engine/graphics/freetype_gl_atlas.cpp index a6fd473f9..682456e65 100644 --- a/engine/graphics/freetype_gl_atlas.cpp +++ b/engine/graphics/freetype_gl_atlas.cpp @@ -7,36 +7,41 @@ 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(cp); + return std::string(1, static_cast(cp)); } - else if (cp < 0x800) - { - s += static_cast(0xC0 | (cp >> 6)); - s += static_cast(0x80 | (cp & 0x3F)); - } - else if (cp < 0x10000) + + if (cp < 0x800) { - s += static_cast(0xE0 | (cp >> 12)); - s += static_cast(0x80 | ((cp >> 6) & 0x3F)); - s += static_cast(0x80 | (cp & 0x3F)); + char bytes[3] = {static_cast(0xC0 | (cp >> 6)), static_cast(0x80 | (cp & 0x3F)), '\0'}; + return std::string(bytes); } - else + + char bytes[4] = {static_cast(0xE0 | (cp >> 12)), static_cast(0x80 | ((cp >> 6) & 0x3F)), + static_cast(0x80 | (cp & 0x3F)), '\0'}; + return std::string(bytes); + } + + bool FreeTypeGLAtlas::SetupFont(ftgl::texture_font_t* font) + { + if (!font) { - s += static_cast(0xF0 | (cp >> 18)); - s += static_cast(0x80 | ((cp >> 12) & 0x3F)); - s += static_cast(0x80 | ((cp >> 6) & 0x3F)); - s += static_cast(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(); @@ -44,7 +49,7 @@ namespace Chained 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); @@ -52,17 +57,11 @@ namespace Chained } 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; @@ -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; @@ -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(g->width); - m.height = static_cast(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(g->width), + static_cast(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(g->width); - m.height = static_cast(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); } } diff --git a/engine/graphics/freetype_gl_atlas.h b/engine/graphics/freetype_gl_atlas.h index 48a824489..690aa7a70 100644 --- a/engine/graphics/freetype_gl_atlas.h +++ b/engine/graphics/freetype_gl_atlas.h @@ -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;