FifeGUI 0.3.0
A C++ GUI library designed for games.
truetypefont.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later OR BSD-3-Clause
2// SPDX-FileCopyrightText: 2004 - 2008 Olof Naessén and Per Larsson
3// SPDX-FileCopyrightText: 2013 - 2026 Fifengine contributors
4
5// Corresponding header include
6#include "fifechan/backends/sdl3/truetypefont.hpp"
7
8// Standard library includes
9#include <string>
10
11// Third-party library includes
12#include <SDL3/SDL.h>
13
14// Project headers (subdirs before local)
15#include "fifechan/backends/sdl3/graphics.hpp"
16#include "fifechan/exception.hpp"
17#include "fifechan/graphics.hpp"
18#include "fifechan/image.hpp"
19
20namespace fcn::sdl3
21{
22 TrueTypeFont::TrueTypeFont(std::string const & filename, int size) :
23 mRowSpacing(0),
25 mAntiAlias(true),
26 mFilename(filename),
27 mFont(TTF_OpenFont(filename.c_str(), static_cast<float>(size)))
28 {
29
30 if (mFont == nullptr) {
31 throwException("TrueTypeFont::TrueTypeFont. " + std::string(SDL_GetError()));
32 }
33 }
34
35 TrueTypeFont::~TrueTypeFont()
36 {
37 TTF_CloseFont(mFont);
38 }
39
40 int TrueTypeFont::getWidth(std::string const & text) const
41 {
42 int w = 0;
43 int h = 0;
44 // Use UTF-8 aware measurement to handle multi-byte glyphs (emoji)
45 TTF_GetStringSize(mFont, text.c_str(), text.length(), &w, &h);
46
47 return w;
48 }
49
51 {
52 return TTF_GetFontHeight(mFont) + mRowSpacing;
53 }
54
55 void TrueTypeFont::drawString(fcn::Graphics* graphics, std::string const & text, int x, int y)
56 {
57 if (text.empty()) {
58 return;
59 }
60
61 auto* sdlGraphics = dynamic_cast<fcn::sdl3::Graphics*>(graphics);
62
63 if (sdlGraphics == nullptr) {
64 throwException("TrueTypeFont::drawString. Graphics object must be fcn::sdl3::Graphics!");
65 return;
66 }
67
68 int const yoffset = getRowSpacing() / 2;
69
70 Color const col = graphics->getColor();
71
72 SDL_Color sdlCol;
73 sdlCol.b = col.b;
74 sdlCol.r = col.r;
75 sdlCol.g = col.g;
76 sdlCol.a = col.a;
77
78 SDL_Surface* textSurface = nullptr;
79 // Use UTF-8 aware rendering to avoid mangling multi-byte sequences
80 if (mAntiAlias) {
81 textSurface = TTF_RenderText_Blended(mFont, text.c_str(), text.length(), sdlCol);
82 } else {
83 textSurface = TTF_RenderText_Solid(mFont, text.c_str(), text.length(), sdlCol);
84 }
85
86 if (textSurface == nullptr) {
87 throwException("TrueTypeFont::drawString. " + std::string(SDL_GetError()));
88 return;
89 }
90
91 SDL_Renderer* renderer = sdlGraphics->getRenderTarget();
92 SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, textSurface);
93 if (texture == nullptr) {
94 SDL_DestroySurface(textSurface);
95 throwException("TrueTypeFont::drawString. Failed to create texture: " + std::string(SDL_GetError()));
96 return;
97 }
98
99 SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
100 SDL_SetTextureScaleMode(texture, SDL_SCALEMODE_NEAREST);
101
102 SDL_FRect dst;
103 SDL_FRect src;
104 dst.x = static_cast<float>(x);
105 dst.y = static_cast<float>(y + yoffset);
106 dst.w = static_cast<float>(textSurface->w);
107 dst.h = static_cast<float>(textSurface->h);
108 src.w = static_cast<float>(textSurface->w);
109 src.h = static_cast<float>(textSurface->h);
110 src.x = 0.0F;
111 src.y = 0.0F;
112
113 sdlGraphics->drawSDLTexture(texture, src, dst);
114
115 SDL_DestroyTexture(texture);
116 SDL_DestroySurface(textSurface);
117 }
118
120 {
121 mRowSpacing = spacing;
122 }
123
125 {
126 return mRowSpacing;
127 }
128
130 {
131 mGlyphSpacing = spacing;
132 }
133
135 {
136 return mGlyphSpacing;
137 }
138
139 void TrueTypeFont::setAntiAlias(bool antiAlias)
140 {
141 mAntiAlias = antiAlias;
142 }
143
145 {
146 return mAntiAlias;
147 }
148} // namespace fcn::sdl3
Color.
Definition color.hpp:58
uint8_t a
Alpha color component (0-255).
Definition color.hpp:350
uint8_t b
Blue color component (0-255).
Definition color.hpp:347
uint8_t g
Green color component (0-255).
Definition color.hpp:344
uint8_t r
Red color component (0-255).
Definition color.hpp:341
Abstract interface providing primitive drawing functions (lines, rectangles, etc.).
Definition graphics.hpp:58
virtual Color const & getColor() const =0
Gets the color to use when drawing.
SDL3 renderer-specific implementation of the Graphics interface.
virtual bool isAntiAlias()
Checks if anti aliasing is used.
int mGlyphSpacing
Additional spacing between glyphs in pixels.
int mRowSpacing
Additional spacing between rows in pixels.
std::string mFilename
Filename of the font used to create mFont.
virtual void setGlyphSpacing(int spacing)
Sets the spacing between letters in pixels.
TTF_Font * mFont
Underlying TTF_Font pointer from SDL_ttf.
virtual void setAntiAlias(bool antiAlias)
Enable or disable anti-aliasing for rendered glyphs.
int getWidth(std::string const &text) const override
Gets the width of a string.
virtual int getRowSpacing()
Gets the spacing between rows in pixels.
void drawString(fcn::Graphics *graphics, std::string const &text, int x, int y) override
Draws a string.
bool mAntiAlias
Whether anti-aliasing is enabled for rendering.
virtual void setRowSpacing(int spacing)
Sets the spacing between rows in pixels.
TrueTypeFont(std::string const &filename, int size)
Constructor.
virtual int getGlyphSpacing()
Gets the spacing between letters in pixels.
int getHeight() const override
Gets the height of the glyphs in the font.
void throwException(std::string const &message, std::source_location location=std::source_location::current())
Throw an Exception capturing the current source location.