diff options
author | chai <chaifix@163.com> | 2021-10-30 22:59:42 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-10-30 22:59:42 +0800 |
commit | 26f05c6e3dcac9995345fb5a2b031be7e3ea79e9 (patch) | |
tree | fc32c3e9d235817df0be331a6100b7f8263facab /Runtime/GUI/TextGenerator.h | |
parent | c3e259f4d29e9bdcb73617ad8e4d71f117b4d289 (diff) |
*TextGenerator
Diffstat (limited to 'Runtime/GUI/TextGenerator.h')
-rw-r--r-- | Runtime/GUI/TextGenerator.h | 89 |
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); + +} |