diff options
-rw-r--r-- | Runtime/GUI/Font.cpp | 89 | ||||
-rw-r--r-- | Runtime/GUI/Font.h | 2 | ||||
-rw-r--r-- | Runtime/GUI/UITextMesh.cpp | 19 | ||||
-rw-r--r-- | Runtime/Math/Rect.h | 7 |
4 files changed, 69 insertions, 48 deletions
diff --git a/Runtime/GUI/Font.cpp b/Runtime/GUI/Font.cpp index d669844..8a5acea 100644 --- a/Runtime/GUI/Font.cpp +++ b/Runtime/GUI/Font.cpp @@ -151,63 +151,70 @@ bool Font::RenderCharacter(character::Codepoint codepoint, int pixelSize) // bug: 发现有时候渲染的结果是FT_PIXEL_MODE_MONO(1-bits),试过不同的flags组合还是不对,最后手动转换为8-bits - //FT_Int32 flags = FT_LOAD_TARGET_NORMAL | FT_LOAD_FORCE_AUTOHINT;
FT_Int32 flags = FT_LOAD_RENDER;
if (FT_Load_Char(m_FTFace, codepoint, flags)) return false; + Character character; + int w = m_FTFace->glyph->bitmap.width; int h = m_FTFace->glyph->bitmap.rows; const unsigned char* pixels = m_FTFace->glyph->bitmap.buffer; - if (pixels == NULL) - return false; - - s_PixelBuffer.resize(w * h); - if (m_FTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) + if (pixels != NULL) // 非空格 { - // 1 bit monochrome
- int pitch = m_FTFace->glyph->bitmap.pitch;
- for (int y = 0; y < h; ++y)
- {
- for (int x = 0; x < w; ++x)
+ s_PixelBuffer.resize(w * h); + if (m_FTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) + { + // 1-bit monochrome
+ int pitch = m_FTFace->glyph->bitmap.pitch;
+ for (int y = 0; y < h; ++y)
{
- int index = x + y * w;
- s_PixelBuffer[index] = ((pixels[pitch * y + x / 8]) & (1 << (7 - x % 8))) ? 255 : 0;
+ for (int x = 0; x < w; ++x)
+ {
+ int index = x + y * w;
+ s_PixelBuffer[index] = ((pixels[pitch * y + x / 8]) & (1 << (7 - x % 8))) ? 255 : 0;
+ }
}
- }
- } - else if (m_FTFace->glyph->bitmap.pixel_mode) - { - // 8 bit grayscale
- memcpy(&s_PixelBuffer[0], pixels, s_SizePerPixel * w * h); - } + } + else if (m_FTFace->glyph->bitmap.pixel_mode) + { + // 8-bit grayscale
+ memcpy(&s_PixelBuffer[0], pixels, s_SizePerPixel * w * h); + } - //TextHelper::print_glyph(&s_PixelBuffer[0], w, h); + //TextHelper::print_glyph(&s_PixelBuffer[0], w, h); - GlyphAtals* atlas = RequestAtlas(pixelSize, Internal::Vector2(w, h)); - Assert(atlas); + GlyphAtals* atlas = RequestAtlas(pixelSize, Internal::Vector2(w, h)); + Assert(atlas); - Internal::Rect rect = GetRenderChartAndMove(atlas, Internal::Vector2(w, h)); + Internal::Rect rect = GetRenderChartAndMove(atlas, Internal::Vector2(w, h)); - try - { - atlas->altas->UpdateSubImage(rect, EPixelFormat::PixelFormat_R, EPixelElementType::PixelType_UNSIGNED_BYTE, &s_PixelBuffer[0]); - } - catch (TextureException& e) - { + try + { + atlas->altas->UpdateSubImage(rect, EPixelFormat::PixelFormat_R, EPixelElementType::PixelType_UNSIGNED_BYTE, &s_PixelBuffer[0]); + } + catch (TextureException& e) + { + s_PixelBuffer.clear(); + std::string error = e.what(); + error = "Render Character Error: " + error; + log_error(e.what()); + return false; + } s_PixelBuffer.clear(); - std::string error = e.what(); - error = "Render Character Error: " + error; - log_error(e.what()); - return false; - } - s_PixelBuffer.clear(); - Character character; - character.atlas = atlas->index; - character.position = rect; - character.bearing = Internal::Vector2(m_FTFace->glyph->bitmap_left, m_FTFace->glyph->bitmap_top); + character.atlas = atlas->index; + character.position = rect; + character.bearing = Internal::Vector2(m_FTFace->glyph->bitmap_left, m_FTFace->glyph->bitmap_top); + } + else // 空格 + { + character.atlas = FONT_NOT_IN_ATLAS_PLACEHOLDER; + character.position = Rect(0,0,0,0); + character.bearing = Vector2(0, 0); + } + character.advance = m_FTFace->glyph->advance.x * 1/64.f; m_Characters.insert(std::pair<character::Hash, Character>(hash, character)); @@ -260,6 +267,8 @@ GlyphAtals* Font::RequestAtlas(int pixelSize, Internal::Vector2 preferSize) auto iter = m_AtlasCache.find(pixelSize); if (iter == m_AtlasCache.end() || !HasEnoughSpace(iter->second, preferSize)) { + Assert(m_Atlases.size() < FONT_NOT_IN_ATLAS_PLACEHOLDER); + Texture* tex = CreateAtlas(); GlyphAtals newAtlas = GlyphAtals(); newAtlas.altas = tex; diff --git a/Runtime/GUI/Font.h b/Runtime/GUI/Font.h index 8e55395..067a364 100644 --- a/Runtime/GUI/Font.h +++ b/Runtime/GUI/Font.h @@ -93,6 +93,8 @@ enum EEncoding Encoding_UTF16, }; +#define FONT_NOT_IN_ATLAS_PLACEHOLDER (INT_MAX) + // 单个字体 class Font : public LuaBind::NativeClass<Font> { diff --git a/Runtime/GUI/UITextMesh.cpp b/Runtime/GUI/UITextMesh.cpp index 32dec3b..823335f 100644 --- a/Runtime/GUI/UITextMesh.cpp +++ b/Runtime/GUI/UITextMesh.cpp @@ -75,16 +75,19 @@ UITextMesh::UITextMesh(const UnicodeString& str, Font* font,int pixelSize, EText continue; unsigned int atlasIndex = ch->atlas; - TextInfo info; - info.ch = ch; - info.offset = offset; + if (atlasIndex != FONT_NOT_IN_ATLAS_PLACEHOLDER) //非空格 + { + TextInfo info; + info.ch = ch; + info.offset = offset; - auto list = s_TextInfos.find(atlasIndex); - if (list == s_TextInfos.end()) - s_TextInfos.insert(std::pair<unsigned int, vector<TextInfo>>(atlasIndex, vector<TextInfo>())); + auto list = s_TextInfos.find(atlasIndex); + if (list == s_TextInfos.end()) + s_TextInfos.insert(std::pair<unsigned int, vector<TextInfo>>(atlasIndex, vector<TextInfo>())); - vector<TextInfo>& v = s_TextInfos[atlasIndex]; - v.push_back(info); + vector<TextInfo>& v = s_TextInfos[atlasIndex]; + v.push_back(info); + } offset += ch->advance; } diff --git a/Runtime/Math/Rect.h b/Runtime/Math/Rect.h index 8e7dae6..21a803e 100644 --- a/Runtime/Math/Rect.h +++ b/Runtime/Math/Rect.h @@ -4,6 +4,13 @@ namespace Internal { struct Rect { + Rect(float x=0, float y = 0, float w = 0, float h = 0) + { + this->x = x; + this->y = y; + this->width = w; + this->height = h; + } float x, y, width, height; }; }
\ No newline at end of file |