Refactor FontAtlas class

This commit is contained in:
Georg Hagen
2025-01-11 01:25:52 +01:00
parent 6a3c31346f
commit 9cb3d4de85
14 changed files with 246 additions and 247 deletions

View File

@@ -5,14 +5,9 @@
*/
#include "FontAtlasGeneratorBase.hpp"
#include "Text/FontAtlas.hpp"
#include "Base/Logger.hpp"
#include "Extensions/STBZlibCompressor.hpp"
#include <filesystem>
#include <fstream>
#define STBI_MSC_SECURE_CRT
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define STBIW_ZLIB_COMPRESS Extensions::STBZlibCompressor
#include <stb_image_write.h>
namespace OpenVulkano::Scene
{
@@ -61,74 +56,10 @@ namespace OpenVulkano::Scene
return fmt::format("Error code is {}", error);
}
void FontAtlasGeneratorBase::SaveAtlasMetadataInfo(const std::string& outputFile, bool packIntoSingleFile) const
{
if (m_atlasData->glyphs.empty())
{
Logger::DATA->info("No glyphs loaded. Nothing to save.");
return;
}
std::string fileName = outputFile;
uint32_t packedFlag = packIntoSingleFile;
if (packIntoSingleFile)
{
std::filesystem::path fPath(fileName);
fileName = (fPath.parent_path() / fPath.stem()).string() + "_packed.png";
SavePng(fileName);
}
std::fstream fs(fileName.c_str(), std::ios_base::out | std::ios_base::binary | (packedFlag ? std::ios_base::app : std::ios_base::trunc));
fs.write(reinterpret_cast<const char*>(&m_atlasData->meta), sizeof(AtlasMetadata));
uint64_t metadataBytes = sizeof(AtlasMetadata);
for (const auto& [key, val] : m_atlasData->glyphs)
{
fs.write(reinterpret_cast<const char*>(&key), sizeof(uint32_t));
fs.write(reinterpret_cast<const char*>(&val.pos), sizeof(GlyphInfo::pos));
fs.write(reinterpret_cast<const char*>(&val.pos), sizeof(GlyphInfo::pos)); // TODO remove this after cleaning up the atlas writing code
fs.write(reinterpret_cast<const char*>(&val.uv), sizeof(GlyphInfo::uv));
fs.write(reinterpret_cast<const char*>(&val.advance), sizeof(GlyphInfo::advance));
fs.write(reinterpret_cast<const char*>(&val.advance), sizeof(GlyphInfo::advance)); // TODO remove this afer cleaning up the atlas writing code
metadataBytes += sizeof(uint32_t);
metadataBytes += sizeof(GlyphInfo);
}
fs.write(reinterpret_cast<const char*>(&metadataBytes), sizeof(uint64_t));
fs.write(reinterpret_cast<const char*>(&packedFlag), sizeof(uint32_t));
fs.close();
}
void FontAtlasGeneratorBase::SavePng(std::string output) const
{
stbi_flip_vertically_on_write(1);
if (std::filesystem::path(output).extension() != ".png")
{
output += ".png";
}
stbi_write_png(output.c_str(), m_atlasData->img->resolution.x, m_atlasData->img->resolution.y, m_channelsCount,
m_atlasData->img->data.Data(), m_channelsCount * m_atlasData->img->resolution.x);
}
void FontAtlasGeneratorBase::SetupAtlasData(Math::Vector2ui textureResolution, double lineHeight,
FontAtlasType::Type atlasType)
{
// generate texture
m_atlasData->img = std::make_unique<Image::Image>();
m_atlasData->img->resolution = Math::Vector3ui(textureResolution, 1);
m_atlasData->img->dataFormat = m_channelsCount == 1 ? DataFormat::R8_UNORM : DataFormat::R8G8B8A8_UNORM;
m_atlasData->img->data = Array<uint8_t>(m_atlasData->img->dataFormat.CalculatedSize(textureResolution.x, textureResolution.y));
m_atlasData->texture.resolution = m_atlasData->img->resolution;
m_atlasData->texture.textureBuffer = m_atlasData->img->data.Data();
m_atlasData->texture.format = m_atlasData->img->dataFormat;
m_atlasData->texture.size = m_atlasData->img->data.Size();
m_atlasData->meta.atlasType = atlasType;
m_atlasData->meta.lineHeight = lineHeight;
if (atlasType == FontAtlasType::BITMAP)
{
m_atlasData->texture.m_samplerConfig = &SamplerConfig::NEAREST;
}
}
void FontAtlasGeneratorBase::SetGlyphData(GlyphInfo& info, Math::Vector2d bearing, Math::Vector2d size,
const Math::AABB& aabb, double advance)
{
const auto& resolution = m_atlasData->GetTexture()->resolution;
const double l = aabb.min.x;
const double r = aabb.max.x;
const double t = aabb.max.y;
@@ -136,23 +67,23 @@ namespace OpenVulkano::Scene
info.pos[0].x = bearing.x;
info.pos[0].y = size.y - bearing.y;
info.uv[0].x = l / m_atlasData->texture.resolution.x;
info.uv[0].y = b / m_atlasData->texture.resolution.y;
info.uv[0].x = l / resolution.x;
info.uv[0].y = b / resolution.y;
info.pos[1].x = bearing.x + size.x;
info.pos[1].y = size.y - bearing.y;
info.uv[1].x = r / m_atlasData->texture.resolution.x;
info.uv[1].y = b / m_atlasData->texture.resolution.y;
info.uv[1].x = r / resolution.x;
info.uv[1].y = b / resolution.y;
info.pos[2].x = bearing.x + size.x;
info.pos[2].y = bearing.y;
info.uv[2].x = r / m_atlasData->texture.resolution.x;
info.uv[2].y = t / m_atlasData->texture.resolution.y;
info.uv[2].x = r / resolution.x;
info.uv[2].y = t / resolution.y;
info.pos[3].x = bearing.x;
info.pos[3].y = bearing.y;
info.uv[3].x = l / m_atlasData->texture.resolution.x;
info.uv[3].y = t / m_atlasData->texture.resolution.y;
info.uv[3].x = l / resolution.x;
info.uv[3].y = t / resolution.y;
info.advance = advance;
}