summaryrefslogtreecommitdiff
path: root/Runtime/GUI/Font.h
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2021-11-01 12:19:36 +0800
committerchai <chaifix@163.com>2021-11-01 12:19:36 +0800
commit4dead522e513ffd326101b790b2129595f72ff42 (patch)
tree9c1cbc8169f524a36e6dbb4a43af7728e15fefe7 /Runtime/GUI/Font.h
parent44d6c41e5e586572de08c72c358aed9100a30353 (diff)
* TextGenerator -> Font
Diffstat (limited to 'Runtime/GUI/Font.h')
-rw-r--r--Runtime/GUI/Font.h110
1 files changed, 110 insertions, 0 deletions
diff --git a/Runtime/GUI/Font.h b/Runtime/GUI/Font.h
index e69de29..da9ef55 100644
--- a/Runtime/GUI/Font.h
+++ b/Runtime/GUI/Font.h
@@ -0,0 +1,110 @@
+#pragma once
+
+#include "Runtime/Utilities/Singleton.h"
+#include "Runtime/Graphics/Texture.h"
+#include "freetype.h"
+#include "Runtime/Lua/LuaHelper.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的尺寸
+ int margin; // atlas的边界
+ int padding; // glyph相互之间的间距,防止采样的时候越界
+};
+
+class Font : public Singleton<Font>
+{
+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 (*Font::Instance())
+
+namespace TextHelper
+{
+
+ void print_glyph(unsigned char* glyph, int width, int height);
+
+}