-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfontrenderer.cpp
104 lines (89 loc) · 2.26 KB
/
fontrenderer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include "fontrenderer.hpp"
#include <cassert>
FontRenderer::FontRenderer(SDL_Renderer * renderer, TTF_Font * font) :
renderer{ renderer },
font { font, TTF_CloseFont },
cache { },
generation { 0 }
{
}
FontRenderer::Text const & FontRenderer::render(const std::string & what) const
{
auto str = what.empty() ? " " : what;
if(auto it = cache.find(what); it != cache.end())
{
if(it->second.last_use != generation)
{
it->second.ttl ++;
it->second.last_use = generation;
}
return it->second;
}
else
{
std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> surface {
TTF_RenderUTF8_Blended(font.get(), str.c_str(), { 0xFF, 0xFF, 0xFF, 0xFF }),
SDL_FreeSurface
};
assert(surface);
std::unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)> texture {
SDL_CreateTextureFromSurface(renderer, surface.get() ) ,
SDL_DestroyTexture
};
assert(texture);
auto [ new_it, emplaced ] = cache.emplace(what, std::move(texture));
assert(emplaced);
new_it->second.width = surface->w;
new_it->second.height = surface->h;
return new_it->second;
}
}
void FontRenderer::render(const SDL_Rect & target, const std::string & what, int align, SDL_Color const & color) const
{
Text const & str = render(what);
SDL_Rect dst, src;
dst.w = std::min(str.width, target.w);
dst.h = std::min(str.height, target.h);
if(align & Right)
dst.x = target.x + target.w - dst.w;
else if(align & Center)
dst.x = target.x + (target.w - dst.w) / 2;
else
dst.x = target.x;
if(align & Bottom)
dst.y = target.y + target.h - dst.h;
else if(align & Middle)
dst.y = target.y + (target.h - dst.h) / 2;
else
dst.y = target.y;
src.w = dst.w;
src.h = dst.h;
src.x = (str.width - dst.w) / 2;
src.y = (str.height - dst.h) / 2;
SDL_SetTextureColorMod(str.texture.get(), color.r, color.g, color.b);
SDL_SetTextureAlphaMod(str.texture.get(), color.a);
SDL_RenderCopy(
renderer,
str.texture.get(),
&src,
&dst
);
}
void FontRenderer::collect_garbage()
{
for(auto it = cache.begin(); it != cache.end(); /* none */)
{
auto current = it;
it++;
current->second.ttl--;
if(current->second.ttl == 0)
cache.erase(current);
}
generation += 1;
}
FontRenderer::Text::Text(FontRenderer::TexturePtr && tex) :
texture(std::move(tex)),
ttl(1),
last_use(~0U)
{
}