summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Data/Scripts/Editor/AssetBrowser.lua4
-rw-r--r--Runtime/GUI/Font.h3
-rw-r--r--Runtime/GUI/TextMeshGenerator.cpp89
-rw-r--r--Runtime/GUI/TextMeshGenerator.h14
-rw-r--r--Runtime/GUI/UITextMesh.cpp25
-rw-r--r--Runtime/GUI/UITextMesh.h33
-rw-r--r--Runtime/Graphics/Color.h6
-rw-r--r--Runtime/Scripting/GUI/Font.bind.cpp8
-rw-r--r--Runtime/Utilities/UtilMacros.h3
9 files changed, 163 insertions, 22 deletions
diff --git a/Data/Scripts/Editor/AssetBrowser.lua b/Data/Scripts/Editor/AssetBrowser.lua
index c1542c2..d975934 100644
--- a/Data/Scripts/Editor/AssetBrowser.lua
+++ b/Data/Scripts/Editor/AssetBrowser.lua
@@ -39,6 +39,10 @@ AssetBrowser.OnGUI = function(self)
--Engine.Rendering.SetTexture("gamelab_main_tex", tex)
--Engine.Rendering.DrawUIQuad({0, 0, 200, 200})
_G["default_font"]:GetCharacters("你好世界!\nHello,World!\nProject Window Properties", 12)
+
+ Engine.Rendering.SetVector2("gamelab_ui_position", {0, 100})
+ _G["default_font"]:GetCharacters("结构体A中包含了4字节长度的int一个", 12)
+
--Engine.Rendering.DrawUI9Slicing(1, {25, 25}, {25, 25}, {80, 80}, {400, 50} )
end
diff --git a/Runtime/GUI/Font.h b/Runtime/GUI/Font.h
index cd546af..565fafc 100644
--- a/Runtime/GUI/Font.h
+++ b/Runtime/GUI/Font.h
@@ -31,10 +31,13 @@ namespace character
union Hash {
unsigned int hashCode;
+#pragma pack(1)
struct {
Unicode codepoint;
unsigned short size;//С
};
+#pragma pack()
+
bool operator==(const Hash &other) const
{
return codepoint == other.codepoint && size == other.size;
diff --git a/Runtime/GUI/TextMeshGenerator.cpp b/Runtime/GUI/TextMeshGenerator.cpp
index 98d3b09..b4c8c4d 100644
--- a/Runtime/GUI/TextMeshGenerator.cpp
+++ b/Runtime/GUI/TextMeshGenerator.cpp
@@ -1,10 +1,89 @@
#include "TextMeshGenerator.h"
-UITextMesh* TextMeshGenerator::GetTextMesh(const UnicodeString& str, Font* font, int pixelSize, int lineHeight, Color32 col32, ETextAnchor anchor, ETextAlignment alignment, bool wordwrap, float preferred)
+// һϣֵ
+static uint32_t GetStrHash(const UnicodeString& str)
{
- for (int i = 0; i < m_TextMeshes.size(); ++i)
- {
- UITextMesh* tm = m_TextMeshes[i];
+ if (str.length == 0)
+ return 0;
- }
+ int len = str.length;
+ uint32_t hash = (uint32_t)len; // seed
+ size_t step = (len >> 5) + 1;
+ for (int l = len; l >= step; l -= step)
+ {
+ unsigned short unicode = str.str[l - 1];
+ unsigned char hicode = *((unsigned char*)&unicode);
+ unsigned char locode = *(((unsigned char*)&unicode) + 1);
+ hash = hash ^ ((hash << 5) + (hash >> 2) + hicode + locode);
+ }
+ return hash;
+}
+
+const UITextMesh* TextMeshGenerator::GetTextMesh(
+ const UnicodeString& str
+ , Font* font
+ , int pixelSize
+ , int lineHeight
+ , Color32 col32
+ , ETextAnchor anchor
+ , ETextAlignment alignment
+ , bool wordwrap
+ , float preferred
+){
+ uint32_t hash = GetStrHash(str);
+ UITextMeshList* tm = NULL;
+ bool hasHash = m_TextMeshes.count(hash);
+ if (hasHash)
+ {
+ tm = m_TextMeshes[hash];
+ while (tm)
+ {
+ UITextMesh* mesh = tm->mesh;
+ if (mesh->GetFont() != font
+ || mesh->GetPixelSize() != pixelSize
+ || mesh->GetLineHeight() != lineHeight
+ || mesh->GetAnchor() != anchor
+ || mesh->GetAlignment() != alignment
+ || mesh->GetWordwrap() != wordwrap
+ || mesh->GetPreferred() != preferred
+ || mesh->GetColor() != col32
+ ){
+ tm = tm->next;
+ continue;
+ }
+ const UnicodeString& content = mesh->GetContent();
+ if (content.length != str.length)
+ {
+ tm = tm->next;
+ continue;
+ }
+ if (memcmp(str.str, content.str, sizeof(character::Unicode) * str.length) == 0)
+ {
+ return tm->mesh;
+ }
+ tm = tm->next;
+ }
+ }
+ tm = new UITextMeshList();
+ try {
+ tm->mesh = new UITextMesh(str, font, pixelSize, lineHeight, col32, anchor, alignment, wordwrap, preferred);
+ log_info("Text", "New UITextMesh");
+ }
+ catch(TextMeshException& e)
+ {
+ delete tm;
+ throw;
+ }
+ if (hasHash)
+ {
+ UITextMeshList* list = m_TextMeshes[hash];
+ tm->next = list;
+ m_TextMeshes[hash] = tm;
+ }
+ else
+ {
+ tm->next = NULL;
+ m_TextMeshes.insert(std::pair<uint32_t, UITextMeshList*>(hash, tm));
+ }
+ return tm->mesh;
}
diff --git a/Runtime/GUI/TextMeshGenerator.h b/Runtime/GUI/TextMeshGenerator.h
index dd4f1d9..815f4c4 100644
--- a/Runtime/GUI/TextMeshGenerator.h
+++ b/Runtime/GUI/TextMeshGenerator.h
@@ -3,9 +3,11 @@
#include "UITextMesh.h"
#include "Runtime/Utilities/IIncrementalTask.h"
#include "Font.h"
+#include "Runtime/Debug/Log.h"
#include <vector>
+#include <unordered_map>
-// collect unused text mesh gradually
+// 𲽻ճûõtextmesh
class GraduallyReleaseTextMesh : public IIncrementalTask
{
public:
@@ -21,14 +23,18 @@ public:
};
+struct UITextMeshList {
+ UITextMesh* mesh;
+ UITextMeshList* next;
+};
+
class TextMeshGenerator : public Singleton<TextMeshGenerator>
{
public:
- UITextMesh* GetTextMesh(const UnicodeString& str, Font* font, int pixelSize, int lineHeight, Color32 col32, ETextAnchor anchor, ETextAlignment alignment, bool wordwrap, float preferred);
+ const UITextMesh* GetTextMesh(const UnicodeString& str, Font* font, int pixelSize, int lineHeight, Color32 col32, ETextAnchor anchor, ETextAlignment alignment, bool wordwrap, float preferred);
private:
- std::vector<UITextMesh*> m_TextMeshes;
-
+ std::unordered_map<uint32_t, UITextMeshList*> m_TextMeshes;
};
#define g_TextMeshGenerator (*TextMeshGenerator::Instance()) \ No newline at end of file
diff --git a/Runtime/GUI/UITextMesh.cpp b/Runtime/GUI/UITextMesh.cpp
index 24aff47..23c0a9c 100644
--- a/Runtime/GUI/UITextMesh.cpp
+++ b/Runtime/GUI/UITextMesh.cpp
@@ -33,7 +33,6 @@ struct TextInfo {
int line; // 0ʼ
};
-static unordered_map<unsigned int, vector<TextInfo>> s_TextInfos;
InitializeStaticVariables([]() {
VertexAttributeDescriptor POSITION = VertexAttributeDescriptor(0, 2, VertexAttrFormat_Float, sizeof(TextMeshVBOLayout));
@@ -63,6 +62,20 @@ UITextMesh::UITextMesh(
, bool wordwrap // Զ
, float preferred // ԶС
){
+ m_Font = font;
+ m_PixelSize = pixelSize;
+ m_LineHeight = lineHeight;
+ m_Color = color32;
+ m_Alignment = alignment;
+ m_Anchor = anchor;
+ m_Wordwrap = wordwrap;
+ m_Preferred = preferred;
+ m_Content.length = str.length;
+ m_Content.str = (character::Unicode*)malloc(str.length * sizeof(character::Unicode));
+ memcpy(m_Content.str, str.str, str.length * sizeof(character::Unicode));
+
+ // ¼ıatlas
+ static unordered_map<unsigned int, vector<TextInfo>> s_TextInfos;
s_TextInfos.clear();
// ¼ıÿеij
@@ -76,9 +89,9 @@ UITextMesh::UITextMesh(
InvokeWhenLeave([]() {
s_LineWidths.clear();
s_LineOffsets.clear();
+ s_TextInfos.clear();
});
- m_Font = font;
const Vector2 atlasSize = font->GetAtlasSize();
//-----------------------------------------------------------------
@@ -149,8 +162,10 @@ UITextMesh::UITextMesh(
textRegion.y = (line + 1) * lineHeight;
- if (s_TextInfos.size() == 0)
- return;
+ if (s_TextInfos.size() == 0)
+ {
+ return;
+ }
Vector2i textOffset;
Vector2 halfRegion = Vector2(textRegion.x/ 2.f, textRegion.y / 2.f);
@@ -240,7 +255,7 @@ UITextMesh::UITextMesh(
WipeGLError();
}
-void UITextMesh::Draw()
+void UITextMesh::Draw() const
{
for (auto subText : m_VBOs)
{
diff --git a/Runtime/GUI/UITextMesh.h b/Runtime/GUI/UITextMesh.h
index c298cb0..505b390 100644
--- a/Runtime/GUI/UITextMesh.h
+++ b/Runtime/GUI/UITextMesh.h
@@ -34,15 +34,34 @@ namespace TextHelper
class UITextMesh
{
public:
- UITextMesh(const UnicodeString& str, Font* font, int pixelSize, int lineHeight, Color32 color32 = Color32::white, ETextAnchor anchor = TextAnchor_UpperLeft, ETextAlignment alignment = TextAlignment_Left, bool wordwrap = false, float preferred = 0)/*throw TextMeshException*/;
+ void Draw() const;
- ~UITextMesh();
+ GET(const Font*, Font, m_Font);
+ GET(int, PixelSize, m_PixelSize);
+ GET(int, LineHeight, m_LineHeight);
+ GET(Color32, Color, m_Color);
+ GET(ETextAlignment, Alignment, m_Alignment);
+ GET(ETextAnchor, Anchor, m_Anchor);
+ GET(bool, Wordwrap, m_Wordwrap);
+ GET(float, Preferred, m_Preferred);
+ GET(const UnicodeString&, Content, m_Content);
- void Draw();
+private:
+ friend class TextMeshGenerator;
-private:
- unsigned long long m_NotUniqueHash;
- Font* m_Font;
- std::unordered_map<int/*IndexOfAtlas*/, VertexBuffer*> m_VBOs;
+ UITextMesh(const UnicodeString& str, Font* font, int pixelSize, int lineHeight, Color32 color32 = Color32::white, ETextAnchor anchor = TextAnchor_UpperLeft, ETextAlignment alignment = TextAlignment_Left, bool wordwrap = false, float preferred = 0)/*throw TextMeshException*/;
+ ~UITextMesh();
+
+ std::unordered_map<int, VertexBuffer*> m_VBOs;
+
+ Font* m_Font;
+ UnicodeString m_Content;
+ int m_PixelSize;
+ int m_LineHeight;
+ Color32 m_Color;
+ ETextAlignment m_Alignment;
+ ETextAnchor m_Anchor;
+ bool m_Wordwrap;
+ float m_Preferred;
}; \ No newline at end of file
diff --git a/Runtime/Graphics/Color.h b/Runtime/Graphics/Color.h
index 41ca2a4..043590b 100644
--- a/Runtime/Graphics/Color.h
+++ b/Runtime/Graphics/Color.h
@@ -40,6 +40,12 @@ namespace Internal
this->b = b;
this->a = a;
}
+
+ bool operator !=(const Color32& col)
+ {
+ return !(r == col.r && g == col.g && b == col.b && a == col.a);
+ }
+
unsigned char r, g, b, a;
static const Color32 white;
diff --git a/Runtime/Scripting/GUI/Font.bind.cpp b/Runtime/Scripting/GUI/Font.bind.cpp
index 7d7e3f2..0570df0 100644
--- a/Runtime/Scripting/GUI/Font.bind.cpp
+++ b/Runtime/Scripting/GUI/Font.bind.cpp
@@ -7,6 +7,8 @@
#include "Runtime/Utilities/StaticInitiator.h"
#include "Runtime/GUI/UITextMesh.h"
#include "Runtime/Math/Math.h"
+#include "Runtime/GUI/TextMeshGenerator.h"
+#include "Runtime/Utilities/AutoInvoke.h"
static std::vector<character::Unicode>* s_Codepoints;
@@ -102,6 +104,10 @@ LUA_BIND_IMPL_METHOD(Font, _GetCharacters)
int encoding = state.GetValue<int>(6, EEncoding::Encoding_UTF8);
s_Codepoints->clear();
+ InvokeWhenLeave([]() {
+ s_Codepoints->clear();
+ });
+
if (encoding == EEncoding::Encoding_UTF8)
{
while (*buf != 0) {
@@ -137,7 +143,7 @@ LUA_BIND_IMPL_METHOD(Font, _GetCharacters)
WipeGLError();
- UITextMesh* tm = new UITextMesh(str, self, size, size + 3, Color32::white, TextAnchor_UpperLeft, TextAlignment_Left, wordwrap, preferred);
+ const UITextMesh* tm = g_TextMeshGenerator.GetTextMesh(str, self, size, size + 3, Color32::white, TextAnchor_UpperLeft, TextAlignment_Left, wordwrap, preferred);
tm->Draw();
return 0;
diff --git a/Runtime/Utilities/UtilMacros.h b/Runtime/Utilities/UtilMacros.h
index 1941d7f..f48be5c 100644
--- a/Runtime/Utilities/UtilMacros.h
+++ b/Runtime/Utilities/UtilMacros.h
@@ -13,4 +13,7 @@
#define Mask(v) (1 << v)
+#define cast(T, v) \
+((T)(v))
+
#endif \ No newline at end of file