diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | src/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/graphics.cpp | 69 | ||||
-rw-r--r-- | src/graphics.h | 22 | ||||
-rw-r--r-- | src/gui/truetypefont.cpp | 145 | ||||
-rw-r--r-- | src/gui/truetypefont.h | 25 | ||||
-rw-r--r-- | src/gui/widgets/browserbox.cpp | 22 | ||||
-rw-r--r-- | src/gui/widgets/button.cpp | 20 | ||||
-rw-r--r-- | src/gui/widgets/checkbox.cpp | 18 | ||||
-rw-r--r-- | src/gui/widgets/label.cpp | 24 | ||||
-rw-r--r-- | src/gui/widgets/radiobutton.cpp | 20 | ||||
-rw-r--r-- | src/gui/widgets/textbox.cpp | 24 | ||||
-rw-r--r-- | src/gui/widgets/textpreview.cpp | 21 | ||||
-rw-r--r-- | src/gui/widgets/window.cpp | 14 | ||||
-rw-r--r-- | src/resources/theme.cpp | 14 | ||||
-rw-r--r-- | src/text.cpp | 6 | ||||
-rw-r--r-- | src/textparticle.cpp | 4 | ||||
-rw-r--r-- | src/textrenderer.h | 139 |
18 files changed, 301 insertions, 290 deletions
@@ -34,6 +34,7 @@ - Re-download updates when their checksum no longer matches - Enabled resizing windows from all sides - Enabled whispers in tabs by default +- Improved quality of outlined text rendering - Made pickup notifications to appear as particle instead of text by default - Made names update immediately when changing "Show gender" option - Made the screenshot file name a clickable link diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f7f3d205..8738a41b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,7 +4,7 @@ pkg_check_modules(SDL2 REQUIRED SDL2_image SDL2_mixer SDL2_net - SDL2_ttf) + SDL2_ttf>=2.0.12) find_package(PhysFS REQUIRED) find_package(CURL REQUIRED) find_package(LibXml2 REQUIRED) @@ -499,7 +499,6 @@ set(SRCS textmanager.h textparticle.cpp textparticle.h - textrenderer.h tileset.h units.cpp units.h diff --git a/src/graphics.cpp b/src/graphics.cpp index c5b86bc6..68fc4e46 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -21,6 +21,9 @@ #include "graphics.h" +#include "gui/truetypefont.h" +#include "resources/theme.h" + #include <guichan/exception.hpp> @@ -170,6 +173,72 @@ void Graphics::drawImageRect(const ImageRect &imgRect, int x, int y, int w, int } } +void Graphics::drawText(const std::string &text, + int x, int y, + gcn::Graphics::Alignment alignment, + const gcn::Color &color, + gcn::Font *font, + bool outline, + bool shadow, + const std::optional<gcn::Color> &outlineColor, + const std::optional<gcn::Color> &shadowColor) +{ + switch (alignment) + { + case gcn::Graphics::LEFT: + break; + case gcn::Graphics::CENTER: + x -= font->getWidth(text) / 2; + break; + case gcn::Graphics::RIGHT: + x -= font->getWidth(text); + break; + default: + throw GCN_EXCEPTION("Unknown alignment."); + } + + auto realOutlineColor = outlineColor; + auto realShadowColor = shadowColor; + + if (shadow && !realShadowColor) + { + auto sc = Theme::getThemeColor(Theme::SHADOW); + sc.a = color.a / 2; + realShadowColor = sc; + } + + if (outline && !realOutlineColor) + { + auto oc = Theme::getThemeColor(Theme::OUTLINE); + oc.a = color.a; + realOutlineColor = oc; + } + + setColor(color); + static_cast<TrueTypeFont*>(font)->drawString(graphics, text, x, y, + realOutlineColor, + realShadowColor); +} + +void Graphics::drawText(const std::string &text, + int x, + int y, + gcn::Graphics::Alignment align, + gcn::Font *font, + const TextFormat &format) +{ + drawText(text, + x, + y, + align, + format.color, + font, + format.outlineColor.has_value(), + format.shadowColor.has_value(), + format.outlineColor, + format.shadowColor); +} + void Graphics::_beginDraw() { pushClipArea(gcn::Rectangle(0, 0, mWidth, mHeight)); diff --git a/src/graphics.h b/src/graphics.h index 9d8a9215..b6508753 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -29,6 +29,9 @@ #include <guichan/graphics.hpp> #include <memory> +#include <optional> + +struct TextFormat; enum class FillMode { @@ -187,6 +190,25 @@ class Graphics : public gcn::Graphics drawImageRect(imgRect, area.x, area.y, area.width, area.height); } + using gcn::Graphics::drawText; + + void drawText(const std::string &text, + int x, int y, + gcn::Graphics::Alignment alignment, + const gcn::Color &color, + gcn::Font *font, + bool outline = false, + bool shadow = false, + const std::optional<gcn::Color> &outlineColor = {}, + const std::optional<gcn::Color> &shadowColor = {}); + + void drawText(const std::string &text, + int x, + int y, + gcn::Graphics::Alignment align, + gcn::Font *font, + const TextFormat &format); + /** * Updates the screen. This is done by either copying the buffer to the * screen or swapping pages. diff --git a/src/gui/truetypefont.cpp b/src/gui/truetypefont.cpp index 444641b5..c85d08c0 100644 --- a/src/gui/truetypefont.cpp +++ b/src/gui/truetypefont.cpp @@ -53,6 +53,7 @@ bool operator==(SDL_Color lhs, SDL_Color rhs) lhs.a == rhs.a); } + class TextChunk { public: @@ -60,24 +61,49 @@ public: : text(text) {} - void generate(TTF_Font *font) + void render(Graphics *graphics, + int x, int y, + TTF_Font *font, + std::unique_ptr<Image> &img, + float scale); + + const std::string text; + std::unique_ptr<Image> regular; + std::unique_ptr<Image> outlined; +}; + +void TextChunk::render(Graphics *graphics, + int x, int y, + TTF_Font *font, + std::unique_ptr<Image> &img, + float scale) +{ + if (!img) { // Always render in white, we'll use color modulation when rendering + constexpr SDL_Color white = { 255, 255, 255, 255 }; SDL_Surface *surface = TTF_RenderUTF8_Blended(font, getSafeUtf8String(text), - SDL_Color { 255, 255, 255, 255 }); + white); - if (!surface) - return; + if (surface) + { + img.reset(Image::load(surface)); + SDL_FreeSurface(surface); + } + } - img.reset(Image::load(surface)); + if (img) + { + graphics->drawRescaledImageF(img.get(), 0, 0, x, y, + img->getWidth(), + img->getHeight(), + img->getWidth() / scale, + img->getHeight() / scale, true); - SDL_FreeSurface(surface); } +} - std::unique_ptr<Image> img; - const std::string text; -}; std::list<TrueTypeFont*> TrueTypeFont::mFonts; float TrueTypeFont::mScale = 1.0f; @@ -85,6 +111,7 @@ float TrueTypeFont::mScale = 1.0f; TrueTypeFont::TrueTypeFont(const std::string &filename, int size, int style) : mFilename(filename) , mPointSize(size) + , mStyle(style) { if (TTF_Init() == -1) { @@ -93,14 +120,18 @@ TrueTypeFont::TrueTypeFont(const std::string &filename, int size, int style) } mFont = TTF_OpenFont(filename.c_str(), size * mScale); + mFontOutline = TTF_OpenFont(filename.c_str(), size * mScale); - if (!mFont) + if (!mFont || !mFontOutline) { throw GCN_EXCEPTION("SDLTrueTypeFont::SDLTrueTypeFont: " + std::string(TTF_GetError())); } TTF_SetFontStyle(mFont, style); + TTF_SetFontStyle(mFontOutline, style); + + TTF_SetFontOutline(mFontOutline, static_cast<int>(mScale)); mFonts.push_back(this); } @@ -112,6 +143,9 @@ TrueTypeFont::~TrueTypeFont() if (mFont) TTF_CloseFont(mFont); + if (mFontOutline) + TTF_CloseFont(mFontOutline); + TTF_Quit(); } @@ -123,37 +157,41 @@ void TrueTypeFont::drawString(gcn::Graphics *graphics, return; auto *g = static_cast<Graphics *>(graphics); + TextChunk &chunk = getChunk(text); - bool found = false; + chunk.render(g, x, y, mFont, chunk.regular, mScale); +} - for (auto i = mCache.begin(); i != mCache.end(); ++i) - { - auto &chunk = *i; - if (chunk.text == text) - { - // Raise priority: move it to front - mCache.splice(mCache.begin(), mCache, i); - found = true; - break; - } - } +void TrueTypeFont::drawString(Graphics *graphics, + const std::string &text, + int x, int y, + const std::optional<gcn::Color> &outlineColor, + const std::optional<gcn::Color> &shadowColor) +{ + if (text.empty()) + return; + + auto *g = static_cast<Graphics *>(graphics); + auto color = graphics->getColor(); + TextChunk &chunk = getChunk(text); - if (!found) + if (shadowColor) { - if (mCache.size() >= CACHE_SIZE) - mCache.pop_back(); - mCache.emplace_front(text); - mCache.front().generate(mFont); + g->setColor(*shadowColor); + if (outlineColor) + chunk.render(g, x, y, mFontOutline, chunk.outlined, mScale); + else + chunk.render(g, x + 1, y + 1, mFont, chunk.regular, mScale); } - if (auto img = mCache.front().img.get()) + if (outlineColor) { - g->drawRescaledImageF(img, 0, 0, x, y, - img->getWidth(), - img->getHeight(), - img->getWidth() / mScale, - img->getHeight() / mScale, true); + g->setColor(*outlineColor); + chunk.render(g, x - 1, y - 1, mFontOutline, chunk.outlined, mScale); } + + g->setColor(color); + chunk.render(g, x, y, mFont, chunk.regular, mScale); } void TrueTypeFont::updateFontScale(float scale) @@ -167,9 +205,16 @@ void TrueTypeFont::updateFontScale(float scale) { #if SDL_TTF_VERSION_ATLEAST(2, 0, 18) TTF_SetFontSize(font->mFont, font->mPointSize * mScale); + TTF_SetFontSize(font->mFontOutline, font->mPointSize * mScale); + TTF_SetFontOutline(font->mFontOutline, mScale); #else TTF_CloseFont(font->mFont); + TTF_CloseFont(font->mFontOutline); font->mFont = TTF_OpenFont(font->mFilename.c_str(), font->mPointSize * mScale); + font->mFontOutline = TTF_OpenFont(font->mFilename.c_str(), font->mPointSize * mScale); + TTF_SetFontStyle(font->mFont, font->mStyle); + TTF_SetFontStyle(font->mFontOutline, font->mStyle); + TTF_SetFontOutline(font->mFontOutline, mScale); #endif font->mCache.clear(); @@ -178,19 +223,11 @@ void TrueTypeFont::updateFontScale(float scale) int TrueTypeFont::getWidth(const std::string &text) const { - for (auto i = mCache.begin(); i != mCache.end(); i++) - { - if (i->text == text) - { - // Raise priority: move it to front - // Assumption is that TTF::draw will be called next - mCache.splice(mCache.begin(), mCache, i); - if (i->img) - return std::ceil(i->img->getWidth() / mScale); - return 0; - } - } + TextChunk &chunk = getChunk(text); + if (auto img = chunk.regular.get()) + return std::ceil(img->getWidth() / mScale); + // If the image wasn't created yet, just calculate the width of the text int w, h; TTF_SizeUTF8(mFont, getSafeUtf8String(text), &w, &h); return std::ceil(w / mScale); @@ -205,3 +242,21 @@ int TrueTypeFont::getLineHeight() const { return std::ceil(TTF_FontLineSkip(mFont) / mScale); } + +TextChunk &TrueTypeFont::getChunk(const std::string &text) const +{ + for (auto i = mCache.begin(); i != mCache.end(); i++) + { + if (i->text == text) + { + // Raise priority: move it to front + mCache.splice(mCache.begin(), mCache, i); + return *i; + } + } + + if (mCache.size() >= CACHE_SIZE) + mCache.pop_back(); + + return mCache.emplace_front(text); +} diff --git a/src/gui/truetypefont.h b/src/gui/truetypefont.h index a479537d..f88938ff 100644 --- a/src/gui/truetypefont.h +++ b/src/gui/truetypefont.h @@ -22,13 +22,16 @@ #pragma once +#include <guichan/color.hpp> #include <guichan/font.hpp> #include <SDL_ttf.h> #include <list> +#include <optional> #include <string> +class Graphics; class TextChunk; /** @@ -46,11 +49,13 @@ class TrueTypeFont : public gcn::Font * @param size Font size. */ TrueTypeFont(const std::string &filename, int size, int style = 0); - ~TrueTypeFont() override; - int getWidth(const std::string &text) const override; + const std::string &filename() const { return mFilename; } + int pointSize() const { return mPointSize; } + int style() const { return mStyle; } + int getWidth(const std::string &text) const override; int getHeight() const override; /** @@ -67,13 +72,27 @@ class TrueTypeFont : public gcn::Font const std::string &text, int x, int y) override; + /** + * Extended version of drawString that allows for rendering text with + * outline and/or shadow. + */ + void drawString(Graphics *graphics, + const std::string &text, + int x, int y, + const std::optional<gcn::Color> &outlineColor, + const std::optional<gcn::Color> &shadowColor); + static void updateFontScale(float scale); private: + TextChunk &getChunk(const std::string &text) const; + const std::string mFilename; - TTF_Font *mFont; + TTF_Font *mFont = nullptr; + TTF_Font *mFontOutline = nullptr; const int mPointSize; + const int mStyle; // Word surfaces cache mutable std::list<TextChunk> mCache; diff --git a/src/gui/widgets/browserbox.cpp b/src/gui/widgets/browserbox.cpp index 1deea30b..bf337a0f 100644 --- a/src/gui/widgets/browserbox.cpp +++ b/src/gui/widgets/browserbox.cpp @@ -23,7 +23,6 @@ #include "gui/widgets/browserbox.h" #include "keyboardconfig.h" -#include "textrenderer.h" #include "gui/gui.h" #include "gui/truetypefont.h" @@ -292,6 +291,8 @@ void BrowserBox::draw(gcn::Graphics *graphics) } } + auto g = static_cast<Graphics*>(graphics); + for (const auto &row : mTextRows) { for (const auto &part : row.parts) @@ -301,16 +302,15 @@ void BrowserBox::draw(gcn::Graphics *graphics) if (part.y > yEnd) return; - TextRenderer::renderText(graphics, - part.text, - part.x, - part.y, - Graphics::LEFT, - part.color, - part.font, - part.outlineColor.has_value() || mOutline, - mShadows, - part.outlineColor); + g->drawText(part.text, + part.x, + part.y, + Graphics::LEFT, + part.color, + part.font, + part.outlineColor.has_value() || mOutline, + mShadows, + part.outlineColor); } } } diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp index 31c3a677..604f5dc8 100644 --- a/src/gui/widgets/button.cpp +++ b/src/gui/widgets/button.cpp @@ -28,7 +28,6 @@ #include "resources/image.h" #include "resources/theme.h" -#include "textrenderer.h" #include <guichan/exception.hpp> #include <guichan/font.hpp> @@ -132,8 +131,9 @@ void Button::draw(gcn::Graphics *graphics) if (isPressed()) widgetState.flags |= STATE_SELECTED; + auto g = static_cast<Graphics *>(graphics); auto &skin = gui->getTheme()->getSkin(SkinType::Button); - skin.draw(static_cast<Graphics *>(graphics), widgetState); + skin.draw(g, widgetState); auto skinState = skin.getState(widgetState.flags); auto font = (skinState && skinState->textFormat.bold) ? boldFont : getFont(); @@ -196,18 +196,16 @@ void Button::draw(gcn::Graphics *graphics) } if (btnIconWidth) - static_cast<Graphics *>(graphics)->drawImage(icon, btnIconX, btnIconY); + g->drawImage(icon, btnIconX, btnIconY); if (auto skinState = skin.getState(widgetState.flags)) { - auto &textFormat = skinState->textFormat; - TextRenderer::renderText(static_cast<Graphics *>(graphics), - getCaption(), - textX, - textY, - getAlignment(), - font, - textFormat); + g->drawText(getCaption(), + textX, + textY, + getAlignment(), + font, + skinState->textFormat); } } diff --git a/src/gui/widgets/checkbox.cpp b/src/gui/widgets/checkbox.cpp index e6079f2f..4bb0bb72 100644 --- a/src/gui/widgets/checkbox.cpp +++ b/src/gui/widgets/checkbox.cpp @@ -21,8 +21,6 @@ #include "gui/widgets/checkbox.h" -#include "textrenderer.h" - #include "gui/gui.h" #include "resources/theme.h" @@ -44,19 +42,19 @@ void CheckBox::draw(gcn::Graphics* graphics) if (isSelected()) widgetState.flags |= STATE_SELECTED; + auto g = static_cast<Graphics *>(graphics); auto &skin = gui->getTheme()->getSkin(SkinType::CheckBox); - skin.draw(static_cast<Graphics *>(graphics), widgetState); + skin.draw(g, widgetState); if (auto skinState = skin.getState(widgetState.flags)) { auto &textFormat = skinState->textFormat; - TextRenderer::renderText(static_cast<Graphics *>(graphics), - getCaption(), - skin.getMinWidth() + skin.padding + skin.spacing, - skin.padding, - Graphics::LEFT, - textFormat.bold ? boldFont : getFont(), - textFormat); + g->drawText(getCaption(), + skin.getMinWidth() + skin.padding + skin.spacing, + skin.padding, + Graphics::LEFT, + textFormat.bold ? boldFont : getFont(), + textFormat); } } diff --git a/src/gui/widgets/label.cpp b/src/gui/widgets/label.cpp index a2ed8820..9c0fd3cd 100644 --- a/src/gui/widgets/label.cpp +++ b/src/gui/widgets/label.cpp @@ -21,8 +21,6 @@ #include "gui/widgets/label.h" -#include "textrenderer.h" - #include "resources/theme.h" #include <guichan/exception.hpp> @@ -59,15 +57,15 @@ void Label::draw(gcn::Graphics *graphics) throw GCN_EXCEPTION("Unknown alignment."); } - TextRenderer::renderText(static_cast<Graphics *>(graphics), - getCaption(), - textX, - textY, - getAlignment(), - getForegroundColor(), - getFont(), - mOutlineColor.has_value(), - mShadowColor.has_value(), - mOutlineColor, - mShadowColor); + auto g = static_cast<Graphics *>(graphics); + g->drawText(getCaption(), + textX, + textY, + getAlignment(), + getForegroundColor(), + getFont(), + mOutlineColor.has_value(), + mShadowColor.has_value(), + mOutlineColor, + mShadowColor); } diff --git a/src/gui/widgets/radiobutton.cpp b/src/gui/widgets/radiobutton.cpp index ceba78eb..3474bbd8 100644 --- a/src/gui/widgets/radiobutton.cpp +++ b/src/gui/widgets/radiobutton.cpp @@ -21,11 +21,11 @@ #include "gui/widgets/radiobutton.h" -#include "textrenderer.h" - #include "gui/gui.h" #include "resources/theme.h" +#include <guichan/font.hpp> + RadioButton::RadioButton(const std::string &caption, const std::string &group, bool marked) @@ -44,19 +44,19 @@ void RadioButton::draw(gcn::Graphics* graphics) if (isSelected()) widgetState.flags |= STATE_SELECTED; + auto g = static_cast<Graphics *>(graphics); auto &skin = gui->getTheme()->getSkin(SkinType::RadioButton); - skin.draw(static_cast<Graphics *>(graphics), widgetState); + skin.draw(g, widgetState); if (auto skinState = skin.getState(widgetState.flags)) { auto &textFormat = skinState->textFormat; - TextRenderer::renderText(static_cast<Graphics *>(graphics), - getCaption(), - skin.getMinWidth() + skin.padding + skin.spacing, - skin.padding, - Graphics::LEFT, - textFormat.bold ? boldFont : getFont(), - textFormat); + g->drawText(getCaption(), + skin.getMinWidth() + skin.padding + skin.spacing, + skin.padding, + Graphics::LEFT, + textFormat.bold ? boldFont : getFont(), + textFormat); } } diff --git a/src/gui/widgets/textbox.cpp b/src/gui/widgets/textbox.cpp index 6cc514fe..7fd7d626 100644 --- a/src/gui/widgets/textbox.cpp +++ b/src/gui/widgets/textbox.cpp @@ -23,7 +23,6 @@ #include "gui/gui.h" #include "resources/theme.h" -#include "textrenderer.h" #include <guichan/font.hpp> @@ -96,7 +95,7 @@ void TextBox::setTextWrapped(const std::string &text, int minDimension) xpos = width; wrappedStream << word; } - else if (xpos != 0 && xpos + getFont()->getWidth(" ") + width <= + else if (xpos != 0 && xpos + getFont()->getWidth(" ") + width <= mMinWidth) { xpos += getFont()->getWidth(" ") + width; @@ -176,18 +175,19 @@ void TextBox::draw(gcn::Graphics *graphics) graphics->setColor(*mTextColor); graphics->setFont(getFont()); + auto g = static_cast<Graphics*>(graphics); + for (i = 0; i < mTextRows.size(); i++) { // Move the text one pixel so we can have a caret before a letter. - TextRenderer::renderText(graphics, - mTextRows[i], - 1, - i * getFont()->getHeight(), - gcn::Graphics::LEFT, - *mTextColor, - getFont(), - mOutlineColor.has_value(), - false, - mOutlineColor); + g->drawText(mTextRows[i], + 1, + i * getFont()->getHeight(), + gcn::Graphics::LEFT, + *mTextColor, + getFont(), + mOutlineColor.has_value(), + false, + mOutlineColor); } } diff --git a/src/gui/widgets/textpreview.cpp b/src/gui/widgets/textpreview.cpp index 2f80bd23..aed04853 100644 --- a/src/gui/widgets/textpreview.cpp +++ b/src/gui/widgets/textpreview.cpp @@ -21,13 +21,7 @@ #include "gui/widgets/textpreview.h" -#include "configuration.h" -#include "textrenderer.h" - #include "gui/gui.h" -#include "gui/truetypefont.h" - -#include <typeinfo> TextPreview::TextPreview(const std::string &text) : mText(text) @@ -36,12 +30,13 @@ TextPreview::TextPreview(const std::string &text) mTextColor = &Theme::getThemeColor(Theme::TEXT); } -void TextPreview::draw(gcn::Graphics* graphics) +void TextPreview::draw(gcn::Graphics *graphics) { - TextRenderer::renderText(graphics, mText, 2, 2, gcn::Graphics::LEFT, - gcn::Color(mTextColor->r, - mTextColor->g, - mTextColor->b, - 255), - mFont, mOutline, mShadow); + auto g = static_cast<Graphics*>(graphics); + g->drawText(mText, 2, 2, gcn::Graphics::LEFT, + gcn::Color(mTextColor->r, + mTextColor->g, + mTextColor->b, + 255), + mFont, mOutline, mShadow); } diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp index bf496bd8..14d91af1 100644 --- a/src/gui/widgets/window.cpp +++ b/src/gui/widgets/window.cpp @@ -23,7 +23,6 @@ #include "configuration.h" #include "log.h" -#include "textrenderer.h" #include "gui/gui.h" #include "gui/viewport.h" @@ -139,13 +138,12 @@ void Window::drawFrame(gcn::Graphics *graphics) if (auto skinState = skin.getState(widgetState.flags)) { auto &textFormat = skinState->textFormat; - TextRenderer::renderText(g, - getCaption(), - getFrameSize() + skin.titleOffsetX, - getFrameSize() + skin.titleOffsetY, - gcn::Graphics::LEFT, - textFormat.bold ? boldFont : getFont(), - textFormat); + g->drawText(getCaption(), + getFrameSize() + skin.titleOffsetX, + getFrameSize() + skin.titleOffsetY, + gcn::Graphics::LEFT, + textFormat.bold ? boldFont : getFont(), + textFormat); } } } diff --git a/src/resources/theme.cpp b/src/resources/theme.cpp index 4dcbb9a4..0c332902 100644 --- a/src/resources/theme.cpp +++ b/src/resources/theme.cpp @@ -25,7 +25,6 @@ #include "configuration.h" #include "log.h" -#include "textrenderer.h" #include "resources/dye.h" #include "resources/image.h" @@ -419,13 +418,12 @@ void Theme::drawProgressBar(Graphics *graphics, const int textX = area.x + area.width / 2; const int textY = area.y + (area.height - font->getHeight()) / 2; - TextRenderer::renderText(graphics, - text, - textX, - textY, - gcn::Graphics::CENTER, - font, - *textFormat); + graphics->drawText(text, + textX, + textY, + gcn::Graphics::CENTER, + font, + *textFormat); } } diff --git a/src/text.cpp b/src/text.cpp index 4698aa87..14ffed18 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -23,7 +23,6 @@ #include "text.h" #include "textmanager.h" -#include "textrenderer.h" #include "gui/gui.h" @@ -94,6 +93,7 @@ void Text::adviseXY(int x, int y) void Text::draw(gcn::Graphics *graphics, int xOff, int yOff) { + auto g = static_cast<Graphics *>(graphics); if (mIsSpeech) { WidgetState state; @@ -103,7 +103,7 @@ void Text::draw(gcn::Graphics *graphics, int xOff, int yOff) state.height = mHeight + 10; auto theme = gui->getTheme(); - theme->drawSkin(static_cast<Graphics *>(graphics), SkinType::SpeechBubble, state); + theme->drawSkin(g, SkinType::SpeechBubble, state); /* if (mWidth >= 15) @@ -115,7 +115,7 @@ void Text::draw(gcn::Graphics *graphics, int xOff, int yOff) */ } - TextRenderer::renderText(graphics, mText, + g->drawText(mText, mX - xOff, mY - yOff, gcn::Graphics::LEFT, *mColor, mFont, !mIsSpeech, true); } diff --git a/src/textparticle.cpp b/src/textparticle.cpp index eb477217..4f6f1df4 100644 --- a/src/textparticle.cpp +++ b/src/textparticle.cpp @@ -21,7 +21,7 @@ #include "textparticle.h" -#include "textrenderer.h" +#include "graphics.h" #include <guichan/color.hpp> @@ -47,7 +47,7 @@ bool TextParticle::draw(Graphics *graphics, int offsetX, int offsetY) const gcn::Color color = *mColor; color.a = getCurrentAlpha() * 255; - TextRenderer::renderText(graphics, mText, + graphics->drawText(mText, screenX, screenY, gcn::Graphics::CENTER, color, mTextFont, mOutline, false); diff --git a/src/textrenderer.h b/src/textrenderer.h deleted file mode 100644 index de4fcff2..00000000 --- a/src/textrenderer.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Text Renderer - * Copyright (C) 2009 The Mana World Development Team - * Copyright (C) 2009-2012 The Mana Developers - * - * This file is part of The Mana Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#pragma once - -#include "resources/theme.h" - -#include <guichan/exception.hpp> -#include <guichan/font.hpp> - -/** - * Class for text rendering which can apply an outline and shadow. - */ -class TextRenderer -{ -public: - /** - * Renders a specified text. - */ - static void renderText(gcn::Graphics *graphics, - const std::string &text, - int x, int y, - gcn::Graphics::Alignment alignment, - const gcn::Color &color, - gcn::Font *font, - bool outline = false, - bool shadow = false, - const std::optional<gcn::Color> &outlineColor = {}, - const std::optional<gcn::Color> &shadowColor = {}) - { - switch (alignment) - { - case gcn::Graphics::LEFT: - break; - case gcn::Graphics::CENTER: - x -= font->getWidth(text) / 2; - break; - case gcn::Graphics::RIGHT: - x -= font->getWidth(text); - break; - default: - throw GCN_EXCEPTION("Unknown alignment."); - } - - // Text shadow - if (shadow) - { - if (shadowColor) - { - graphics->setColor(*shadowColor); - } - else - { - auto sc = Theme::getThemeColor(Theme::SHADOW); - sc.a = color.a / 2; - graphics->setColor(sc); - } - - if (outline) - font->drawString(graphics, text, x + 2, y + 2); - else - font->drawString(graphics, text, x + 1, y + 1); - } - - if (outline) - { - /* - graphics->setColor(guiPalette->getColor(Palette::OUTLINE, - alpha/4)); - // TODO: Reanable when we can draw it nicely in software mode - font->drawString(graphics, text, x + 2, y + 2); - font->drawString(graphics, text, x + 1, y + 2); - font->drawString(graphics, text, x + 2, y + 1); - */ - - // Text outline - if (outlineColor) - { - graphics->setColor(*outlineColor); - } - else - { - auto oc = Theme::getThemeColor(Theme::OUTLINE); - oc.a = color.a; - graphics->setColor(oc); - } - - font->drawString(graphics, text, x + 1, y); - font->drawString(graphics, text, x - 1, y); - font->drawString(graphics, text, x, y + 1); - font->drawString(graphics, text, x, y - 1); - } - - graphics->setColor(color); - font->drawString(graphics, text, x, y); - } - - /** - * Renders a specified text. - */ - static void renderText(gcn::Graphics *graphics, - const std::string &text, - int x, - int y, - gcn::Graphics::Alignment align, - gcn::Font *font, - const TextFormat &format) - { - renderText(graphics, - text, - x, - y, - align, - format.color, - font, - format.outlineColor.has_value(), - format.shadowColor.has_value(), - format.outlineColor, - format.shadowColor); - } -}; |