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
|
#pragma once
#include "Runtime/Utilities/Singleton.h"
#include "Runtime/Graphics/Texture.h"
#include "freetype.h"
#include <string>
#include <unordered_map>
#include <vector>
//https://learnopengl.com/In-Practice/Text-Rendering
struct Character {
unsigned int atlas; // atlas����
Internal::Rect position; // ��altas����
Internal::Vector2 bearing; // ���Ͻ������ԭ���ƫ��
unsigned int advance; // �ܿ��������˼��
};
namespace character
{
typedef unsigned short Codepoint; // unicode Codepoint��BMP��U+0000��U+FFFF)
union Hash {
unsigned int hashCode;
struct {
Codepoint codepoint;
unsigned short size;//�����С
};
bool operator==(const Hash &other) const
{
return codepoint == other.codepoint && size == other.size;
}
};
}
namespace std
{
template <>
struct hash<character::Hash>
{
std::size_t operator()(const character::Hash& k) const
{
return k.hashCode;
}
};
}
struct GlyphAtals
{
int index;
Texture* altas; // ��ͼ
int width, height; // �ߴ�
Internal::Vector2 cursor; // �α꣬�����Ͻǣ�0,0����ʼ
int rowHeight; // ��ǰ�еĸ߶�
};
struct TextGeneratingSettings
{
Internal::Vector2 atlasSize; // atlas�ijߴ�
int margin; // atlas�ı߽�
int padding; // glyph�֮��ļ�࣬��ֹ������ʱ��Խ��
};
class TextGenerator : public Singleton<TextGenerator>
{
public:
void Setup(TextGeneratingSettings settings);
const Character* GetCharacter(character::Codepoint codepoint, int pixelSize);
const GlyphAtals* GetGlyphAtlas(int index);
// pre-bake
void RenderCharacter(character::Codepoint codepoint, int pixelSize);
void RenderCharacters(character::Codepoint* codepoint, int n, int pixelSize);
private:
Texture* CreateAtlas();
GlyphAtals* RequestAtlas(int pixelSize, Internal::Vector2 preferSize);
Internal::Rect GetRenderChartAndMove(GlyphAtals* atlas, Internal::Vector2 preferSize);
bool HasEnoughSpace(GlyphAtals* atlas, Internal::Vector2 preferSize);
character::Hash GetHash(character::Codepoint Codepoint, int pixelSize);
std::unordered_map<character::Hash, Character> m_Characters; // ��Ⱦ�������
std::vector<GlyphAtals> m_Atlases; // ��ǰ���е�atlas
std::unordered_map<int, GlyphAtals*> m_AtlasCache; // �����ҵ����õ�atlas
int m_AtlasMargin;
int m_GlyphPadding;
Internal::Vector2 m_AtlasSize;
FT_Library m_FTLibrary;
FT_Face m_FTFace;
};
#define g_TextGenerator (*TextGenerator::Instance())
namespace TextHelper
{
void print_glyph(unsigned char* glyph, int width, int height);
}
|