forked from CleverRaven/Cataclysm-DDA
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsdl_font.h
174 lines (148 loc) · 6.5 KB
/
sdl_font.h
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#pragma once
#ifndef CATA_SRC_SDL_FONT_H
#define CATA_SRC_SDL_FONT_H
#if defined(TILES)
#include "cursesdef.h" // IWYU pragma: associated
#include "sdltiles.h" // IWYU pragma: associated
#include <array>
#include <map>
#include <memory>
#include <vector>
#include <string>
#include "sdl_geometry.h"
#include "color.h"
#include "color_loader.h"
#include "debug.h"
#include "font_loader.h"
#include "point.h"
#include "hash_utils.h"
#include "sdl_wrappers.h"
using palette_array = std::array<SDL_Color, color_loader<SDL_Color>::COLOR_NAMES_COUNT>;
/// Interface which is capable of rendering a single character on the screen.
class Font
{
public:
Font( int w, int h, const palette_array &palette ) :
width( w ), height( h ), palette( palette ) { }
virtual ~Font() = default;
/// @return `true` if font is able to render utf-8 encoded symbol @p ch.
virtual bool isGlyphProvided( const std::string &ch ) const = 0;
/// Draw a single character using font's palette.
/// @param ch Character to draw
/// @param p Point on the screen where to draw character
/// @param color Curses color to use when drawing
/// @param opacity Optional opacity of the character
virtual void OutputChar( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry,
const std::string &ch, const point &p,
unsigned char color, float opacity = 1.0f ) = 0;
/// Draw an ascii line using font's palette.
/// @param line_id Character to draw
/// @param point Point on the screen where to draw character
/// @param color Curses color to use when drawing
virtual void draw_ascii_lines( const SDL_Renderer_Ptr &renderer,
const GeometryRenderer_Ptr &geometry,
unsigned char line_id, const point &p, unsigned char color ) const;
/// Try to load a font by typeface (Bitmap or Truetype).
static std::unique_ptr<Font> load_font(
SDL_Renderer_Ptr &renderer, SDL_PixelFormat_Ptr &format,
const std::string &typeface, int fontsize, int fontwidth,
int fontheight,
const palette_array &palette,
bool fontblending );
public:
// the width of the font, background is always this size.
int width;
// the height of the font, background is always this size.
int height;
// font palette.
const palette_array &palette;
};
using Font_Ptr = std::unique_ptr<Font>;
/// Font implementation on a TrueType font. Its glyphs are cached.
class CachedTTFFont : public Font
{
public:
CachedTTFFont(
int w, int h,
const palette_array &palette,
std::string typeface, int fontsize, bool fontblending );
~CachedTTFFont() override = default;
bool isGlyphProvided( const std::string &ch ) const override;
void OutputChar( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry,
const std::string &ch,
const point &p,
unsigned char color, float opacity = 1.0f ) override;
protected:
SDL_Texture_Ptr create_glyph( const SDL_Renderer_Ptr &renderer, const std::string &ch, int color );
TTF_Font_Ptr font;
// Maps (character code, color) to SDL_Texture*
struct key_t {
std::string codepoints;
unsigned char color;
std::pair<std::string, unsigned char> as_pair() const {
return std::make_pair( codepoints, color );
}
friend bool operator==( const key_t &lhs, const key_t &rhs ) noexcept {
return lhs.as_pair() == rhs.as_pair();
}
};
struct key_t_hash {
size_t operator()( const key_t &k ) const {
return cata::auto_hash<std::pair<std::string, unsigned char>>()( k.as_pair() );
}
};
struct cached_t {
SDL_Texture_Ptr texture;
int width;
};
std::unordered_map<key_t, cached_t, key_t_hash> glyph_cache_map;
const bool fontblending;
};
/// A font created from a bitmap. Each character is taken from a
/// specific area of the source bitmap.
class BitmapFont : public Font
{
public:
BitmapFont(
SDL_Renderer_Ptr &renderer, SDL_PixelFormat_Ptr &format,
int w, int h,
const palette_array &palette,
const std::string &typeface_path );
~BitmapFont() override = default;
bool isGlyphProvided( const std::string &ch ) const override;
void OutputChar( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry,
const std::string &ch,
const point &p,
unsigned char color, float opacity = 1.0f ) override;
void OutputChar( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry, int t,
const point &p,
unsigned char color, float opacity = 1.0f );
void draw_ascii_lines( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry,
unsigned char line_id, const point &p, unsigned char color ) const override;
protected:
std::array<SDL_Texture_Ptr, color_loader<SDL_Color>::COLOR_NAMES_COUNT> ascii;
int tilewidth;
};
/// Multiple fonts container. Tries to render character using font on the top,
/// if glyph is not supported, tries next font, and so on.
class FontFallbackList : public Font
{
public:
FontFallbackList(
SDL_Renderer_Ptr &renderer, SDL_PixelFormat_Ptr &format,
int w, int h,
const palette_array &palette,
const std::vector<std::string> &typefaces,
int fontsize, bool fontblending );
~FontFallbackList() override = default;
bool isGlyphProvided( const std::string &ch ) const override;
void OutputChar( const SDL_Renderer_Ptr &renderer, const GeometryRenderer_Ptr &geometry,
const std::string &ch,
const point &p,
unsigned char color, float opacity = 1.0f ) override;
protected:
std::vector<std::unique_ptr<Font>> fonts;
std::map<std::string, std::vector<std::unique_ptr<Font>>::iterator> glyph_font;
};
#endif // TILES
#endif // CATA_SRC_SDL_FONT_H