From a73df1b4f34b3a41987ea0117bdc57340915f393 Mon Sep 17 00:00:00 2001 From: ohyzha Date: Wed, 22 Jan 2025 17:08:14 +0200 Subject: [PATCH] text with smallest possible spacing between glyphs --- examples/ExampleApps/TextExampleApp.cpp | 24 ++++++++++++------------ openVulkanoCpp/Scene/TextDrawable.cpp | 19 ++++++++++++++----- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/examples/ExampleApps/TextExampleApp.cpp b/examples/ExampleApps/TextExampleApp.cpp index e286b87..0e76db8 100644 --- a/examples/ExampleApps/TextExampleApp.cpp +++ b/examples/ExampleApps/TextExampleApp.cpp @@ -34,7 +34,7 @@ namespace OpenVulkano namespace fs = std::filesystem; constexpr int CREATE_BITMAP_ATLAS = 0; - constexpr int CREATE_NEW_ATLAS = 0; + //#define CREATE_NEW_ATLAS class TextExampleAppImpl final : public TextExampleApp { @@ -53,6 +53,8 @@ namespace OpenVulkano texts.push_back(std::make_pair("Hello, World!", TextConfig())); texts.push_back(std::make_pair("\u0410\u0411\u0412\u041F", TextConfig())); texts.push_back(std::make_pair("Unsupported glyphs \u1E30\u1E31 are coming", TextConfig())); + texts.push_back(std::make_pair("AAAA, ____", TextConfig())); + texts.push_back(std::make_pair("0123456789", TextConfig())); texts.push_back(std::make_pair("This is first line\nSecond gg line\nThird G line", TextConfig())); texts[1].second.backgroundColor.a = 255; @@ -72,12 +74,12 @@ namespace OpenVulkano generator.GetAtlas()->Save("bitmap_atlas_packed.png"); } -#if defined(MSDFGEN_AVAILABLE) && CREATE_NEW_ATLAS - std::set s = SdfFontAtlasGenerator::LoadAllGlyphs(fontPath); - m_atlasGenerator.GenerateAtlas(fontPath, s); - m_msdfAtlasGenerator.GenerateAtlas(fontPath, s); - m_atlasGenerator.GetAtlas()->Save("sdf_atlas_packed.png"); - m_msdfAtlasGenerator.GetAtlas()->Save("msdf_atlas_packed.png"); +#if defined(MSDFGEN_AVAILABLE) && defined(CREATE_NEW_ATLAS) + std::set s = SdfFontAtlasGenerator::LoadAllGlyphs(fontPath); + m_atlasGenerator.GenerateAtlas(fontPath, s); + m_msdfAtlasGenerator.GenerateAtlas(fontPath, s); + m_atlasGenerator.GetAtlas()->Save("sdf_atlas_packed.png"); + m_msdfAtlasGenerator.GetAtlas()->Save("msdf_atlas_packed.png"); #else auto sdfMetadataInfo = resourceLoader.GetResource("sdf_atlas_packed.png"); auto msdfMetadataInfo = resourceLoader.GetResource("msdf_atlas_packed.png"); @@ -90,16 +92,14 @@ namespace OpenVulkano for (int j = 0; j < texts.size(); j++) { TextDrawable* t = nullptr; -#if defined(MSDFGEN_AVAILABLE) && CREATE_NEW_ATLAS +#if defined(MSDFGEN_AVAILABLE) && defined(CREATE_NEW_ATLAS) if (i < texts.size()) { - t = new TextDrawable(m_atlasGenerator.GetAtlasData(), texts[j].second); - t->SetShader(&TextDrawable::GetSdfDefaultShader()); + t = new TextDrawable(m_atlasGenerator.GetAtlas(), texts[j].second); } else { - t = new TextDrawable(m_msdfAtlasGenerator.GetAtlasData(), texts[j].second); - t->SetShader(&TextDrawable::GetMsdfDefaultShader()); + t = new TextDrawable(m_msdfAtlasGenerator.GetAtlas(), texts[j].second); } #else if (i == 0) diff --git a/openVulkanoCpp/Scene/TextDrawable.cpp b/openVulkanoCpp/Scene/TextDrawable.cpp index ae5e2c1..a140294 100644 --- a/openVulkanoCpp/Scene/TextDrawable.cpp +++ b/openVulkanoCpp/Scene/TextDrawable.cpp @@ -96,12 +96,14 @@ namespace OpenVulkano::Scene const double lineHeight = m_atlasData->GetLineHeight(); double posY = pos.y; Math::Vector2f bmin(pos), bmax(pos); + float prevGlyphXBound = -INFINITY; for (auto begin = text.begin(), end = text.end(); begin != end;) { uint32_t c = utf8::next(begin, end); if (c == '\n') { posY -= lineHeight; + prevGlyphXBound = -INFINITY; cursorX = pos.x; continue; } @@ -115,19 +117,26 @@ namespace OpenVulkano::Scene const GlyphInfo& info = symbols.at(c); + float offset = 0; + const bool isZeroLenGlyph = info.pos[1].x == 0; + const bool isBitmap = m_atlasData->GetAtlasType().IsBitmap(); + if (prevGlyphXBound != -INFINITY && !isZeroLenGlyph && !isBitmap) + { + offset = prevGlyphXBound - (info.pos[0].x + cursorX); + } + for (int i = 0; i < 4; i++) { - vertices->position[i].x = info.pos[i].x + cursorX; + vertices->position[i].x = info.pos[i].x + cursorX + offset; vertices->uv[i] = info.uv[i]; if (i < 2) vertices->position[i].y = posY - info.pos[i].y; else vertices->position[i].y = posY + info.pos[i].y; vertices->color = m_cfg.textColor; vertices->background = m_cfg.backgroundColor; } - - // TODO: change to lower value(or ideally remove completely) to avoid overlapping and make less space between symbols - // when setting for depth comparison operator will be available( <= ) - cursorX += info.advance + 0.08; + // slight offset for bitmap atlas since it's tightly packed without any extra padding, while sdf has additional padding + cursorX += info.advance + (isBitmap ? 0.05 : 0); + prevGlyphXBound = isZeroLenGlyph ? cursorX : vertices->position[2].x; if (!m_symbolCount) bmin.x = vertices->position[0].x; bmax.x = std::max(bmax.x, vertices->position[1].x);