diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-08-18 17:24:54 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-08-18 17:24:54 +0200 |
commit | b51ee8b029b0b9f719f01bbdd21a329e65d4d238 (patch) | |
tree | 52e79f7d4582023148fe24a494606e4792e419fa /servers/text_server.cpp | |
parent | a2a1ed1aac1cd7caa418a0a35a936f289b886a41 (diff) | |
parent | 5d3fcc57669c4104a85c79327f7c2662a0d191a3 (diff) | |
download | redot-engine-b51ee8b029b0b9f719f01bbdd21a329e65d4d238.tar.gz |
Merge pull request #80650 from bruvzg/comp_char_fix
[TextServer] Fix system font fallback and caret/selection behavior for composite characters.
Diffstat (limited to 'servers/text_server.cpp')
-rw-r--r-- | servers/text_server.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/servers/text_server.cpp b/servers/text_server.cpp index 07ad14f120..470814ca59 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -448,6 +448,11 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("shaped_text_next_grapheme_pos", "shaped", "pos"), &TextServer::shaped_text_next_grapheme_pos); ClassDB::bind_method(D_METHOD("shaped_text_prev_grapheme_pos", "shaped", "pos"), &TextServer::shaped_text_prev_grapheme_pos); + ClassDB::bind_method(D_METHOD("shaped_text_get_character_breaks", "shaped"), &TextServer::shaped_text_get_character_breaks); + ClassDB::bind_method(D_METHOD("shaped_text_next_character_pos", "shaped", "pos"), &TextServer::shaped_text_next_character_pos); + ClassDB::bind_method(D_METHOD("shaped_text_prev_character_pos", "shaped", "pos"), &TextServer::shaped_text_prev_character_pos); + ClassDB::bind_method(D_METHOD("shaped_text_closest_character_pos", "shaped", "pos"), &TextServer::shaped_text_closest_character_pos); + ClassDB::bind_method(D_METHOD("shaped_text_draw", "shaped", "canvas", "pos", "clip_l", "clip_r", "color"), &TextServer::shaped_text_draw, DEFVAL(-1), DEFVAL(-1), DEFVAL(Color(1, 1, 1))); ClassDB::bind_method(D_METHOD("shaped_text_draw_outline", "shaped", "canvas", "pos", "clip_l", "clip_r", "outline_size", "color"), &TextServer::shaped_text_draw_outline, DEFVAL(-1), DEFVAL(-1), DEFVAL(1), DEFVAL(Color(1, 1, 1))); @@ -458,6 +463,7 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("percent_sign", "language"), &TextServer::percent_sign, DEFVAL("")); ClassDB::bind_method(D_METHOD("string_get_word_breaks", "string", "language", "chars_per_line"), &TextServer::string_get_word_breaks, DEFVAL(""), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("string_get_character_breaks", "string", "language"), &TextServer::string_get_character_breaks, DEFVAL("")); ClassDB::bind_method(D_METHOD("is_confusable", "string", "dict"), &TextServer::is_confusable); ClassDB::bind_method(D_METHOD("spoof_check", "string"), &TextServer::spoof_check); @@ -1424,6 +1430,57 @@ int64_t TextServer::shaped_text_prev_grapheme_pos(const RID &p_shaped, int64_t p return p_pos; } +int64_t TextServer::shaped_text_prev_character_pos(const RID &p_shaped, int64_t p_pos) const { + const PackedInt32Array &chars = shaped_text_get_character_breaks(p_shaped); + int64_t prev = 0; + for (const int32_t &E : chars) { + if (E >= p_pos) { + return prev; + } + prev = E; + } + return prev; +} + +int64_t TextServer::shaped_text_next_character_pos(const RID &p_shaped, int64_t p_pos) const { + const PackedInt32Array &chars = shaped_text_get_character_breaks(p_shaped); + int64_t prev = 0; + for (const int32_t &E : chars) { + if (E > p_pos) { + return E; + } + prev = E; + } + return prev; +} + +int64_t TextServer::shaped_text_closest_character_pos(const RID &p_shaped, int64_t p_pos) const { + const PackedInt32Array &chars = shaped_text_get_character_breaks(p_shaped); + int64_t prev = 0; + for (const int32_t &E : chars) { + if (E == p_pos) { + return E; + } else if (E > p_pos) { + if ((E - p_pos) < (p_pos - prev)) { + return E; + } else { + return prev; + } + } + prev = E; + } + return prev; +} + +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; + } + return ret; +} + void TextServer::shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, const Color &p_color) const { TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped); bool hex_codes = shaped_text_get_preserve_control(p_shaped) || shaped_text_get_preserve_invalid(p_shaped); |