summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2021-11-03 13:29:01 +0800
committerchai <chaifix@163.com>2021-11-03 13:29:01 +0800
commit4428d0ac933482274d09862fd984ac8ede681f7c (patch)
tree45704fd105a2e71cc1e5de64576f95ebb245b050
parent5cd2e2299f98065fa06c192df4dfb2c014b2b253 (diff)
*font space
-rw-r--r--Runtime/GUI/Font.cpp89
-rw-r--r--Runtime/GUI/Font.h2
-rw-r--r--Runtime/GUI/UITextMesh.cpp19
-rw-r--r--Runtime/Math/Rect.h7
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