summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-07-10 13:44:10 +0200
committerThorbjørn Lindeijer <bjorn@lindeijer.nl>2025-07-15 11:40:25 +0200
commitf83b1d648fc6ec2c64fd2c3483fede23c973c20f (patch)
tree04dd7950cbea1331870190d1caf9061011dfca05 /src
parent32bcf41f01d4ed4a3a08030095611e75d6186d60 (diff)
downloadmana-master.tar.gz
mana-master.tar.bz2
mana-master.tar.xz
mana-master.zip
Render font outlines using TTF_SetFontOutlineHEADmaster
Rather than rendering the same texture 4 additional times, render a specific outline version of the text. While reducing the number of times the text is drawn, it does increase font texture use. Result is a generally prettier outline due to rendering it properly at sharp corners of the characters. The shadow for outlined text is now also thicker, as appropriate. As part of this change, the `TextRenderer` class was merged into the `Graphics` and `TrueTypeFont` classes. There seemed to be little point in having a separate function for this, apart from needing more static casts to `Graphics*`. Also fixed an issue where the font style was not being restored after adjusting the font scale, when using an older SDL_ttf than 2.0.18. Closes #87
Diffstat (limited to 'src')
-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
17 files changed, 300 insertions, 290 deletions
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);
- }
-};