From 545cf49642dabb11bea5016184cac1f3915f70a4 Mon Sep 17 00:00:00 2001 From: "@clasher113" Date: Sat, 24 Aug 2024 22:40:18 +0300 Subject: [PATCH 1/7] block model "x" preview fix --- src/graphics/render/BlocksPreview.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphics/render/BlocksPreview.cpp b/src/graphics/render/BlocksPreview.cpp index bf6b2a10..619266bd 100644 --- a/src/graphics/render/BlocksPreview.cpp +++ b/src/graphics/render/BlocksPreview.cpp @@ -102,6 +102,7 @@ std::unique_ptr BlocksPreview::draw( } break; case BlockModel::xsprite: { + shader->uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset)); glm::vec3 right = glm::normalize(glm::vec3(1.f, 0.f, -1.f)); batch->sprite( right*float(size)*0.43f+glm::vec3(0, size*0.4f, 0), From f2b9d0620aad052574aafaf1a8f804b2fa07588c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 28 Aug 2024 11:59:35 +0300 Subject: [PATCH 2/7] add cameras.get(int) overload --- res/scripts/classes.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/res/scripts/classes.lua b/res/scripts/classes.lua index 1c2b0cba..3c23fdc4 100644 --- a/res/scripts/classes.lua +++ b/res/scripts/classes.lua @@ -22,6 +22,9 @@ local Camera = {__index={ local wrappers = {} cameras.get = function(name) + if type(name) == 'number' then + return cameras.get(cameras.name(name)) + end local wrapper = wrappers[name] if wrapper ~= nil then return wrapper From f8d0a4f4c7ec63709c309d90d71b601d078a6090 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 29 Aug 2024 13:01:32 +0300 Subject: [PATCH 3/7] add util::crop_utf8 (stringutil) --- src/util/stringutil.cpp | 13 +++++++++++++ src/util/stringutil.hpp | 15 +++++++++++++++ test/util/stringutil.cpp | 10 ++++++++++ 3 files changed, 38 insertions(+) create mode 100644 test/util/stringutil.cpp diff --git a/src/util/stringutil.cpp b/src/util/stringutil.cpp index c494a759..8f3bddd8 100644 --- a/src/util/stringutil.cpp +++ b/src/util/stringutil.cpp @@ -141,6 +141,19 @@ extern uint32_t util::decode_utf8(uint& size, const char* chr) { return code; } +size_t util::crop_utf8(std::string_view s, size_t maxSize) { + size_t pos = 0; + uint size = 0; + while (pos < s.length()) { + decode_utf8(size, &s.at(pos)); + if (pos + size > maxSize) { + return pos; + } + pos += size; + } + return pos; +} + std::string util::wstr2str_utf8(const std::wstring& ws) { std::vector chars; char buffer[4]; diff --git a/src/util/stringutil.hpp b/src/util/stringutil.hpp index 54a0a5e2..14ba9432 100644 --- a/src/util/stringutil.hpp +++ b/src/util/stringutil.hpp @@ -17,8 +17,23 @@ namespace util { uint encode_utf8(uint32_t c, ubyte* bytes); uint32_t decode_utf8(uint& size, const char* bytes); + + /// @brief Encode raw wstring to UTF-8 + /// @param ws source raw wstring + /// @return new UTF-8 encoded string std::string wstr2str_utf8(const std::wstring& ws); + + /// @brief Decode UTF + /// @param s source encoded string + /// @return new raw decoded string std::wstring str2wstr_utf8(const std::string& s); + + /// @brief Calculated length of UTF-8 encoded string that fits into maxSize + /// @param s source UTF-8 encoded string view + /// @param maxSize max encoded string length after crop + /// @return cropped string size (less or equal to maxSize) + size_t crop_utf8(std::string_view s, size_t maxSize); + bool is_integer(const std::string& text); bool is_integer(const std::wstring& text); bool is_valid_filename(const std::wstring& name); diff --git a/test/util/stringutil.cpp b/test/util/stringutil.cpp new file mode 100644 index 00000000..d2172380 --- /dev/null +++ b/test/util/stringutil.cpp @@ -0,0 +1,10 @@ +#include "util/stringutil.hpp" + +#include + +TEST(stringutil, crop_utf8) { + // Project source files must be UTF-8 encoded + std::string str = "пример"; + str = str.substr(0, util::crop_utf8(str, 7)); + EXPECT_EQ(str, "при"); +} From c5811e36f9f55dd4946f42f0a1d2f02d19f4c9b9 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 29 Aug 2024 13:32:56 +0300 Subject: [PATCH 4/7] update .github/workflows/windows.yml --- .github/workflows/windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 6af90077..60ad52a6 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -42,7 +42,7 @@ jobs: cp -r build/* packaged/ working-directory: ${{ github.workspace }} - name: Run tests - run: ctest --test-dir build + run: ctest --output-on-failure --test-dir build - uses: actions/upload-artifact@v2 with: name: Windows-Build From 5045ffb923e5fc9faf7d73233721e04ff379a19e Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 29 Aug 2024 13:47:18 +0300 Subject: [PATCH 5/7] fix stringutil test --- test/util/stringutil.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/util/stringutil.cpp b/test/util/stringutil.cpp index d2172380..ed6e2b00 100644 --- a/test/util/stringutil.cpp +++ b/test/util/stringutil.cpp @@ -4,7 +4,7 @@ TEST(stringutil, crop_utf8) { // Project source files must be UTF-8 encoded - std::string str = "пример"; + std::string str = u8"пример"; str = str.substr(0, util::crop_utf8(str, 7)); - EXPECT_EQ(str, "при"); + EXPECT_EQ(str, u8"при"); } From 96941cb7072520dd18f0f6af2ef314df853e70ed Mon Sep 17 00:00:00 2001 From: MihailRis Date: Thu, 29 Aug 2024 15:09:27 +0300 Subject: [PATCH 6/7] fix utf-8 decoder & add u32string functions --- src/util/stringutil.cpp | 61 +++++++++++++++++++++++++++------------- src/util/stringutil.hpp | 14 +++++++-- test/util/stringutil.cpp | 7 +++++ 3 files changed, 60 insertions(+), 22 deletions(-) diff --git a/src/util/stringutil.cpp b/src/util/stringutil.cpp index 8f3bddd8..97ca4786 100644 --- a/src/util/stringutil.cpp +++ b/src/util/stringutil.cpp @@ -116,20 +116,22 @@ const utf_t utf[] = { }; inline uint utf8_len(ubyte cp) { - uint len = 0; - for (const utf_t* u = utf; u->mask; ++u) { - if ((cp >= u->beg) && (cp <= u->end)) { - break; - } - ++len; + if ((cp & 0x80) == 0) { + return 1; } - if (len > 4) /* Out of bounds */ - throw std::runtime_error("utf-8 decode error"); - - return len; + if ((cp & 0xE0) == 0xC0) { + return 2; + } + if ((cp & 0xF0) == 0xE0) { + return 3; + } + if ((cp & 0xF8) == 0xF0) { + return 4; + } + return 0; } -extern uint32_t util::decode_utf8(uint& size, const char* chr) { +uint32_t util::decode_utf8(uint& size, const char* chr) { size = utf8_len(*chr); int shift = utf[0].bits_stored * (size - 1); uint32_t code = (*chr++ & utf[size].mask) << shift; @@ -145,7 +147,7 @@ size_t util::crop_utf8(std::string_view s, size_t maxSize) { size_t pos = 0; uint size = 0; while (pos < s.length()) { - decode_utf8(size, &s.at(pos)); + decode_utf8(size, s.data() + pos); if (pos + size > maxSize) { return pos; } @@ -154,11 +156,13 @@ size_t util::crop_utf8(std::string_view s, size_t maxSize) { return pos; } -std::string util::wstr2str_utf8(const std::wstring& ws) { +template +std::string xstr2str_utf8(const std::basic_string& xs) { std::vector chars; - char buffer[4]; - for (wchar_t wc : ws) { - uint size = encode_utf8((uint)wc, (ubyte*)buffer); + ubyte buffer[4]; + for (C xc : xs) { + uint size = util::encode_utf8( + static_cast(xc), buffer); for (uint i = 0; i < size; i++) { chars.push_back(buffer[i]); } @@ -166,15 +170,32 @@ std::string util::wstr2str_utf8(const std::wstring& ws) { return std::string(chars.data(), chars.size()); } -std::wstring util::str2wstr_utf8(const std::string& s) { - std::vector chars; +std::string util::wstr2str_utf8(const std::wstring& ws) { + return xstr2str_utf8(ws); +} + +std::string util::u32str2str_utf8(const std::u32string& ws) { + return xstr2str_utf8(ws); +} + +template +std::basic_string str2xstr_utf8(const std::string& s) { + std::vector chars; size_t pos = 0; uint size = 0; while (pos < s.length()) { - chars.push_back(decode_utf8(size, &s.at(pos))); + chars.push_back(util::decode_utf8(size, &s.at(pos))); pos += size; } - return std::wstring(chars.data(), chars.size()); + return std::basic_string(chars.data(), chars.size()); +} + +std::wstring util::str2wstr_utf8(const std::string& s) { + return str2xstr_utf8(s); +} + +std::u32string util::str2u32str_utf8(const std::string& s) { + return str2xstr_utf8(s); } bool util::is_integer(const std::string& text) { diff --git a/src/util/stringutil.hpp b/src/util/stringutil.hpp index 14ba9432..38e7cf89 100644 --- a/src/util/stringutil.hpp +++ b/src/util/stringutil.hpp @@ -23,11 +23,21 @@ namespace util { /// @return new UTF-8 encoded string std::string wstr2str_utf8(const std::wstring& ws); - /// @brief Decode UTF + /// @brief Decode UTF-8 string /// @param s source encoded string - /// @return new raw decoded string + /// @return new raw decoded wstring std::wstring str2wstr_utf8(const std::string& s); + /// @brief Encode raw u32string to UTF-8 + /// @param ws source raw wstring + /// @return new UTF-8 encoded string + std::string u32str2str_utf8(const std::u32string& ws); + + /// @brief Decode UTF-8 string + /// @param s source encoded string + /// @return new raw decoded u32string + std::u32string str2u32str_utf8(const std::string& s); + /// @brief Calculated length of UTF-8 encoded string that fits into maxSize /// @param s source UTF-8 encoded string view /// @param maxSize max encoded string length after crop diff --git a/test/util/stringutil.cpp b/test/util/stringutil.cpp index ed6e2b00..7bd0f85c 100644 --- a/test/util/stringutil.cpp +++ b/test/util/stringutil.cpp @@ -8,3 +8,10 @@ TEST(stringutil, crop_utf8) { str = str.substr(0, util::crop_utf8(str, 7)); EXPECT_EQ(str, u8"при"); } + +TEST(stringutil, utf8) { + std::string str = u8"テキストデモ"; + auto u32str = util::str2u32str_utf8(str); + std::string str2 = util::u32str2str_utf8(u32str); + EXPECT_EQ(str, str2); +} From 8ddfa48339c87153a15bfafb2a04e0bcf4289273 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 30 Aug 2024 06:13:58 +0300 Subject: [PATCH 7/7] fix skeleton:get_texture --- src/logic/scripting/lua/lib__skeleton.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/logic/scripting/lua/lib__skeleton.cpp b/src/logic/scripting/lua/lib__skeleton.cpp index 9c6295d2..1e0365b7 100644 --- a/src/logic/scripting/lua/lib__skeleton.cpp +++ b/src/logic/scripting/lua/lib__skeleton.cpp @@ -62,8 +62,6 @@ static int l_set_matrix(lua::State* L) { static int l_get_texture(lua::State* L) { if (auto entity = get_entity(L, 1)) { auto& skeleton = entity->getSkeleton(); - skeleton.textures[lua::require_string(L, 2)] = - lua::require_string(L, 3); const auto& found = skeleton.textures.find(lua::require_string(L, 2)); if (found != skeleton.textures.end()) { return lua::pushstring(L, found->second);