diff --git a/CMakeLists.txt b/CMakeLists.txt
index 09b1200..977912c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -96,7 +96,7 @@ add_library(Lina::VG ALIAS ${PROJECT_NAME})
target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include)
target_compile_definitions(${PROJECT_NAME} PUBLIC LINAVG_VERSION_MAJOR=1)
target_compile_definitions(${PROJECT_NAME} PUBLIC LINAVG_VERSION_MINOR=4)
-target_compile_definitions(${PROJECT_NAME} PUBLIC LINAVG_VERSION_PATCH=1)
+target_compile_definitions(${PROJECT_NAME} PUBLIC LINAVG_VERSION_PATCH=2)
#--------------------------------------------------------------------
# Subdirectories & linking
diff --git a/Examples/include/Backends/GL/GLBackend.hpp b/Examples/include/Backends/GL/GLBackend.hpp
index 920bab6..1d841f3 100644
--- a/Examples/include/Backends/GL/GLBackend.hpp
+++ b/Examples/include/Backends/GL/GLBackend.hpp
@@ -61,12 +61,12 @@ namespace LinaVG::Backend
ShaderData m_sdfTextShaderData;
ShaderData m_simpleTextShaderData;
float m_proj[4][4] = {0};
- char* m_defaultVtxShader = nullptr;
- char* m_defaultFragShader = nullptr;
- char* m_roundedGradientFragShader = nullptr;
- char* m_texturedFragShader = nullptr;
- char* m_sdfTextFragShader = nullptr;
- char* m_simpleTextFragShader = nullptr;
+ const char* m_defaultVtxShader = nullptr;
+ const char* m_defaultFragShader = nullptr;
+ const char* m_roundedGradientFragShader = nullptr;
+ const char* m_texturedFragShader = nullptr;
+ const char* m_sdfTextFragShader = nullptr;
+ const char* m_simpleTextFragShader = nullptr;
bool m_skipDraw = false;
};
diff --git a/include/Core/Drawer.hpp b/include/Core/Drawer.hpp
index 8efb4f1..a9ea210 100644
--- a/include/Core/Drawer.hpp
+++ b/include/Core/Drawer.hpp
@@ -469,7 +469,7 @@ namespace LinaVG
///
/// For processing UTf8 texts.
///
- uint32_t GetNextUnicodeChar(const char* text, uint32_t& byteCount);
+ std::vector GetUtf8Codepoints(const char* str);
#endif
}; // namespace Internal
diff --git a/include/Core/Math.hpp b/include/Core/Math.hpp
index 8ff4683..d65f1ff 100644
--- a/include/Core/Math.hpp
+++ b/include/Core/Math.hpp
@@ -82,10 +82,10 @@ namespace LinaVG
///
static Vec2 GetPolygonCentroidFast(Vec2* points, int size);
- static bool Math::IsEqual(const Vec2& v1, const Vec2& v2);
- static bool Math::IsEqualMarg(const Vec2& v1, const Vec2& v2, float err = 0.001f);
- static bool Math::IsEqualMarg(float f1, float f2, float err = 0.001f);
- static bool Math::IsEqual(const Vec4& v1, const Vec4& v2);
+ static bool IsEqual(const Vec2& v1, const Vec2& v2);
+ static bool IsEqualMarg(const Vec2& v1, const Vec2& v2, float err = 0.001f);
+ static bool IsEqualMarg(float f1, float f2, float err = 0.001f);
+ static bool IsEqual(const Vec4& v1, const Vec4& v2);
static float Abs(float f);
static float Clamp(float f, float min, float max);
static int Clamp(int i, int min, int max);
diff --git a/src/Core/Drawer.cpp b/src/Core/Drawer.cpp
index 13185a2..c2bb15f 100644
--- a/src/Core/Drawer.cpp
+++ b/src/Core/Drawer.cpp
@@ -3176,50 +3176,6 @@ namespace LinaVG
return offset;
}
- uint32_t GetNextUnicodeChar(const char* p, uint32_t& byteCount)
- {
- uint32_t codepoint = 0;
- if ((*p & 0b10000000) == 0b00000000)
- {
- // 1-byte character (ASCII)
- auto ch = static_cast(*p);
- byteCount = 1;
- codepoint = static_cast(ch);
- }
- else if ((*p & 0b11100000) == 0b11000000)
- {
- // 2-byte character
- codepoint = ((*p & 0b00011111) << 6) |
- (*(p + 1) & 0b00111111);
- byteCount = 2;
- }
- else if ((*p & 0b11110000) == 0b11100000)
- {
- // 3-byte character
- codepoint = ((*p & 0b00001111) << 12) |
- ((*(p + 1) & 0b00111111) << 6) |
- (*(p + 2) & 0b00111111);
- byteCount = 3;
- }
- else if ((*p & 0b11111000) == 0b11110000)
- {
- // 4-byte character
- codepoint = ((*p & 0b00000111) << 18) |
- ((*(p + 1) & 0b00111111) << 12) |
- ((*(p + 2) & 0b00111111) << 6) |
- (*(p + 3) & 0b00111111);
- byteCount = 4;
- }
- else
- {
- // Invalid UTF-8 sequence
- if (Config.errorCallback)
- Config.errorCallback("LinaVG -> Invalid UTF-8 sequence!");
- }
-
- return codepoint;
- }
-
void DrawText(DrawBuffer* buf, LinaVGFont* font, const char* text, const Vec2& position, const Vec2& offset, const Vec4Grad& color, float spacing, bool isGradient, float scale)
{
const uint8_t* c;
@@ -3314,19 +3270,12 @@ namespace LinaVG
if (font->m_supportsUnicode)
{
- const uint8_t* c = (const uint8_t*)text;
- for (const char* p = text; *p; p++)
- {
- uint32_t byteCount = 0;
- uint32_t character = GetNextUnicodeChar(p, byteCount);
-
- if (byteCount == 0)
- return;
+ auto codepoints = GetUtf8Codepoints(text);
- auto ch = font->m_characterGlyphs[character];
- drawChar(ch, character);
-
- p += byteCount - 1;
+ for (auto cp : codepoints)
+ {
+ auto ch = font->m_characterGlyphs[cp];
+ drawChar(ch, cp);
}
}
else
@@ -3340,6 +3289,39 @@ namespace LinaVG
}
}
+ std::vector GetUtf8Codepoints(const char* str)
+ {
+ std::vector codepoints;
+ const char* p = str;
+ while (*p)
+ {
+ int32_t codepoint = 0;
+ unsigned char c = *p;
+ if (c < 0x80)
+ { // 1-byte sequence
+ codepoint = c;
+ p += 1;
+ }
+ else if (c < 0xE0)
+ { // 2-byte sequence
+ codepoint = ((p[0] & 0x1F) << 6) | (p[1] & 0x3F);
+ p += 2;
+ }
+ else if (c < 0xF0)
+ { // 3-byte sequence
+ codepoint = ((p[0] & 0x0F) << 12) | ((p[1] & 0x3F) << 6) | (p[2] & 0x3F);
+ p += 3;
+ }
+ else
+ { // 4-byte sequence
+ codepoint = ((p[0] & 0x07) << 18) | ((p[1] & 0x3F) << 12) | ((p[2] & 0x3F) << 6) | (p[3] & 0x3F);
+ p += 4;
+ }
+ codepoints.push_back(codepoint);
+ }
+ return codepoints;
+ }
+
Vec2 CalcTextSize(const char* text, LinaVGFont* font, float scale, float spacing, float sdfThickness)
{
float maxCharacterHeight = 0.0f;
@@ -3355,18 +3337,12 @@ namespace LinaVG
if (font->m_supportsUnicode)
{
- for (const char* p = text; *p; p++)
- {
- uint32_t byteCount = 0;
- uint32_t character = GetNextUnicodeChar(p, byteCount);
+ auto codepoints = GetUtf8Codepoints(text);
- if (byteCount == 0)
- return Vec2(0, 0);
-
- auto ch = font->m_characterGlyphs[character];
- calcSizeChar(ch, character);
-
- p += byteCount - 1;
+ for (auto cp : codepoints)
+ {
+ auto ch = font->m_characterGlyphs[cp];
+ calcSizeChar(ch, cp);
}
}
else