diff --git a/src/graphics/core/Font.cpp b/src/graphics/core/Font.cpp index c148ae72..189bec14 100644 --- a/src/graphics/core/Font.cpp +++ b/src/graphics/core/Font.cpp @@ -1,5 +1,6 @@ #include "Font.hpp" +#include #include #include "Texture.hpp" #include "Batch2D.hpp" @@ -64,7 +65,7 @@ static inline void draw_glyph( -0.2f * style.italic, 16, c, - batch.getColor() + batch.getColor() * style.color ); } } @@ -87,7 +88,7 @@ static inline void draw_glyph( 0.5f, 16, c, - batch.getColor() + batch.getColor() * style.color ); } } @@ -100,17 +101,33 @@ static inline void draw_text( const glm::vec3& pos, const glm::vec3& right, const glm::vec3& up, - float glyphInterval + float glyphInterval, + const FontStylesScheme* styles ) { + static FontStylesScheme defStyles { + {{std::numeric_limits::max()}}, + }; + if (styles == nullptr) { + styles = &defStyles; + } + uint page = 0; uint next = MAX_CODEPAGES; int x = 0; int y = 0; - FontStyle style {}; - do { - for (uint c : text){ + size_t entryIndex = 0; + int styleCharsCounter = -1; + const FontStyle* style = &styles->palette.at(entryIndex); + + for (uint c : text) { + styleCharsCounter++; + if (styleCharsCounter > style->n && + entryIndex + 1 < styles->palette.size()) { + style = &styles->palette.at(++entryIndex); + styleCharsCounter = -1; + } if (!font.isPrintableChar(c)) { x++; continue; @@ -119,7 +136,14 @@ static inline void draw_text( if (charpage == page){ batch.texture(font.getPage(charpage)); draw_glyph( - batch, pos, glm::vec2(x, y), c, right, up, glyphInterval, style + batch, + pos, + glm::vec2(x, y), + c, + right, + up, + glyphInterval, + *style ); } else if (charpage > page && charpage < next){ @@ -145,20 +169,27 @@ const Texture* Font::getPage(int charpage) const { } void Font::draw( - Batch2D& batch, std::wstring_view text, int x, int y, float scale + Batch2D& batch, + std::wstring_view text, + int x, + int y, + const FontStylesScheme* styles, + float scale ) const { draw_text( *this, batch, text, glm::vec3(x, y, 0), glm::vec3(glyphInterval*scale, 0, 0), glm::vec3(0, lineHeight*scale, 0), - glyphInterval/static_cast(lineHeight) + glyphInterval/static_cast(lineHeight), + styles ); } void Font::draw( Batch3D& batch, std::wstring_view text, + const FontStylesScheme* styles, const glm::vec3& pos, const glm::vec3& right, const glm::vec3& up @@ -167,6 +198,7 @@ void Font::draw( *this, batch, text, pos, right * static_cast(glyphInterval), up * static_cast(lineHeight), - glyphInterval/static_cast(lineHeight) + glyphInterval/static_cast(lineHeight), + styles ); } diff --git a/src/graphics/core/Font.hpp b/src/graphics/core/Font.hpp index 121a19a6..0543065a 100644 --- a/src/graphics/core/Font.hpp +++ b/src/graphics/core/Font.hpp @@ -12,11 +12,16 @@ class Batch3D; class Camera; struct FontStyle { + size_t n = -1; bool bold = false; bool italic = false; glm::vec4 color {1, 1, 1, 1}; }; +struct FontStylesScheme { + std::vector palette; +}; + class Font { int lineHeight; int yoffset; @@ -45,12 +50,20 @@ public: /// @brief Check if character is visible (non-whitespace) /// @param codepoint character unicode codepoint bool isPrintableChar(uint codepoint) const; - - void draw(Batch2D& batch, std::wstring_view text, int x, int y, float scale=1) const; + + void draw( + Batch2D& batch, + std::wstring_view text, + int x, + int y, + const FontStylesScheme* styles, + float scale = 1 + ) const; void draw( Batch3D& batch, std::wstring_view text, + const FontStylesScheme* styles, const glm::vec3& pos, const glm::vec3& right={1, 0, 0}, const glm::vec3& up={0, 1, 0} diff --git a/src/graphics/render/TextsRenderer.cpp b/src/graphics/render/TextsRenderer.cpp index fa24b61b..2a7d09db 100644 --- a/src/graphics/render/TextsRenderer.cpp +++ b/src/graphics/render/TextsRenderer.cpp @@ -98,11 +98,13 @@ void TextsRenderer::renderNote( pos + xvec * (width * 0.5f * preset.scale))) { return; } + static FontStylesScheme styles {}; auto color = preset.color; batch.setColor(glm::vec4(color.r, color.g, color.b, color.a * opacity)); font.draw( batch, text, + &styles, pos - xvec * (width * 0.5f) * preset.scale, xvec * preset.scale, yvec * preset.scale diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index 78751cea..04e2c28b 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -194,9 +194,9 @@ void SlotView::draw(const DrawContext* pctx, Assets* assets) { int y = pos.y+slotSize-16; batch->setColor({0, 0, 0, 1.0f}); - font->draw(*batch, text, x+1, y+1); + font->draw(*batch, text, x+1, y+1, nullptr); batch->setColor(glm::vec4(1.0f)); - font->draw(*batch, text, x, y); + font->draw(*batch, text, x, y, nullptr); } } diff --git a/src/graphics/ui/elements/Label.cpp b/src/graphics/ui/elements/Label.cpp index c356f13b..c1a4dd0d 100644 --- a/src/graphics/ui/elements/Label.cpp +++ b/src/graphics/ui/elements/Label.cpp @@ -66,6 +66,8 @@ Label::Label(const std::wstring& text, std::string fontName) cache.update(this->text, multiline, textWrap); } +Label::~Label() = default; + glm::vec2 Label::calcSize() { auto font = cache.font; uint lineHeight = font->getLineHeight(); @@ -201,10 +203,10 @@ void Label::draw(const DrawContext* pctx, Assets* assets) { if (i < cache.lines.size()-1) { view = std::wstring_view(text.c_str()+offset, cache.lines.at(i+1).offset-offset); } - font->draw(*batch, view, pos.x, pos.y + i * totalLineHeight); + font->draw(*batch, view, pos.x, pos.y + i * totalLineHeight, styles.get()); } } else { - font->draw(*batch, text, pos.x, pos.y); + font->draw(*batch, text, pos.x, pos.y, styles.get()); } } @@ -239,3 +241,7 @@ void Label::setTextWrapping(bool flag) { bool Label::isTextWrapping() const { return textWrap; } + +void Label::setStyles(std::unique_ptr styles) { + this->styles = std::move(styles); +} diff --git a/src/graphics/ui/elements/Label.hpp b/src/graphics/ui/elements/Label.hpp index 4aca8a7a..f2101147 100644 --- a/src/graphics/ui/elements/Label.hpp +++ b/src/graphics/ui/elements/Label.hpp @@ -3,6 +3,7 @@ #include "UINode.hpp" class Font; +struct FontStylesScheme; namespace gui { struct LineScheme { @@ -51,10 +52,14 @@ namespace gui { /// @brief Auto resize label to fit text bool autoresize = false; + + std::unique_ptr styles; public: Label(const std::string& text, std::string fontName="normal"); Label(const std::wstring& text, std::string fontName="normal"); + virtual ~Label(); + virtual void setText(const std::wstring& text); const std::wstring& getText() const; @@ -107,5 +112,7 @@ namespace gui { virtual void setTextWrapping(bool flag); virtual bool isTextWrapping() const; + + virtual void setStyles(std::unique_ptr styles); }; } diff --git a/src/graphics/ui/elements/Plotter.cpp b/src/graphics/ui/elements/Plotter.cpp index 293d84b5..d5d906e6 100644 --- a/src/graphics/ui/elements/Plotter.cpp +++ b/src/graphics/ui/elements/Plotter.cpp @@ -47,6 +47,12 @@ void Plotter::draw(const DrawContext* pctx, Assets* assets) { batch->setColor({1,1,1,0.2f}); string = util::to_wstring(y / multiplier, 3); } - font->draw(*batch, string, pos.x+dmwidth+2, pos.y+dmheight-y-labelsInterval); + font->draw( + *batch, + string, + pos.x + dmwidth + 2, + pos.y + dmheight - y - labelsInterval, + nullptr + ); } }