summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/graphics.cpp69
-rw-r--r--src/graphics.h22
-rw-r--r--src/gui/truetypefont.cpp145
-rw-r--r--src/gui/truetypefont.h25
-rw-r--r--src/gui/widgets/browserbox.cpp22
-rw-r--r--src/gui/widgets/button.cpp20
-rw-r--r--src/gui/widgets/checkbox.cpp18
-rw-r--r--src/gui/widgets/label.cpp24
-rw-r--r--src/gui/widgets/radiobutton.cpp20
-rw-r--r--src/gui/widgets/textbox.cpp24
-rw-r--r--src/gui/widgets/textpreview.cpp21
-rw-r--r--src/gui/widgets/window.cpp14
-rw-r--r--src/resources/theme.cpp14
-rw-r--r--src/text.cpp6
-rw-r--r--src/textparticle.cpp4
-rw-r--r--src/textrenderer.h139
18 files changed, 301 insertions, 290 deletions
diff --git a/NEWS b/NEWS
index 64bd4374..93267cb7 100644
--- a/NEWS
+++ b/NEWS
@@ -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);
- }
-};