implement text rendering without msdfgen library

This commit is contained in:
ohyzha
2024-08-05 18:25:19 +03:00
parent 62a0e84634
commit afccf5dee0
10 changed files with 302 additions and 150 deletions

View File

@@ -6,6 +6,8 @@
#include "FontAtlasGenerator.hpp"
#include "Base/Logger.hpp"
#include "Scene/AtlasMetadata.hpp"
#include <fstream>
namespace OpenVulkano::Scene
{
@@ -45,6 +47,21 @@ namespace OpenVulkano::Scene
Generate(ft, font, charset, pngOutput);
}
void FontAtlasGenerator::SaveAtlasMetadataInfo(const std::string& outputFile) const
{
if (m_symbols.empty())
{
Logger::DATA->info("No glyphs loaded. Nothing to save.");
return;
}
std::fstream fs(outputFile.c_str(), std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
for (const auto& [key, val] : m_symbols)
{
fs.write(reinterpret_cast<const char*>(&key), sizeof(uint32_t));
fs.write(reinterpret_cast<const char*>(&val), sizeof(GlyphInfo));
}
}
void FontAtlasGenerator::Generate(FreetypeHandle* ft, FontHandle* font, const Charset& chset,
const std::optional<std::string>& pngOutput)
{
@@ -75,12 +92,57 @@ namespace OpenVulkano::Scene
m_atlasTex.textureBuffer = (msdfgen::byte*) storage.pixels;
m_atlasTex.format = OpenVulkano::DataFormat::R8_UNORM;
m_atlasTex.size = storage.width * storage.height * 1; // 1 channel
struct Bbox
{
double l = 0, r = 0, t = 0, b = 0;
};
for (const auto& glyph: glyphsGeometry)
{
GlyphInfo& info = m_symbols[glyph.getCodepoint()];
info.geometry = glyph;
info.glyphBox = m_generator.getLayout()[idx++];
const GlyphBox& glyphBox = m_generator.getLayout()[idx++];
Bbox glyphBaselineBbox, glyphAtlasBbox;
glyph.getQuadPlaneBounds(glyphBaselineBbox.l, glyphBaselineBbox.b, glyphBaselineBbox.r,
glyphBaselineBbox.t);
glyph.getQuadAtlasBounds(glyphAtlasBbox.l, glyphAtlasBbox.b, glyphAtlasBbox.r, glyphAtlasBbox.t);
double bearingX = glyphBox.bounds.l;
double bearingY = glyphBox.bounds.t;
double w = glyphBaselineBbox.r - glyphBaselineBbox.l;
double h = glyphBaselineBbox.t - glyphBaselineBbox.b;
double l = glyphAtlasBbox.l;
double r = glyphAtlasBbox.r;
double t = glyphAtlasBbox.t;
double b = glyphAtlasBbox.b;
info.xyz[0].x = bearingX;
info.xyz[0].y = h - bearingY;
info.xyz[0].z = 1;
info.uv[0].x = l / m_atlasTex.resolution.x;
info.uv[0].y = b / m_atlasTex.resolution.y;
info.xyz[1].x = bearingX + w;
info.xyz[1].y = h - bearingY;
info.xyz[1].z = 1;
info.uv[1].x = r / m_atlasTex.resolution.x;
info.uv[1].y = b / m_atlasTex.resolution.y;
info.xyz[2].x = bearingX + w;
info.xyz[2].y = bearingY; //h - bearingY + h;
info.xyz[2].z = 1;
info.uv[2].x = r / m_atlasTex.resolution.x;
info.uv[2].y = t / m_atlasTex.resolution.y;
info.xyz[3].x = bearingX;
info.xyz[3].y = bearingY;
info.xyz[3].z = 1;
info.uv[3].x = l / m_atlasTex.resolution.x;
info.uv[3].y = t / m_atlasTex.resolution.y;
info.advance = glyphBox.advance;
}
if (pngOutput && !pngOutput->empty())
{
savePng(m_generator.atlasStorage(), pngOutput->c_str());