From a116801ec76fa2159191609d0dbef666d92385a4 Mon Sep 17 00:00:00 2001
From: bruvzg <7645683+bruvzg@users.noreply.github.com>
Date: Mon, 15 Apr 2024 22:14:41 +0300
Subject: [PATCH] Improve TextEdit/LineEdit word selection.
---
doc/classes/TextServer.xml | 1 +
doc/classes/TextServerExtension.xml | 1 +
.../4.2-stable.expected | 7 ++++
servers/text/text_server_extension.cpp | 8 ++--
servers/text/text_server_extension.h | 4 +-
servers/text_server.compat.inc | 41 +++++++++++++++++++
servers/text_server.cpp | 13 +++---
servers/text_server.h | 7 +++-
8 files changed, 70 insertions(+), 12 deletions(-)
create mode 100644 servers/text_server.compat.inc
diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml
index c0cd7f79e7e..c30e83a85d6 100644
--- a/doc/classes/TextServer.xml
+++ b/doc/classes/TextServer.xml
@@ -1505,6 +1505,7 @@
+
Breaks text into words and returns array of character ranges. Use [param grapheme_flags] to set what characters are used for breaking (see [enum GraphemeFlag]).
diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml
index 06a0daece6d..94fd69c8635 100644
--- a/doc/classes/TextServerExtension.xml
+++ b/doc/classes/TextServerExtension.xml
@@ -1664,6 +1664,7 @@
+
[b]Optional.[/b]
Breaks text into words and returns array of character ranges. Use [param grapheme_flags] to set what characters are used for breaking (see [enum TextServer.GraphemeFlag]).
diff --git a/misc/extension_api_validation/4.2-stable.expected b/misc/extension_api_validation/4.2-stable.expected
index de60e5114c9..4706ed37f0c 100644
--- a/misc/extension_api_validation/4.2-stable.expected
+++ b/misc/extension_api_validation/4.2-stable.expected
@@ -308,3 +308,10 @@ Validate extension JSON: Error: Field 'classes/XRServer/methods/remove_tracker/a
All trackers now have an XRTracker base, and the XRServer uses the XRTracker type.
+
+GH-90732
+--------
+Validate extension JSON: Error: Field 'classes/TextServer/methods/shaped_text_get_word_breaks/arguments': size changed value in new API, from 2 to 3.
+Validate extension JSON: Error: Field 'classes/TextServerExtension/methods/_shaped_text_get_word_breaks/arguments': size changed value in new API, from 2 to 3.
+
+Added optional argument. Compatibility method registered.
diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp
index 53e1d119fd2..8f9797805f8 100644
--- a/servers/text/text_server_extension.cpp
+++ b/servers/text/text_server_extension.cpp
@@ -285,7 +285,7 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(_shaped_text_get_line_breaks_adv, "shaped", "width", "start", "once", "break_flags");
GDVIRTUAL_BIND(_shaped_text_get_line_breaks, "shaped", "width", "start", "break_flags");
- GDVIRTUAL_BIND(_shaped_text_get_word_breaks, "shaped", "grapheme_flags");
+ GDVIRTUAL_BIND(_shaped_text_get_word_breaks, "shaped", "grapheme_flags", "skip_grapheme_flags");
GDVIRTUAL_BIND(_shaped_text_get_trim_pos, "shaped");
GDVIRTUAL_BIND(_shaped_text_get_ellipsis_pos, "shaped");
@@ -1256,12 +1256,12 @@ PackedInt32Array TextServerExtension::shaped_text_get_line_breaks(const RID &p_s
return TextServer::shaped_text_get_line_breaks(p_shaped, p_width, p_start, p_break_flags);
}
-PackedInt32Array TextServerExtension::shaped_text_get_word_breaks(const RID &p_shaped, BitField p_grapheme_flags) const {
+PackedInt32Array TextServerExtension::shaped_text_get_word_breaks(const RID &p_shaped, BitField p_grapheme_flags, BitField p_skip_grapheme_flags) const {
PackedInt32Array ret;
- if (GDVIRTUAL_CALL(_shaped_text_get_word_breaks, p_shaped, p_grapheme_flags, ret)) {
+ if (GDVIRTUAL_CALL(_shaped_text_get_word_breaks, p_shaped, p_grapheme_flags, p_skip_grapheme_flags, ret)) {
return ret;
}
- return TextServer::shaped_text_get_word_breaks(p_shaped, p_grapheme_flags);
+ return TextServer::shaped_text_get_word_breaks(p_shaped, p_grapheme_flags, p_skip_grapheme_flags);
}
int64_t TextServerExtension::shaped_text_get_trim_pos(const RID &p_shaped) const {
diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h
index 53d30abee42..f447f0f5bdd 100644
--- a/servers/text/text_server_extension.h
+++ b/servers/text/text_server_extension.h
@@ -472,10 +472,10 @@ public:
virtual PackedInt32Array shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start = 0, bool p_once = true, BitField p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
virtual PackedInt32Array shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start = 0, BitField p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
- virtual PackedInt32Array shaped_text_get_word_breaks(const RID &p_shaped, BitField p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const override;
+ virtual PackedInt32Array shaped_text_get_word_breaks(const RID &p_shaped, BitField p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION, BitField p_skip_grapheme_flags = GRAPHEME_IS_VIRTUAL) const override;
GDVIRTUAL5RC(PackedInt32Array, _shaped_text_get_line_breaks_adv, RID, const PackedFloat32Array &, int64_t, bool, BitField);
GDVIRTUAL4RC(PackedInt32Array, _shaped_text_get_line_breaks, RID, double, int64_t, BitField);
- GDVIRTUAL2RC(PackedInt32Array, _shaped_text_get_word_breaks, RID, BitField);
+ GDVIRTUAL3RC(PackedInt32Array, _shaped_text_get_word_breaks, RID, BitField, BitField);
virtual int64_t shaped_text_get_trim_pos(const RID &p_shaped) const override;
virtual int64_t shaped_text_get_ellipsis_pos(const RID &p_shaped) const override;
diff --git a/servers/text_server.compat.inc b/servers/text_server.compat.inc
new file mode 100644
index 00000000000..0ff35721a3f
--- /dev/null
+++ b/servers/text_server.compat.inc
@@ -0,0 +1,41 @@
+/**************************************************************************/
+/* text_server.compat.inc */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef DISABLE_DEPRECATED
+
+PackedInt32Array TextServer::_shaped_text_get_word_breaks_bind_compat_90732(const RID &p_shaped, BitField p_grapheme_flags) const {
+ return shaped_text_get_word_breaks(p_shaped, p_grapheme_flags, 0);
+}
+
+void TextServer::_bind_compatibility_methods() {
+ ClassDB::bind_compatibility_method(D_METHOD("shaped_text_get_word_breaks", "shaped", "grapheme_flags"), &TextServer::_shaped_text_get_word_breaks_bind_compat_90732, DEFVAL(GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION));
+}
+
+#endif
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index fac9e32d01b..562f2df411c 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -29,6 +29,8 @@
/**************************************************************************/
#include "servers/text_server.h"
+#include "text_server.compat.inc"
+
#include "core/variant/typed_array.h"
#include "servers/rendering_server.h"
@@ -435,7 +437,7 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("shaped_text_get_range", "shaped"), &TextServer::shaped_text_get_range);
ClassDB::bind_method(D_METHOD("shaped_text_get_line_breaks_adv", "shaped", "width", "start", "once", "break_flags"), &TextServer::shaped_text_get_line_breaks_adv, DEFVAL(0), DEFVAL(true), DEFVAL(BREAK_MANDATORY | BREAK_WORD_BOUND));
ClassDB::bind_method(D_METHOD("shaped_text_get_line_breaks", "shaped", "width", "start", "break_flags"), &TextServer::shaped_text_get_line_breaks, DEFVAL(0), DEFVAL(BREAK_MANDATORY | BREAK_WORD_BOUND));
- ClassDB::bind_method(D_METHOD("shaped_text_get_word_breaks", "shaped", "grapheme_flags"), &TextServer::shaped_text_get_word_breaks, DEFVAL(GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION));
+ ClassDB::bind_method(D_METHOD("shaped_text_get_word_breaks", "shaped", "grapheme_flags", "skip_grapheme_flags"), &TextServer::shaped_text_get_word_breaks, DEFVAL(GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION), DEFVAL(GRAPHEME_IS_VIRTUAL));
ClassDB::bind_method(D_METHOD("shaped_text_get_trim_pos", "shaped"), &TextServer::shaped_text_get_trim_pos);
ClassDB::bind_method(D_METHOD("shaped_text_get_ellipsis_pos", "shaped"), &TextServer::shaped_text_get_ellipsis_pos);
@@ -1094,7 +1096,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, do
return lines;
}
-PackedInt32Array TextServer::shaped_text_get_word_breaks(const RID &p_shaped, BitField p_grapheme_flags) const {
+PackedInt32Array TextServer::shaped_text_get_word_breaks(const RID &p_shaped, BitField p_grapheme_flags, BitField p_skip_grapheme_flags) const {
PackedInt32Array words;
const_cast(this)->shaped_text_update_justification_ops(p_shaped);
@@ -1107,10 +1109,11 @@ PackedInt32Array TextServer::shaped_text_get_word_breaks(const RID &p_shaped, Bi
for (int i = 0; i < l_size; i++) {
if (l_gl[i].count > 0) {
- if ((l_gl[i].flags & p_grapheme_flags) != 0) {
- if (word_start != l_gl[i].start) {
+ if ((l_gl[i].flags & p_grapheme_flags) != 0 && (l_gl[i].flags & p_skip_grapheme_flags) == 0) {
+ int next = (i == 0) ? l_gl[i].start : l_gl[i - 1].end;
+ if (word_start < next) {
words.push_back(word_start);
- words.push_back(l_gl[i].start);
+ words.push_back(next);
}
word_start = l_gl[i].end;
}
diff --git a/servers/text_server.h b/servers/text_server.h
index 396d7ca8e5e..775dbb55086 100644
--- a/servers/text_server.h
+++ b/servers/text_server.h
@@ -226,6 +226,11 @@ protected:
static void _bind_methods();
+#ifndef DISABLE_DEPRECATED
+ PackedInt32Array _shaped_text_get_word_breaks_bind_compat_90732(const RID &p_shaped, BitField p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const;
+ static void _bind_compatibility_methods();
+#endif
+
public:
virtual bool has_feature(Feature p_feature) const = 0;
virtual String get_name() const = 0;
@@ -483,7 +488,7 @@ public:
virtual PackedInt32Array shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start = 0, bool p_once = true, BitField p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
virtual PackedInt32Array shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start = 0, BitField p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
- virtual PackedInt32Array shaped_text_get_word_breaks(const RID &p_shaped, BitField p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const;
+ virtual PackedInt32Array shaped_text_get_word_breaks(const RID &p_shaped, BitField p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION, BitField p_skip_grapheme_flags = GRAPHEME_IS_VIRTUAL) const;
virtual int64_t shaped_text_get_trim_pos(const RID &p_shaped) const = 0;
virtual int64_t shaped_text_get_ellipsis_pos(const RID &p_shaped) const = 0;