summaryrefslogtreecommitdiff
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
parent44d6c41e5e586572de08c72c358aed9100a30353 (diff)
* TextGenerator -> Font
-rw-r--r--Editor/EditorMain.cpp7
-rw-r--r--Projects/VisualStudio/Editor/Editor.vcxproj4
-rw-r--r--Projects/VisualStudio/Editor/Editor.vcxproj.filters18
-rw-r--r--Runtime/GUI/Font.cpp214
-rw-r--r--Runtime/GUI/Font.h110
-rw-r--r--Runtime/GUI/TextGenerator.cpp214
-rw-r--r--Runtime/GUI/TextGenerator.h109
7 files changed, 334 insertions, 342 deletions
diff --git a/Editor/EditorMain.cpp b/Editor/EditorMain.cpp
index 45ac81a..187df1c 100644
--- a/Editor/EditorMain.cpp
+++ b/Editor/EditorMain.cpp
@@ -9,7 +9,7 @@
#include "Editor/Win/Win.h"
#include "Runtime/Threading/Thread.h"
-#include "Runtime/GUI/TextGenerator.h"
+#include "Runtime/GUI/Font.h"
using namespace LuaBind;
@@ -25,10 +25,9 @@ void TestFont()
setting.padding = 5;
setting.atlasSize = Internal::Vector2(512, 512);
- TextGenerator::Instance()->Setup(setting);
+ Font::Instance()->Setup(setting);
auto content = L"abcdf与电子计算机的区别 与电子计算机的最大区别在于: 只是简单的计算工具,有些机型具备函数计算功能,有些机型具备一定的贮存功能,但一般只能存储几组数据。计算机则具备复杂存贮功能、控制功能,更加";
- TextGenerator::Instance()->RenderCharacters((character::Codepoint*)content, wcslen(content), 14);
-
+ Font::Instance()->RenderCharacters((character::Codepoint*)content, wcslen(content), 14);
}
int BeforeMainLoop(lua_State* L)
diff --git a/Projects/VisualStudio/Editor/Editor.vcxproj b/Projects/VisualStudio/Editor/Editor.vcxproj
index ffdf5ef..f732067 100644
--- a/Projects/VisualStudio/Editor/Editor.vcxproj
+++ b/Projects/VisualStudio/Editor/Editor.vcxproj
@@ -200,7 +200,6 @@
<ClCompile Include="..\..\..\Runtime\Graphics\VertexAttribute.cpp" />
<ClCompile Include="..\..\..\Runtime\Graphics\VertexBuffer.cpp" />
<ClCompile Include="..\..\..\Runtime\GUI\Font.cpp" />
- <ClCompile Include="..\..\..\Runtime\GUI\TextGenerator.cpp" />
<ClCompile Include="..\..\..\Runtime\Lua\LuaBind\LuaBindCFunctions.cpp" />
<ClCompile Include="..\..\..\Runtime\Lua\LuaBind\LuaBindClass.cpp" />
<ClCompile Include="..\..\..\Runtime\Lua\LuaBind\LuaBindEnum.cpp" />
@@ -284,9 +283,8 @@
<ClInclude Include="..\..\..\Runtime\Graphics\Texture.h" />
<ClInclude Include="..\..\..\Runtime\Graphics\VertexAttribute.h" />
<ClInclude Include="..\..\..\Runtime\Graphics\VertexBuffer.h" />
- <ClInclude Include="..\..\..\Runtime\GUI\Font.h" />
<ClInclude Include="..\..\..\Runtime\GUI\freetype.h" />
- <ClInclude Include="..\..\..\Runtime\GUI\TextGenerator.h" />
+ <ClInclude Include="..\..\..\Runtime\GUI\Font.h" />
<ClInclude Include="..\..\..\Runtime\Lua\LuaBind\LuaBind.h" />
<ClInclude Include="..\..\..\Runtime\Lua\LuaBind\LuaBindCFunctions.h" />
<ClInclude Include="..\..\..\Runtime\Lua\LuaBind\LuaBindClass.hpp" />
diff --git a/Projects/VisualStudio/Editor/Editor.vcxproj.filters b/Projects/VisualStudio/Editor/Editor.vcxproj.filters
index 9fb8bf2..edda3e3 100644
--- a/Projects/VisualStudio/Editor/Editor.vcxproj.filters
+++ b/Projects/VisualStudio/Editor/Editor.vcxproj.filters
@@ -378,9 +378,6 @@
<ClCompile Include="..\..\..\Editor\FileSystem\FileWatcher.cpp">
<Filter>Editor\FileSystem</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\Runtime\GUI\TextGenerator.cpp">
- <Filter>Runtime\GUI</Filter>
- </ClCompile>
<ClCompile Include="..\..\..\Runtime\Rendering\Quad.cpp">
<Filter>Runtime\Rendering</Filter>
</ClCompile>
@@ -390,12 +387,12 @@
<ClCompile Include="..\..\..\Runtime\Graphics\RenderCommands.cpp">
<Filter>Runtime\Graphics</Filter>
</ClCompile>
- <ClCompile Include="..\..\..\Runtime\GUI\Font.cpp">
- <Filter>Runtime\GUI</Filter>
- </ClCompile>
<ClCompile Include="..\..\..\Runtime\Graphics\DynamicVertexBuffer.cpp">
<Filter>Runtime\Graphics</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\Runtime\GUI\Font.cpp">
+ <Filter>Runtime\GUI</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Editor\GUI\Dock.h">
@@ -659,9 +656,6 @@
<ClInclude Include="..\..\..\Editor\FileSystem\FileWatcher.h">
<Filter>Editor\FileSystem</Filter>
</ClInclude>
- <ClInclude Include="..\..\..\Runtime\GUI\TextGenerator.h">
- <Filter>Runtime\GUI</Filter>
- </ClInclude>
<ClInclude Include="..\..\..\Runtime\GUI\freetype.h">
<Filter>Runtime\GUI</Filter>
</ClInclude>
@@ -683,12 +677,12 @@
<ClInclude Include="..\..\..\Runtime\Graphics\RenderCommands.h">
<Filter>Runtime\Graphics</Filter>
</ClInclude>
- <ClInclude Include="..\..\..\Runtime\GUI\Font.h">
- <Filter>Runtime\GUI</Filter>
- </ClInclude>
<ClInclude Include="..\..\..\Runtime\Graphics\DynamicVertexBuffer.h">
<Filter>Runtime\Graphics</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\Runtime\GUI\Font.h">
+ <Filter>Runtime\GUI</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\..\Runtime\Lua\LuaBind\LuaBindClass.inc">
diff --git a/Runtime/GUI/Font.cpp b/Runtime/GUI/Font.cpp
index e69de29..f00f33d 100644
--- a/Runtime/GUI/Font.cpp
+++ b/Runtime/GUI/Font.cpp
@@ -0,0 +1,214 @@
+#include "freetype.h"
+#include "Font.h"
+#include "../Math/Math.h"
+#include "Runtime/Debug/Log.h"
+#include "Runtime/Utilities/Assert.h"
+#include "Runtime/Graphics/ImageData.h"
+
+using namespace character;
+
+//https://unicode-table.com/en/#cjk-unified-ideographs-extension-a
+//https://learnopengl.com/In-Practice/Text-Rendering
+//https://www.zhihu.com/question/294660079
+//https://baike.baidu.com/item/%E5%9F%BA%E6%9C%AC%E5%A4%9A%E6%96%87%E7%A7%8D%E5%B9%B3%E9%9D%A2/10788078
+//https://stackoverflow.com/questions/27331819/whats-the-difference-between-a-character-a-code-point-a-glyph-and-a-grapheme
+
+void Font::Setup(TextGeneratingSettings settings)
+{
+ m_AtlasMargin = settings.margin;
+ m_GlyphPadding = settings.padding;
+ m_AtlasSize = settings.atlasSize;
+
+ if (FT_Init_FreeType(&m_FTLibrary))
+ {
+ return;
+ }
+
+ if (FT_New_Face(m_FTLibrary, "Resources/Font/Deng.ttf", 0, &m_FTFace))
+ {
+ return;
+ }
+}
+
+character::Hash Font::GetHash(Codepoint codepoint, int pixelSize)
+{
+ character::Hash hash;
+ hash.codepoint = codepoint;
+ hash.size = pixelSize;
+ return hash;
+}
+
+const Character* Font::GetCharacter(character::Codepoint codepoint, int pixelSize)
+{
+ character::Hash hash = GetHash(codepoint, pixelSize);
+ auto iter = m_Characters.find(hash);
+ if (iter == m_Characters.end())
+ {
+ RenderCharacter(codepoint, pixelSize);
+ iter = m_Characters.find(hash);
+ }
+ Assert(iter != m_Characters.end());
+ return &iter->second;
+}
+
+void Font::RenderCharacters(character::Codepoint* codepoint, int n, int pixelSize)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ RenderCharacter(codepoint[i], pixelSize);
+ }
+}
+
+void Font::RenderCharacter(character::Codepoint codepoint, int pixelSize)
+{
+ character::Hash hash = GetHash(codepoint, pixelSize);
+ if (m_Characters.count(hash) != 0)
+ return;
+ FT_Set_Pixel_Sizes(m_FTFace, 0, pixelSize);
+ if (FT_Load_Char(m_FTFace, codepoint, FT_LOAD_RENDER))
+ {
+ return;
+ }
+
+ int w = m_FTFace->glyph->bitmap.width;
+ int h = m_FTFace->glyph->bitmap.rows;
+
+ //TextHelper::print_glyph(m_FTFace->glyph->bitmap.buffer, w, h);
+
+ GlyphAtals* atlas = RequestAtlas(pixelSize, Internal::Vector2(w, h));
+ Assert(atlas);
+
+ Internal::Rect rect = GetRenderChartAndMove(atlas, Internal::Vector2(w, h));
+
+ try
+ {
+ atlas->altas->UpdateSubImage(rect, EPixelFormat::PixelFormat_R, EPixelElementType::PixelType_UNSIGNED_BYTE, m_FTFace->glyph->bitmap.buffer);
+ }
+ catch (TextureException& e)
+ {
+ std::string error = e.what();
+ error = "Render Character Error: " + error;
+ log_error(e.what());
+ return;
+ }
+
+ Character character;
+ character.atlas = atlas->index;
+ character.position = rect;
+ character.bearing = Internal::Vector2(m_FTFace->glyph->bitmap_left, m_FTFace->glyph->bitmap_top);
+ character.advance = m_FTFace->glyph->advance.x * 1/64.f;
+
+ m_Characters.insert(std::pair<character::Hash, Character>(hash, character));
+}
+
+const GlyphAtals* Font::GetGlyphAtlas(int index)
+{
+ if (index >= m_Atlases.size())
+ return NULL;
+ return &m_Atlases[index];
+}
+
+Internal::Rect Font::GetRenderChartAndMove(GlyphAtals* atlas, Internal::Vector2 preferSize)
+{
+ Internal::Rect rect;
+ Internal::Vector2 space;
+ space.x = atlas->width - atlas->cursor.x - m_AtlasMargin;
+ space.y = atlas->height - atlas->cursor.y - m_AtlasMargin;
+ if (space.x > preferSize.x && space.y > preferSize.y)
+ {
+ rect.x = atlas->cursor.x;
+ rect.y = atlas->cursor.y;
+ rect.width = preferSize.x;
+ rect.height = preferSize.y;
+ atlas->cursor.x += rect.width + m_GlyphPadding;
+ atlas->rowHeight = max(atlas->rowHeight, preferSize.y);
+ }
+ else if (space.y - atlas->rowHeight - m_GlyphPadding - m_AtlasMargin > preferSize.y)
+ {
+ rect.x = m_AtlasMargin;
+ rect.y = atlas->cursor.y + m_GlyphPadding + atlas->rowHeight;
+ rect.width = preferSize.x;
+ rect.height = preferSize.y;
+ atlas->cursor.x = m_AtlasMargin;
+ atlas->cursor.y += atlas->rowHeight + m_GlyphPadding;
+ atlas->rowHeight = rect.height;
+ }
+ else
+ {
+ Assert(false);
+ }
+ return rect;
+}
+
+GlyphAtals* Font::RequestAtlas(int pixelSize, Internal::Vector2 preferSize)
+{
+ GlyphAtals* atlas = NULL;
+ auto iter = m_AtlasCache.find(pixelSize);
+ if (iter == m_AtlasCache.end() || !HasEnoughSpace(iter->second, preferSize))
+ {
+ Texture* tex = CreateAtlas();
+ GlyphAtals newAtlas = GlyphAtals();
+ newAtlas.altas = tex;
+ newAtlas.width = m_AtlasSize.x;
+ newAtlas.height = m_AtlasSize.y;
+ newAtlas.index = m_Atlases.size();
+ newAtlas.cursor = Internal::Vector2(m_AtlasMargin, m_AtlasMargin);
+
+ m_Atlases.push_back(newAtlas);
+ atlas = &m_Atlases[m_Atlases.size() - 1];
+
+ if (iter != m_AtlasCache.end())
+ m_AtlasCache.erase(pixelSize);
+ m_AtlasCache.insert(std::pair<int, GlyphAtals*>(pixelSize, atlas));
+ }
+ else
+ {
+ atlas = iter->second;
+ }
+ Assert(atlas);
+ return atlas;
+}
+
+Texture* Font::CreateAtlas()
+{
+ TextureSetting setting;
+ setting.filterMode = ETextureFilterMode::Linear;
+ setting.wrapMode = ETextureWrapMode::Clamp;
+ setting.format = ETextureFormat::R8;
+ setting.type = ETextureType::TEX_2D;
+ setting.keepImageData = false;
+ Texture* tex = new Texture(setting, m_AtlasSize.x, m_AtlasSize.y);
+ return tex;
+}
+
+bool Font::HasEnoughSpace(GlyphAtals* atlas, Internal::Vector2 preferSize)
+{
+ if (atlas == NULL)
+ return false;
+ Internal::Vector2 space;
+ space.x = atlas->width - atlas->cursor.x - m_AtlasMargin;
+ space.y = atlas->height - atlas->cursor.y - m_AtlasMargin;
+ if (space.x > preferSize.x && space.y > preferSize.y)
+ return true;
+ if (space.y - atlas->rowHeight - m_GlyphPadding - m_AtlasMargin > preferSize.y)
+ return true;
+ return false;
+}
+
+Character GetCharacter(character::Codepoint Codepoint, int pixelSize)
+{
+ return Character();
+}
+
+void TextHelper::print_glyph(unsigned char* glyph, int width, int height)
+{
+ for (int r = 0; r < height; ++r)
+ {
+ for (int c = 0; c < width; ++c)
+ {
+ unsigned char ch = glyph[c + r * width];
+ printf("%c", ch == 0 ? ' ' : '+');
+ }
+ printf("\n");
+ }
+}
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);
+
+}
diff --git a/Runtime/GUI/TextGenerator.cpp b/Runtime/GUI/TextGenerator.cpp
deleted file mode 100644
index d2cd20c..0000000
--- a/Runtime/GUI/TextGenerator.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-#include "freetype.h"
-#include "TextGenerator.h"
-#include "../Math/Math.h"
-#include "Runtime/Debug/Log.h"
-#include "Runtime/Utilities/Assert.h"
-#include "Runtime/Graphics/ImageData.h"
-
-using namespace character;
-
-//https://unicode-table.com/en/#cjk-unified-ideographs-extension-a
-//https://learnopengl.com/In-Practice/Text-Rendering
-//https://www.zhihu.com/question/294660079
-//https://baike.baidu.com/item/%E5%9F%BA%E6%9C%AC%E5%A4%9A%E6%96%87%E7%A7%8D%E5%B9%B3%E9%9D%A2/10788078
-//https://stackoverflow.com/questions/27331819/whats-the-difference-between-a-character-a-code-point-a-glyph-and-a-grapheme
-
-void TextGenerator::Setup(TextGeneratingSettings settings)
-{
- m_AtlasMargin = settings.margin;
- m_GlyphPadding = settings.padding;
- m_AtlasSize = settings.atlasSize;
-
- if (FT_Init_FreeType(&m_FTLibrary))
- {
- return;
- }
-
- if (FT_New_Face(m_FTLibrary, "Resources/Font/Deng.ttf", 0, &m_FTFace))
- {
- return;
- }
-}
-
-character::Hash TextGenerator::GetHash(Codepoint codepoint, int pixelSize)
-{
- character::Hash hash;
- hash.codepoint = codepoint;
- hash.size = pixelSize;
- return hash;
-}
-
-const Character* TextGenerator::GetCharacter(character::Codepoint codepoint, int pixelSize)
-{
- character::Hash hash = GetHash(codepoint, pixelSize);
- auto iter = m_Characters.find(hash);
- if (iter == m_Characters.end())
- {
- RenderCharacter(codepoint, pixelSize);
- iter = m_Characters.find(hash);
- }
- Assert(iter != m_Characters.end());
- return &iter->second;
-}
-
-void TextGenerator::RenderCharacters(character::Codepoint* codepoint, int n, int pixelSize)
-{
- for (int i = 0; i < n; ++i)
- {
- RenderCharacter(codepoint[i], pixelSize);
- }
-}
-
-void TextGenerator::RenderCharacter(character::Codepoint codepoint, int pixelSize)
-{
- character::Hash hash = GetHash(codepoint, pixelSize);
- if (m_Characters.count(hash) != 0)
- return;
- FT_Set_Pixel_Sizes(m_FTFace, 0, pixelSize);
- if (FT_Load_Char(m_FTFace, codepoint, FT_LOAD_RENDER))
- {
- return;
- }
-
- int w = m_FTFace->glyph->bitmap.width;
- int h = m_FTFace->glyph->bitmap.rows;
-
- //TextHelper::print_glyph(m_FTFace->glyph->bitmap.buffer, w, h);
-
- GlyphAtals* atlas = RequestAtlas(pixelSize, Internal::Vector2(w, h));
- Assert(atlas);
-
- Internal::Rect rect = GetRenderChartAndMove(atlas, Internal::Vector2(w, h));
-
- try
- {
- atlas->altas->UpdateSubImage(rect, EPixelFormat::PixelFormat_R, EPixelElementType::PixelType_UNSIGNED_BYTE, m_FTFace->glyph->bitmap.buffer);
- }
- catch (TextureException& e)
- {
- std::string error = e.what();
- error = "Render Character Error: " + error;
- log_error(e.what());
- return;
- }
-
- Character character;
- character.atlas = atlas->index;
- character.position = rect;
- character.bearing = Internal::Vector2(m_FTFace->glyph->bitmap_left, m_FTFace->glyph->bitmap_top);
- character.advance = m_FTFace->glyph->advance.x * 1/64.f;
-
- m_Characters.insert(std::pair<character::Hash, Character>(hash, character));
-}
-
-const GlyphAtals* TextGenerator::GetGlyphAtlas(int index)
-{
- if (index >= m_Atlases.size())
- return NULL;
- return &m_Atlases[index];
-}
-
-Internal::Rect TextGenerator::GetRenderChartAndMove(GlyphAtals* atlas, Internal::Vector2 preferSize)
-{
- Internal::Rect rect;
- Internal::Vector2 space;
- space.x = atlas->width - atlas->cursor.x - m_AtlasMargin;
- space.y = atlas->height - atlas->cursor.y - m_AtlasMargin;
- if (space.x > preferSize.x && space.y > preferSize.y)
- {
- rect.x = atlas->cursor.x;
- rect.y = atlas->cursor.y;
- rect.width = preferSize.x;
- rect.height = preferSize.y;
- atlas->cursor.x += rect.width + m_GlyphPadding;
- atlas->rowHeight = max(atlas->rowHeight, preferSize.y);
- }
- else if (space.y - atlas->rowHeight - m_GlyphPadding - m_AtlasMargin > preferSize.y)
- {
- rect.x = m_AtlasMargin;
- rect.y = atlas->cursor.y + m_GlyphPadding + atlas->rowHeight;
- rect.width = preferSize.x;
- rect.height = preferSize.y;
- atlas->cursor.x = m_AtlasMargin;
- atlas->cursor.y += atlas->rowHeight + m_GlyphPadding;
- atlas->rowHeight = rect.height;
- }
- else
- {
- Assert(false);
- }
- return rect;
-}
-
-GlyphAtals* TextGenerator::RequestAtlas(int pixelSize, Internal::Vector2 preferSize)
-{
- GlyphAtals* atlas = NULL;
- auto iter = m_AtlasCache.find(pixelSize);
- if (iter == m_AtlasCache.end() || !HasEnoughSpace(iter->second, preferSize))
- {
- Texture* tex = CreateAtlas();
- GlyphAtals newAtlas = GlyphAtals();
- newAtlas.altas = tex;
- newAtlas.width = m_AtlasSize.x;
- newAtlas.height = m_AtlasSize.y;
- newAtlas.index = m_Atlases.size();
- newAtlas.cursor = Internal::Vector2(m_AtlasMargin, m_AtlasMargin);
-
- m_Atlases.push_back(newAtlas);
- atlas = &m_Atlases[m_Atlases.size() - 1];
-
- if (iter != m_AtlasCache.end())
- m_AtlasCache.erase(pixelSize);
- m_AtlasCache.insert(std::pair<int, GlyphAtals*>(pixelSize, atlas));
- }
- else
- {
- atlas = iter->second;
- }
- Assert(atlas);
- return atlas;
-}
-
-Texture* TextGenerator::CreateAtlas()
-{
- TextureSetting setting;
- setting.filterMode = ETextureFilterMode::Linear;
- setting.wrapMode = ETextureWrapMode::Clamp;
- setting.format = ETextureFormat::R8;
- setting.type = ETextureType::TEX_2D;
- setting.keepImageData = false;
- Texture* tex = new Texture(setting, m_AtlasSize.x, m_AtlasSize.y);
- return tex;
-}
-
-bool TextGenerator::HasEnoughSpace(GlyphAtals* atlas, Internal::Vector2 preferSize)
-{
- if (atlas == NULL)
- return false;
- Internal::Vector2 space;
- space.x = atlas->width - atlas->cursor.x - m_AtlasMargin;
- space.y = atlas->height - atlas->cursor.y - m_AtlasMargin;
- if (space.x > preferSize.x && space.y > preferSize.y)
- return true;
- if (space.y - atlas->rowHeight - m_GlyphPadding - m_AtlasMargin > preferSize.y)
- return true;
- return false;
-}
-
-Character GetCharacter(character::Codepoint Codepoint, int pixelSize)
-{
- return Character();
-}
-
-void TextHelper::print_glyph(unsigned char* glyph, int width, int height)
-{
- for (int r = 0; r < height; ++r)
- {
- for (int c = 0; c < width; ++c)
- {
- unsigned char ch = glyph[c + r * width];
- printf("%c", ch == 0 ? ' ' : '+');
- }
- printf("\n");
- }
-}
diff --git a/Runtime/GUI/TextGenerator.h b/Runtime/GUI/TextGenerator.h
deleted file mode 100644
index ef78eb6..0000000
--- a/Runtime/GUI/TextGenerator.h
+++ /dev/null
@@ -1,109 +0,0 @@
-#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的尺寸
- 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);
-
-}