97 lines
3.2 KiB
C++
97 lines
3.2 KiB
C++
// IAEngine: 2D Game Engine by IA
|
|
// Copyright (C) 2025 IASoft (PVT) LTD (oss@iasoft.dev)
|
|
//
|
|
// 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 <https://www.gnu.org/licenses/>.
|
|
|
|
#include <FontManager.hpp>
|
|
|
|
#include <Renderer/GPUResourceManager.hpp>
|
|
|
|
#include <ft2build.h>
|
|
#include FT_FREETYPE_H
|
|
|
|
namespace ia::iae
|
|
{
|
|
Map<String, FontManager::Font> FontManager::s_fonts;
|
|
|
|
FT_Library g_freetype;
|
|
|
|
VOID FontManager::Initialize()
|
|
{
|
|
if (FT_Init_FreeType(&g_freetype))
|
|
THROW_UNKNOWN("Failed to initialize the FreeType font library");
|
|
|
|
//LoadFont("Roboto", "Resources/Fonts/Roboto-Black.ttf");
|
|
}
|
|
|
|
VOID FontManager::Terminate()
|
|
{
|
|
for(const auto& f: s_fonts)
|
|
{
|
|
for(const auto& t: f->Value.Chars)
|
|
GPUResourceManager::DestroyTexture(t.Texture);
|
|
}
|
|
|
|
FT_Done_FreeType(g_freetype);
|
|
}
|
|
|
|
VOID FontManager::LoadFont(IN CONST String &name, IN CONST String &path)
|
|
{
|
|
STATIC Vector<UINT8> GLYPH_PIXEL_DATA;
|
|
|
|
Font result;
|
|
|
|
const auto fontSize = 16;
|
|
|
|
FT_Face face;
|
|
if (FT_New_Face(g_freetype, path.c_str(), 0, &face))
|
|
THROW_UNKNOWN("Failed to load the TrueType font '", path, "'");
|
|
|
|
FT_Set_Pixel_Sizes(face, 0, fontSize);
|
|
|
|
const auto charCount = static_cast<UINT8>(sizeof(result.Chars) / sizeof(result.Chars[0]));
|
|
for (UINT8 c = 0; c < charCount; c++)
|
|
{
|
|
if (FT_Load_Char(face, c, FT_LOAD_RENDER))
|
|
THROW_UNKNOWN("Failed to load character '", (CHAR) c, "' of TrueType font '", path, "'");
|
|
|
|
const auto glyphSize = face->glyph->bitmap.pitch * face->glyph->bitmap.rows;
|
|
if(!glyphSize) continue;
|
|
|
|
GLYPH_PIXEL_DATA.clear();
|
|
GLYPH_PIXEL_DATA.resize(glyphSize << 2);
|
|
|
|
for(SIZE_T t = 0; t < glyphSize; t++)
|
|
{
|
|
const auto pi= t<<2;
|
|
const auto p = face->glyph->bitmap.buffer[t];
|
|
GLYPH_PIXEL_DATA[pi + 0] = p;
|
|
GLYPH_PIXEL_DATA[pi + 1] = p;
|
|
GLYPH_PIXEL_DATA[pi + 2] = p;
|
|
GLYPH_PIXEL_DATA[pi + 3] = p;
|
|
}
|
|
|
|
result.Chars[c] = {
|
|
IVec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
|
|
IVec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
|
|
static_cast<UINT32>(face->glyph->advance.x) >> 6,
|
|
GPUResourceManager::CreateTexture(SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET, face->glyph->bitmap.width, face->glyph->bitmap.rows, GLYPH_PIXEL_DATA.data()),
|
|
};
|
|
}
|
|
|
|
FT_Done_Face(face);
|
|
|
|
s_fonts[name] = IA_MOVE(result);
|
|
}
|
|
} // namespace ia::iae
|