From 0fe1509c6c4f29b51ee26c70ec6ad7209420c441 Mon Sep 17 00:00:00 2001 From: Simon Hardt Date: Sat, 5 Mar 2022 21:58:04 +0100 Subject: [PATCH] add: more font --- fontConverter/src/main.cpp | 66 +++++++++++++------------------ frame/src/Image.cpp | 8 ++++ frame/src/Image.hpp | 4 ++ frame/src/font/Font.cpp | 46 ++++++++++++++++++--- frame/src/font/Font.hpp | 13 +++++- frame/src/font/Glyph.hpp | 6 +-- frame/src/main.cpp | 22 ++++++++++- frame/src/render/RenderTarget.cpp | 27 ++++++++++++- frame/src/render/RenderTarget.hpp | 9 ++++- 9 files changed, 149 insertions(+), 52 deletions(-) diff --git a/fontConverter/src/main.cpp b/fontConverter/src/main.cpp index 431178f..60bec8c 100644 --- a/fontConverter/src/main.cpp +++ b/fontConverter/src/main.cpp @@ -7,6 +7,8 @@ using json = nlohmann::json; void PrintGlyph(sf::Font const& font, sf::Glyph const& g, unsigned int size); +void ExportSize(json& out, uint32_t size, sf::Font& font); + int main() { sf::Font font; @@ -16,46 +18,39 @@ int main() fmt::print("Loaded {}\n", ok); - std::vector chars = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', - 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', - 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; - fmt::print("{}\n", font.getInfo().family); fmt::print("Line Spacing: {}\n", font.getLineSpacing(14)); - std::map glyphs; - - for(auto el : chars) - { - auto a = font.getGlyph(el, 14, false); - - fmt::print("{}: w {} h {}\n", - el, - a.textureRect.width, - a.textureRect.height); - - fmt::print("- t: {} l: {} w: {} h: {}\n", - a.bounds.top, - a.bounds.left, - a.bounds.width, - a.bounds.height); - - fmt::print("offset: {}\n\n", a.advance); - - glyphs[el] = a; - } - - auto font_image = font.getTexture(14).copyToImage(); - auto size = font_image.getSize(); - json export_font; export_font["name"] = font.getInfo().family; export_font["sizes"] = json::object(); - auto& size_14 = export_font["sizes"]["14"]; + std::vector sizes = + {12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 100, 150, 200, 250, 300}; - size_14["LineSpacing"] = font.getLineSpacing(14); - auto& Glyphs = size_14["Glyphs"]; + for(auto& size : sizes) + { + fmt::print("Export: {}\n", size); + ExportSize(export_font["sizes"][fmt::format("{}", size)], size, font); + } + + std::fstream out(fmt::format("{}.json", font.getInfo().family), + std::ios::out); + out << export_font.dump(); +} + +void ExportSize(json& out, uint32_t size, sf::Font& font) +{ + std::map glyphs; + + for(uint8_t c = 32; c <= 126; ++c) + { + glyphs[(char)c] = font.getGlyph(c, size, false); + } + auto font_image = font.getTexture(size).copyToImage(); + + out["LineSpacing"] = font.getLineSpacing(size); + auto& Glyphs = out["Glyphs"]; for(auto&& [c, g] : glyphs) { @@ -82,13 +77,6 @@ int main() current["data"] = data; } - - std::fstream out(fmt::format("{}.json", font.getInfo().family), - std::ios::out); - out << export_font.dump(); - - fmt::print("Size x: {} y: {}\n", size.x, size.y); - font_image.saveToFile("Test.png"); } void PrintGlyph(sf::Font const& font, sf::Glyph const& g, unsigned int size) diff --git a/frame/src/Image.cpp b/frame/src/Image.cpp index c23376e..b2b3bbf 100644 --- a/frame/src/Image.cpp +++ b/frame/src/Image.cpp @@ -1,7 +1,10 @@ #include "Image.hpp" +#include "Color.hpp" + #include + namespace frame { @@ -36,6 +39,11 @@ namespace frame return mBuffer.at(toInternal(x, y)); } + void Image::Clear(Color color) + { + memset(mBuffer.data(), color, mBuffer.size()); + } + void Image::operator=(Image const& image) { mHeight = image.mHeight; diff --git a/frame/src/Image.hpp b/frame/src/Image.hpp index 82a8642..3b755e3 100644 --- a/frame/src/Image.hpp +++ b/frame/src/Image.hpp @@ -1,9 +1,11 @@ #pragma once +#include "Color.hpp" #include "Size.hpp" #include #include + namespace frame { @@ -25,6 +27,8 @@ namespace frame uint8_t& at(uint32_t x, uint32_t y); uint8_t const& at(uint32_t x, uint32_t y) const; + void Clear(Color color); + auto getWidth() const { return mWidth; diff --git a/frame/src/font/Font.cpp b/frame/src/font/Font.cpp index 87e84b2..9f32d57 100644 --- a/frame/src/font/Font.cpp +++ b/frame/src/font/Font.cpp @@ -24,6 +24,47 @@ namespace frame::font } } + Glyph const& Font::getGlyph(uint32_t size, char c) const + { + return sizes.at(size).at(c); + } + + uint32_t Font::getLength(std::string_view text, uint32_t size) const + { + uint32_t length = 0; + + for(auto c : text) + { + auto const& g = getGlyph(size, c); + length += g.advance; + } + return length; + } + + uint32_t Font::getHeight(std::string_view text, uint32_t size) const + { + uint32_t height = 0; + + for(auto c : text) + { + auto const& g = getGlyph(size, c); + height = std::max((uint32_t)g.height, height); + } + return height; + } + + int32_t Font::getMaxYOffset(std::string_view text, uint32_t size) const + { + int32_t y_offset = 0; + + for(auto c : text) + { + auto const& g = getGlyph(size, c); + y_offset = std::min(g.y_offset, y_offset); + } + return y_offset; + } + void Font::LoadFromStream(std::istream& os) { json file_data = json::parse(os); @@ -46,9 +87,4 @@ namespace frame::font } } - Glyph const& Font::getGlyph(uint32_t size, char c) const - { - return sizes.at(size).at(c); - } - } // namespace frame::font \ No newline at end of file diff --git a/frame/src/font/Font.hpp b/frame/src/font/Font.hpp index 8f9b488..ca1fe80 100644 --- a/frame/src/font/Font.hpp +++ b/frame/src/font/Font.hpp @@ -9,12 +9,12 @@ namespace frame::font { using Glyphs = std::map; - using LineSpacing = std::map; + using LineSpacing = std::map; class Font { std::string name; - std::map sizes; + std::map sizes; LineSpacing lineSpacing; public: @@ -23,6 +23,15 @@ namespace frame::font Glyph const& getGlyph(uint32_t size, char c) const; + uint32_t getLength(std::string_view text, uint32_t size) const; + uint32_t getHeight(std::string_view text, uint32_t size) const; + int32_t getMaxYOffset(std::string_view text, uint32_t size) const; + + uint32_t getLineSpacing(uint32_t size) const + { + return lineSpacing.at(size); + } + protected: void LoadFromStream(std::istream& os); }; diff --git a/frame/src/font/Glyph.hpp b/frame/src/font/Glyph.hpp index 39c2b3e..61be2fb 100644 --- a/frame/src/font/Glyph.hpp +++ b/frame/src/font/Glyph.hpp @@ -13,9 +13,9 @@ namespace frame::font Image image; uint8_t height; uint8_t width; - int8_t x_offset; - int8_t y_offset; - int8_t advance; + int32_t x_offset; + int32_t y_offset; + int32_t advance; public: Glyph() = default; diff --git a/frame/src/main.cpp b/frame/src/main.cpp index 2ebfa6b..9506d98 100644 --- a/frame/src/main.cpp +++ b/frame/src/main.cpp @@ -65,12 +65,32 @@ int main() {110, (int)display->getSize().height - 10}, 5); - target.DrawText("abcdefghijklmnopqrstuvwxyz", {100, 50}, *font, 14); + target.DrawText("Hallo Welt!", {100, 50}, *font, 14); + target.DrawText("Hallo Welt!", {50, 100}, *font, 30); display->Display(target.getImage()); std::this_thread::sleep_for(10s); + target.Clear(); + + frame::Vector pos = display->getSize() / 2; + + auto text = "10:30"; + + pos.x -= font->getLength(text, 250) / 2; + pos.y += font->getHeight(text, 250) / 2; + pos.y -= font->getMaxYOffset(text, 250) + font->getHeight(text, 250); + + target.DrawText(text, pos, *font, 250); + + target.DrawTextGlyphBounds(text, pos, *font, 250); + target.DrawLine({0, (int32_t)pos.y}, + {(int32_t)display->getSize().width, pos.y}); + display->Display(target.getImage()); + + std::this_thread::sleep_for(10s); + display->Clear(frame::display::Color::WHITE); } diff --git a/frame/src/render/RenderTarget.cpp b/frame/src/render/RenderTarget.cpp index 329af6f..42e2164 100644 --- a/frame/src/render/RenderTarget.cpp +++ b/frame/src/render/RenderTarget.cpp @@ -173,7 +173,7 @@ namespace frame::render void RenderTarget::DrawText(std::string_view pText, Vector pCenterLineStart, font::Font const& pFont, - uint8_t size) + uint32_t size) { auto pos = pCenterLineStart; for(auto c : pText) @@ -182,6 +182,31 @@ namespace frame::render } } + void RenderTarget::DrawTextGlyphBounds(std::string_view pText, + Vector pCenterLineStart, + font::Font const& pFont, + uint32_t size) + { + auto pos = pCenterLineStart; + + auto lineSpacing = pFont.getLineSpacing(size); + auto _3 = lineSpacing / 3; + for(auto c : pText) + { + auto const& g = pFont.getGlyph(size, c); + DrawRect({int32_t(pos.x), int32_t(pos.y - _3 * 2)}, + {int32_t(pos.x + g.advance), int32_t(pos.y + _3)}, + 1); + + pos.x += g.advance; + } + } + + void RenderTarget::Clear(Color color) + { + image.Clear(color); + } + void RenderTarget::DrawPointsMirrorCircle(Vector const& center, Vector const& pos, Color color) diff --git a/frame/src/render/RenderTarget.hpp b/frame/src/render/RenderTarget.hpp index 1d783e0..aba08ae 100644 --- a/frame/src/render/RenderTarget.hpp +++ b/frame/src/render/RenderTarget.hpp @@ -43,7 +43,14 @@ namespace frame::render void DrawText(std::string_view pText, Vector pCenterLineStart, font::Font const& pFont, - uint8_t size); + uint32_t size); + + void DrawTextGlyphBounds(std::string_view pText, + Vector pCenterLineStart, + font::Font const& pFont, + uint32_t size); + + void Clear(Color color = WHITE); Image const& getImage() {