#pragma once #include #include #include #include #include FT_FREETYPE_H #include #include namespace ADVect::Graphics { bool Init(u16 width, u16 height); void Shutdown(); enum MarkupStyle { TEXT_NONE = 0, TEXT_BOLD = 1 << 0, TEXT_ITALIC = 1 << 1, TEXT_UNDERLINE = 1 << 2, TEXT_STRIKETHROUGH = 1 << 3, TEXT_OVERLINE = 1 << 4 }; struct ImageTexture { i32 w, h, channels; u8* buffer; bgfx::TextureHandle tx; }; ImageTexture* GetImageTextureFromFile(const std::string& file); struct Font { FT_Face face = nullptr; std::unordered_map, u32, u32, i32, i32, i32, i32>> cache{}; std::tuple, u32, u32, i32, i32, i32, i32>& get_char(NVL::Char c); }; void DrawTexture(const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h, u64 state, const bgfx::ProgramHandle& pg); void DrawTextureImage(const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h); void DrawTextureImage(const ImageTexture& img, i32 pos_x, i32 pos_y); void DrawTextureImageAlpha(const ImageTexture& img, i32 pos_x, i32 pos_y, f32 alpha); void DrawTextureStencilAlpha(const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h); Font* ResolveStyleFlags(u32 style_flags); template void RenderGlyph(NVL::Char c, std::conditional_t pos_x, std::conditional_t pos_y, u32 col, u32 style_flags) { Font* f = ResolveStyleFlags(style_flags); auto& [tx, w, h, l, t, x, y] = f->get_char(c); pos_x += l; if (auto& buf = tx; DoRender && tx && w != 0) { DrawTextureStencilAlpha(*buf, pos_x, pos_y - (h - t), w, h); } pos_x += x >> 6; pos_y += y >> 6; } template void RenderString(const NVL::String& s, std::conditional_t pos_x, std::conditional_t pos_y, u32 col, u32 style_flags) { for (const auto& c : s) { RenderGlyph(c, pos_x, pos_y, col, style_flags); } } template void RenderString(NVL::String::const_iterator cbegin, NVL::String::const_iterator cend, std::conditional_t pos_x, std::conditional_t pos_y, u32 col, u32 style_flags) { while (cbegin < cend) { RenderGlyph(*cbegin++, pos_x, pos_y, col, style_flags); } } i32 RenderSubstringBox(const NVL::String& s, i32& pos_x, i32& pos_y, i32 reset_x, u32 w, u32 col, u32 style_flags = TEXT_NONE, size_t s_end = NVL::String::npos); void RenderSubstringMarkupBox(const NVL::Environment::MarkupString& ms, i32 pos_x, i32 pos_y, u32 w, u32 col, size_t end = NVL::String::npos); }