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/TextGenerator.cpp | |
parent | 44d6c41e5e586572de08c72c358aed9100a30353 (diff) |
* TextGenerator -> Font
Diffstat (limited to 'Runtime/GUI/TextGenerator.cpp')
-rw-r--r-- | Runtime/GUI/TextGenerator.cpp | 214 |
1 files changed, 0 insertions, 214 deletions
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"); - } -} |