summaryrefslogtreecommitdiff
path: root/Runtime/GUI/TextGenerator.h
diff options
context:
space:
mode:
Diffstat (limited to 'Runtime/GUI/TextGenerator.h')
-rw-r--r--Runtime/GUI/TextGenerator.h89
1 files changed, 81 insertions, 8 deletions
diff --git a/Runtime/GUI/TextGenerator.h b/Runtime/GUI/TextGenerator.h
index eacc99c..1065acf 100644
--- a/Runtime/GUI/TextGenerator.h
+++ b/Runtime/GUI/TextGenerator.h
@@ -1,32 +1,105 @@
#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 textureID; // ID handle of the glyph texture
- Internal::Vector2 size; // Size of glyph
- Internal::Vector2 bearing; // Offset from baseline to left/top of glyph
- unsigned int advance; // Offset to advance to next glyph
+ unsigned int atlas; // atlas索引
+ Internal::Rect position; // 在altas里的位置
+ Internal::Vector2 bearing; // 左上角相对于原点的偏移
+ unsigned int advance; // 总宽,算上了间隔
};
namespace character
{
- typedef wchar_t unicode;
- typedef unsigned int hash;
+ 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的尺寸
+ int margin; // atlas的边界
+ int padding; // glyph相互之间的间距,防止采样的时候越界
+};
+
class TextGenerator : public Singleton<TextGenerator>
{
public:
+ void Setup(TextGeneratingSettings settings);
+ Character GetCharacter(character::Codepoint codepoint, int pixelSize);
+ void RenderCharacter(character::Codepoint codepoint, int pixelSize);
+ GlyphAtals* GetGlyphAtlas(int index);
private:
- std::unordered_map<character::hash, Character> m_Characters;
- character::hash GetCharacterHash(character::unicode unicode, int pixelSize);
+ Texture* CreateAtlas();
+ GlyphAtals* RequestAtlas(int pixelSize, Internal::Vector2 preferSize);
+
+ Internal::Rect GetRenderChartAndMove(GlyphAtals* atlas, Internal::Vector2 preferSize);
+ bool HasEnoughSpace(GlyphAtals* atlas, Internal::Vector2 preferSize);
+
+ 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;
+
+ character::Hash GetHash(character::Codepoint Codepoint, int pixelSize);
};
+
+#define g_TextGenerator (*TextGenerator::Instance())
+
+namespace TextHelper
+{
+
+ void print_glyph(unsigned char* glyph, int width, int height);
+
+}