diff options
author | chai <chaifix@163.com> | 2021-11-01 12:19:36 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-11-01 12:19:36 +0800 |
commit | 4dead522e513ffd326101b790b2129595f72ff42 (patch) | |
tree | 9c1cbc8169f524a36e6dbb4a43af7728e15fefe7 /Runtime/GUI/Font.h | |
parent | 44d6c41e5e586572de08c72c358aed9100a30353 (diff) |
* TextGenerator -> Font
Diffstat (limited to 'Runtime/GUI/Font.h')
-rw-r--r-- | Runtime/GUI/Font.h | 110 |
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); + +} |