#pragma once /* * Copyright (C) 2024 Brett Terpstra * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef BLT_WITH_GRAPHICS_FONT_RENDERER_H #define BLT_WITH_GRAPHICS_FONT_RENDERER_H #include #include #include #include #include #include namespace blt::gfx { class font_texture_atlas : public texture_gl2D { public: struct bounded_t { font::glyph_t glyph; // starting point blt::vec2ui min; // ending point of the glyph, inside texture atlas blt::vec2ui max; }; struct added_font_results_t { blt::u64 last_inserted_index; blt::u64 min_index_used; blt::u64 max_index_used; }; public: explicit font_texture_atlas(blt::i32 dimensions); added_font_results_t add_font(const font::font_file_t& file); added_font_results_t add_font(const font::font_file_t& file, blt::u64 start); bounded_t& get_glyph(blt::u64 c) { return glyphs.at(c); } [[nodiscard]] const bounded_t& get_glyph(blt::u64 c) const { return glyphs.at(c); } private: blt::hashmap_t glyphs; blt::u32 used_width = 0; blt::u32 used_height = 0; }; class font_generator_t { public: struct bounded_font_t { std::unique_ptr atlas; float min_size, max_size; blt::u64 min_char, max_char; bounded_font_t(std::unique_ptr atlas, float minSize, float maxSize, u64 minChar, u64 maxChar): atlas(std::move(atlas)), min_size(minSize), max_size(maxSize), min_char(minChar), max_char(maxChar) {} }; public: explicit font_generator_t(blt::i32 dimensions, const std::vector& sizes_to_generate); void add_font(const font::font_file_t& file); inline font_texture_atlas& get_texture(float size, blt::u64 c) { for (auto& atlas : atlases) { if (!(size >= atlas.min_size && size <= atlas.max_size)) continue; if (atlas.min_char > c && atlas.max_char < c) return *atlas.atlas; } throw std::runtime_error("Character not found inside atlases at this size"); } private: blt::i32 dimensions; std::vector atlases; std::vector sizes_to_generate; }; class font_renderer_t { public: struct compiled_text_t { std::shared_ptr vao; blt::size_t render_count; }; public: explicit font_renderer_t(); void create(const std::vector& generated_font_sizes, blt::i32 dimensions = 0); void cleanup(); void add_font(const font::font_file_t& file) { generator->add_font(file); } compiled_text_t create_text(std::string_view str); private: std::unique_ptr generator; std::unique_ptr font_shader; }; } #endif //BLT_WITH_GRAPHICS_FONT_RENDERER_H