#pragma once #include #include #include #include #include #include "render/Renderer.h" #include "render/TextureManager.h" #include namespace ZL { struct GlyphInfo { Eigen::Vector2f uv; // u,v координата левого верхнего угла в атласе (0..1) Eigen::Vector2f uvSize; // ширина/высота в UV (0..1) Eigen::Vector2f size; // glyph size in pixels Eigen::Vector2f bearing; // offset from baseline unsigned int advance = 0; // advance.x in 1/64 pixels }; class TextRenderer { public: TextRenderer() = default; ~TextRenderer(); bool init(Renderer& renderer, const std::string& ttfPath, int pixelSize, const std::string& zipfilename); void drawText(const std::string& text, float x, float y, float scale, bool centered, std::array color = { 1.f,1.f,1.f,1.f }); float measureTextWidth(const std::string& text, float scale = 1.0f) const; float getLineHeight(float scale = 1.0f) const { return lineHeight * scale; } // Clear cached meshes (call on window resize / DPI change) void ClearCache(); private: bool loadGlyphs(const std::string& ttfPath, int pixelSize, const std::string& zipfilename); Renderer* r = nullptr; std::unordered_map glyphs; // единый атлас для всех глифов std::shared_ptr atlasTexture; size_t atlasWidth = 0; size_t atlasHeight = 0; float lineHeight = 32.0f; VertexRenderStruct textMesh; std::string shaderName = "text2d"; // caching for static texts struct CachedText { VertexRenderStruct mesh; float width = 0.f; // in pixels, total advance float height = 0.f; // optional, not currently used }; // key: text + "|" + scale + "|" + centered std::unordered_map cache; }; } // namespace ZL