From 94d4aa935683dc38d22a5da6b28b4af6a879bebb Mon Sep 17 00:00:00 2001 From: Thraix Date: Wed, 10 May 2023 22:53:34 +0200 Subject: [PATCH] Add Font BoundingBox calculation --- CopiumEngine/CopiumEngine.vcxproj | 2 + CopiumEngine/CopiumEngine.vcxproj.filters | 6 +++ CopiumEngine/assets/font.meta | 2 +- CopiumEngine/src/copium/core/Application.cpp | 5 ++- CopiumEngine/src/copium/renderer/Renderer.cpp | 8 ++-- CopiumEngine/src/copium/sampler/Font.cpp | 42 +++++++++++++++++-- CopiumEngine/src/copium/sampler/Font.h | 7 ++-- CopiumEngine/src/copium/sampler/Glyph.h | 8 ++-- CopiumEngine/src/copium/util/BoundingBox.cpp | 25 +++++++++++ CopiumEngine/src/copium/util/BoundingBox.h | 22 ++++++++++ 10 files changed, 108 insertions(+), 19 deletions(-) create mode 100644 CopiumEngine/src/copium/util/BoundingBox.cpp create mode 100644 CopiumEngine/src/copium/util/BoundingBox.h diff --git a/CopiumEngine/CopiumEngine.vcxproj b/CopiumEngine/CopiumEngine.vcxproj index f725376..47cb8f3 100644 --- a/CopiumEngine/CopiumEngine.vcxproj +++ b/CopiumEngine/CopiumEngine.vcxproj @@ -201,6 +201,7 @@ + @@ -260,6 +261,7 @@ + diff --git a/CopiumEngine/CopiumEngine.vcxproj.filters b/CopiumEngine/CopiumEngine.vcxproj.filters index 6b89672..8dbac8d 100644 --- a/CopiumEngine/CopiumEngine.vcxproj.filters +++ b/CopiumEngine/CopiumEngine.vcxproj.filters @@ -183,6 +183,9 @@ Source Files + + Source Files + @@ -374,5 +377,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/CopiumEngine/assets/font.meta b/CopiumEngine/assets/font.meta index 19a9ef5..46c800e 100644 --- a/CopiumEngine/assets/font.meta +++ b/CopiumEngine/assets/font.meta @@ -1,3 +1,3 @@ [Font] -filepath=res/fonts/Roboto-Thin.ttf +filepath=res/fonts/Roboto-Regular.ttf uuid=3e9ef1a2-59ba-2e4d-b2cd-f5efaa531af7 \ No newline at end of file diff --git a/CopiumEngine/src/copium/core/Application.cpp b/CopiumEngine/src/copium/core/Application.cpp index 6826c64..8af67c0 100644 --- a/CopiumEngine/src/copium/core/Application.cpp +++ b/CopiumEngine/src/copium/core/Application.cpp @@ -223,7 +223,10 @@ namespace Copium renderer->Quad(glm::vec2{ 0.1, -0.4}, glm::vec2{0.8, 0.8}, AssetManager::GetAsset(font)); renderer->Quad(mousePos - glm::vec2(0.1), glm::vec2{0.2}, AssetManager::GetAsset(texture2D2)); std::string s = std::to_string(fps) + " fps"; - renderer->Text(s, glm::vec2{-aspect + 0.01, 0.94}, AssetManager::GetAsset(font), 0.06, glm::vec3{0.3, 0.2, 0.8}); + BoundingBox boundingBox = AssetManager::GetAsset(font).GetTextBoundingBox(s, 0.06); + glm::vec2 pos = glm::vec2{-aspect + 0.01, 0.94}; + renderer->Quad(pos + boundingBox.lb, boundingBox.GetSize()); + renderer->Text(s, pos, AssetManager::GetAsset(font), 0.06, glm::vec3{0.0f}); renderer->End(); fb.Unbind(*commandBuffer); diff --git a/CopiumEngine/src/copium/renderer/Renderer.cpp b/CopiumEngine/src/copium/renderer/Renderer.cpp index 132b292..9f81e52 100644 --- a/CopiumEngine/src/copium/renderer/Renderer.cpp +++ b/CopiumEngine/src/copium/renderer/Renderer.cpp @@ -74,10 +74,10 @@ namespace Copium const Glyph& glyph = font.GetGlyph(c); AllocateQuad(); int texIndex = AllocateSampler(font); - AddVertex(offset + glm::vec2{glyph.pos1.x * size, glyph.pos1.y * size}, color, texIndex, glyph.texCoord1, RendererVertex::TYPE_TEXT); - AddVertex(offset + glm::vec2{glyph.pos2.x * size, glyph.pos1.y * size}, color, texIndex, glm::vec2{glyph.texCoord2.x, glyph.texCoord1.y}, RendererVertex::TYPE_TEXT); - AddVertex(offset + glm::vec2{glyph.pos2.x * size, glyph.pos2.y * size}, color, texIndex, glyph.texCoord2, RendererVertex::TYPE_TEXT); - AddVertex(offset + glm::vec2{glyph.pos1.x * size, glyph.pos2.y * size}, color, texIndex, glm::vec2{glyph.texCoord1.x, glyph.texCoord2.y}, RendererVertex::TYPE_TEXT); + AddVertex(offset + glm::vec2{glyph.boundingBox.l * size, glyph.boundingBox.b * size}, color, texIndex, glyph.texCoordBoundingBox.lb, RendererVertex::TYPE_TEXT); + AddVertex(offset + glm::vec2{glyph.boundingBox.r * size, glyph.boundingBox.b * size}, color, texIndex, glm::vec2{glyph.texCoordBoundingBox.r, glyph.texCoordBoundingBox.b}, RendererVertex::TYPE_TEXT); + AddVertex(offset + glm::vec2{glyph.boundingBox.r * size, glyph.boundingBox.t * size}, color, texIndex, glyph.texCoordBoundingBox.rt, RendererVertex::TYPE_TEXT); + AddVertex(offset + glm::vec2{glyph.boundingBox.l * size, glyph.boundingBox.t * size}, color, texIndex, glm::vec2{glyph.texCoordBoundingBox.l, glyph.texCoordBoundingBox.t}, RendererVertex::TYPE_TEXT); offset.x += glyph.advance * size; } return offset; diff --git a/CopiumEngine/src/copium/sampler/Font.cpp b/CopiumEngine/src/copium/sampler/Font.cpp index e53b9fa..e8aff92 100644 --- a/CopiumEngine/src/copium/sampler/Font.cpp +++ b/CopiumEngine/src/copium/sampler/Font.cpp @@ -60,11 +60,9 @@ namespace Copium glyph.advance = glyphGeom.getAdvance(); double l, b, r, t; glyphGeom.getQuadPlaneBounds(l, b, r, t); - glyph.pos1 = glm::vec2{l, b}; - glyph.pos2 = glm::vec2{r, t}; + glyph.boundingBox = BoundingBox{(float)l, (float)b, (float)r, (float)t}; glyphGeom.getQuadAtlasBounds(l, b, r, t); - glyph.texCoord1 = glm::vec2{l / width, b / height}; - glyph.texCoord2 = glm::vec2{r / width, t / height}; + glyph.texCoordBoundingBox = BoundingBox{(float)l / width, (float)b / height, (float)r / width, (float)t / height}; this->glyphs.emplace((char)glyphGeom.getCodepoint(), glyph); } lineHeight = fontGeometry.getMetrics().lineHeight; @@ -101,6 +99,42 @@ namespace Copium return lineHeight; } + BoundingBox Font::GetTextBoundingBox(const std::string& str, float size) const + { + BoundingBox boundingBox{0.0f}; + glm::vec2 offset{0.0f}; + for (auto c : str) + { + if(c == ' ') + { + const Glyph& glyph = GetGlyph(c); + offset.x += glyph.advance; + continue; + } + else if (c == '\t') + { + const Glyph& glyph = GetGlyph(' '); + offset.x += glyph.advance * 4; + continue; + } + else if (c == '\n') + { + boundingBox.r = std::max(boundingBox.r, offset.x); + offset.y -= GetLineHeight(); + offset.x = 0.0f; + continue; + } + const Glyph& glyph = GetGlyph(c); + boundingBox.l = std::min(boundingBox.l, offset.x + glyph.boundingBox.l); + boundingBox.t = std::max(boundingBox.t, offset.y + glyph.boundingBox.t); + offset.x += glyph.advance; + boundingBox.b = std::min(boundingBox.b, offset.y + glyph.boundingBox.b); + } + boundingBox.r = std::max(boundingBox.r, offset.x); + boundingBox.lbrt *= size; + return boundingBox; + } + void Font::InitializeTextureImageFromData(const uint8_t* rgbaData, int width, int height) { VkDeviceSize bufferSize = width * height * 4; diff --git a/CopiumEngine/src/copium/sampler/Font.h b/CopiumEngine/src/copium/sampler/Font.h index e129d9b..7242495 100644 --- a/CopiumEngine/src/copium/sampler/Font.h +++ b/CopiumEngine/src/copium/sampler/Font.h @@ -2,16 +2,13 @@ #include "copium/sampler/Sampler.h" #include "copium/sampler/Glyph.h" +#include "copium/util/BoundingBox.h" namespace Copium { class Font : public Sampler { CP_DELETE_COPY_AND_MOVE_CTOR(Font); - struct GlyphData - { - - }; private: VkImage image; VkDeviceMemory imageMemory; @@ -27,6 +24,8 @@ namespace Copium const Glyph& GetGlyph(char c) const; float GetLineHeight() const; + + BoundingBox GetTextBoundingBox(const std::string& str, float size) const; private: void InitializeTextureImageFromFile(const std::string& filename); void InitializeTextureImageFromData(const uint8_t* rgbaData, int width, int height); diff --git a/CopiumEngine/src/copium/sampler/Glyph.h b/CopiumEngine/src/copium/sampler/Glyph.h index 16db301..476725f 100644 --- a/CopiumEngine/src/copium/sampler/Glyph.h +++ b/CopiumEngine/src/copium/sampler/Glyph.h @@ -1,15 +1,13 @@ #pragma once -#include +#include "copium/util/BoundingBox.h" namespace Copium { struct Glyph { float advance; - glm::vec2 pos1; - glm::vec2 pos2; - glm::vec2 texCoord1; - glm::vec2 texCoord2; + BoundingBox boundingBox; + BoundingBox texCoordBoundingBox; }; } diff --git a/CopiumEngine/src/copium/util/BoundingBox.cpp b/CopiumEngine/src/copium/util/BoundingBox.cpp new file mode 100644 index 0000000..dc93782 --- /dev/null +++ b/CopiumEngine/src/copium/util/BoundingBox.cpp @@ -0,0 +1,25 @@ +#include "copium/util/BoundingBox.h" + +namespace Copium +{ + BoundingBox::BoundingBox() + : l{0.0f}, b{0.0f}, r{0.0f}, t{0.0f} + {} + + BoundingBox::BoundingBox(float all) + : l{all}, b{all}, r{all}, t{all} + {} + + BoundingBox::BoundingBox(float l, float b, float r, float t) + : l{l}, b{b}, r{r}, t{t} + {} + + BoundingBox::BoundingBox(glm::vec2 lb, glm::vec2 rt) + : lb{lb}, rt{rt} + {} + + glm::vec2 BoundingBox::GetSize() const + { + return rt - lb; + } +} diff --git a/CopiumEngine/src/copium/util/BoundingBox.h b/CopiumEngine/src/copium/util/BoundingBox.h new file mode 100644 index 0000000..0989b63 --- /dev/null +++ b/CopiumEngine/src/copium/util/BoundingBox.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +namespace Copium +{ + struct BoundingBox + { + union + { + struct { float l; float b; float r; float t; }; + struct { glm::vec2 lb; glm::vec2 rt; }; + struct { glm::vec4 lbrt; }; + }; + BoundingBox(); + BoundingBox(float all); + BoundingBox(float l, float b, float r, float t); + BoundingBox(glm::vec2 lb, glm::vec2 rt); + + glm::vec2 GetSize() const; + }; +}