diff options
author | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2023-08-19 11:19:09 +0300 |
---|---|---|
committer | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2023-08-19 11:49:34 +0300 |
commit | 07d859de25572052250512e344b88e5641bedd00 (patch) | |
tree | 1b15fe93689326aad447b08d50c5cabe211b06fb | |
parent | b51ee8b029b0b9f719f01bbdd21a329e65d4d238 (diff) | |
download | redot-engine-07d859de25572052250512e344b88e5641bedd00.tar.gz |
[TextServer] Fix issues with character breaks, add more tests.
-rw-r--r-- | modules/text_server_adv/text_server_adv.cpp | 7 | ||||
-rw-r--r-- | modules/text_server_fb/text_server_fb.cpp | 12 | ||||
-rw-r--r-- | servers/text_server.cpp | 8 | ||||
-rw-r--r-- | tests/servers/test_text_server.h | 80 |
4 files changed, 97 insertions, 10 deletions
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 7855f75877..804a16423d 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -4864,8 +4864,7 @@ void TextServerAdvanced::_update_chars(ShapedTextDataAdvanced *p_sd) const { while (i + 1 < spans.size() && language == spans[i + 1].language) { i++; } - int r_end = MIN(spans[i].end - p_sd->start, p_sd->text.size()); - + int r_end = MIN(spans[i].end - p_sd->start, p_sd->text.length()); UBreakIterator *bi = ubrk_open(UBRK_CHARACTER, (language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale().ascii().get_data() : language.ascii().get_data(), data + _convert_pos_inv(p_sd, r_start), _convert_pos_inv(p_sd, r_end - r_start), &err); if (U_SUCCESS(err)) { while (ubrk_next(bi) != UBRK_DONE) { @@ -4877,9 +4876,9 @@ void TextServerAdvanced::_update_chars(ShapedTextDataAdvanced *p_sd) const { } ubrk_close(bi); } else { - for (int j = r_start; j <= r_end; j++) { + for (int j = r_start; j < r_end; j++) { if (prev != j) { - p_sd->chars.push_back(j + p_sd->start); + p_sd->chars.push_back(j + 1 + p_sd->start); } prev = j; } diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index bf7cc776c0..4976c70b3b 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -4084,11 +4084,17 @@ PackedInt32Array TextServerFallback::_shaped_text_get_character_breaks(const RID ERR_FAIL_COND_V(!sd, PackedInt32Array()); MutexLock lock(sd->mutex); + if (!sd->valid) { + const_cast<TextServerFallback *>(this)->_shaped_text_shape(p_shaped); + } PackedInt32Array ret; - ret.resize(sd->end - sd->start); - for (int i = sd->start; i < sd->end; i++) { - ret.write[i] = i; + int size = sd->end - sd->start; + if (size > 0) { + ret.resize(size); + for (int i = 0; i < size; i++) { + ret.write[i] = i + 1 + sd->start; + } } return ret; } diff --git a/servers/text_server.cpp b/servers/text_server.cpp index 470814ca59..28c6b20f7b 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -1474,9 +1474,11 @@ int64_t TextServer::shaped_text_closest_character_pos(const RID &p_shaped, int64 PackedInt32Array TextServer::string_get_character_breaks(const String &p_string, const String &p_language) const { PackedInt32Array ret; - ret.resize(p_string.size()); - for (int i = 0; i <= p_string.size(); i++) { - ret.write[i] = i; + if (!p_string.is_empty()) { + ret.resize(p_string.size() - 1); + for (int i = 0; i < p_string.size() - 1; i++) { + ret.write[i] = i + 1; + } } return ret; } diff --git a/tests/servers/test_text_server.h b/tests/servers/test_text_server.h index 75e97d0384..eef5b850ca 100644 --- a/tests/servers/test_text_server.h +++ b/tests/servers/test_text_server.h @@ -175,10 +175,13 @@ TEST_SUITE("[TextServer]") { RID font1 = ts->create_font(); ts->font_set_data_ptr(font1, _font_NotoSans_Regular, _font_NotoSans_Regular_size); + ts->font_set_allow_system_fallback(font1, false); RID font2 = ts->create_font(); ts->font_set_data_ptr(font2, _font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size); + ts->font_set_allow_system_fallback(font2, false); RID font3 = ts->create_font(); ts->font_set_data_ptr(font3, _font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size); + ts->font_set_allow_system_fallback(font3, false); Array font; font.push_back(font1); @@ -186,6 +189,83 @@ TEST_SUITE("[TextServer]") { font.push_back(font3); { + RID ctx = ts->create_shaped_text(); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); + ts->shaped_text_add_string(ctx, U"Xtest", font, 10); + ts->shaped_text_add_string(ctx, U"xs", font, 10); + RID sctx = ts->shaped_text_substr(ctx, 1, 5); + CHECK_FALSE_MESSAGE(sctx == RID(), "Creating substring text buffer failed."); + PackedInt32Array sbrk = ts->shaped_text_get_character_breaks(sctx); + CHECK_FALSE_MESSAGE(sbrk.size() != 5, "Invalid substring char breaks number."); + if (sbrk.size() == 5) { + CHECK_FALSE_MESSAGE(sbrk[0] != 2, "Invalid substring char break position."); + CHECK_FALSE_MESSAGE(sbrk[1] != 3, "Invalid substring char break position."); + CHECK_FALSE_MESSAGE(sbrk[2] != 4, "Invalid substring char break position."); + CHECK_FALSE_MESSAGE(sbrk[3] != 5, "Invalid substring char break position."); + CHECK_FALSE_MESSAGE(sbrk[4] != 6, "Invalid substring char break position."); + } + PackedInt32Array fbrk = ts->shaped_text_get_character_breaks(ctx); + CHECK_FALSE_MESSAGE(fbrk.size() != 7, "Invalid char breaks number."); + if (fbrk.size() == 7) { + CHECK_FALSE_MESSAGE(fbrk[0] != 1, "Invalid char break position."); + CHECK_FALSE_MESSAGE(fbrk[1] != 2, "Invalid char break position."); + CHECK_FALSE_MESSAGE(fbrk[2] != 3, "Invalid char break position."); + CHECK_FALSE_MESSAGE(fbrk[3] != 4, "Invalid char break position."); + CHECK_FALSE_MESSAGE(fbrk[4] != 5, "Invalid char break position."); + CHECK_FALSE_MESSAGE(fbrk[5] != 6, "Invalid char break position."); + CHECK_FALSE_MESSAGE(fbrk[6] != 7, "Invalid char break position."); + } + PackedInt32Array rbrk = ts->string_get_character_breaks(U"Xtestxs"); + CHECK_FALSE_MESSAGE(rbrk.size() != 7, "Invalid char breaks number."); + if (rbrk.size() == 7) { + CHECK_FALSE_MESSAGE(rbrk[0] != 1, "Invalid char break position."); + CHECK_FALSE_MESSAGE(rbrk[1] != 2, "Invalid char break position."); + CHECK_FALSE_MESSAGE(rbrk[2] != 3, "Invalid char break position."); + CHECK_FALSE_MESSAGE(rbrk[3] != 4, "Invalid char break position."); + CHECK_FALSE_MESSAGE(rbrk[4] != 5, "Invalid char break position."); + CHECK_FALSE_MESSAGE(rbrk[5] != 6, "Invalid char break position."); + CHECK_FALSE_MESSAGE(rbrk[6] != 7, "Invalid char break position."); + } + + ts->free_rid(sctx); + ts->free_rid(ctx); + } + + if (ts->has_feature(TextServer::FEATURE_BREAK_ITERATORS)) { + RID ctx = ts->create_shaped_text(); + CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); + ts->shaped_text_add_string(ctx, U"X❤️🔥", font, 10); + ts->shaped_text_add_string(ctx, U"xs", font, 10); + RID sctx = ts->shaped_text_substr(ctx, 1, 5); + CHECK_FALSE_MESSAGE(sctx == RID(), "Creating substring text buffer failed."); + PackedInt32Array sbrk = ts->shaped_text_get_character_breaks(sctx); + CHECK_FALSE_MESSAGE(sbrk.size() != 2, "Invalid substring char breaks number."); + if (sbrk.size() == 2) { + CHECK_FALSE_MESSAGE(sbrk[0] != 5, "Invalid substring char break position."); + CHECK_FALSE_MESSAGE(sbrk[1] != 6, "Invalid substring char break position."); + } + PackedInt32Array fbrk = ts->shaped_text_get_character_breaks(ctx); + CHECK_FALSE_MESSAGE(fbrk.size() != 4, "Invalid char breaks number."); + if (fbrk.size() == 4) { + CHECK_FALSE_MESSAGE(fbrk[0] != 1, "Invalid char break position."); + CHECK_FALSE_MESSAGE(fbrk[1] != 5, "Invalid char break position."); + CHECK_FALSE_MESSAGE(fbrk[2] != 6, "Invalid char break position."); + CHECK_FALSE_MESSAGE(fbrk[3] != 7, "Invalid char break position."); + } + PackedInt32Array rbrk = ts->string_get_character_breaks(U"X❤️🔥xs"); + CHECK_FALSE_MESSAGE(rbrk.size() != 4, "Invalid char breaks number."); + if (rbrk.size() == 4) { + CHECK_FALSE_MESSAGE(rbrk[0] != 1, "Invalid char break position."); + CHECK_FALSE_MESSAGE(rbrk[1] != 5, "Invalid char break position."); + CHECK_FALSE_MESSAGE(rbrk[2] != 6, "Invalid char break position."); + CHECK_FALSE_MESSAGE(rbrk[3] != 7, "Invalid char break position."); + } + + ts->free_rid(sctx); + ts->free_rid(ctx); + } + + { String test = U"Test test long text long text\n"; RID ctx = ts->create_shaped_text(); CHECK_FALSE_MESSAGE(ctx == RID(), "Creating text buffer failed."); |