summaryrefslogtreecommitdiff
path: root/servers/text_server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/text_server.cpp')
-rw-r--r--servers/text_server.cpp36
1 files changed, 32 insertions, 4 deletions
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index 2303f27495..143cda985d 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -327,6 +327,9 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("font_remove_script_support_override", "font_rid", "script"), &TextServer::font_remove_script_support_override);
ClassDB::bind_method(D_METHOD("font_get_script_support_overrides", "font_rid"), &TextServer::font_get_script_support_overrides);
+ ClassDB::bind_method(D_METHOD("font_set_opentype_feature_overrides", "font_rid", "overrides"), &TextServer::font_set_opentype_feature_overrides);
+ ClassDB::bind_method(D_METHOD("font_get_opentype_feature_overrides", "font_rid"), &TextServer::font_get_opentype_feature_overrides);
+
ClassDB::bind_method(D_METHOD("font_supported_feature_list", "font_rid"), &TextServer::font_supported_feature_list);
ClassDB::bind_method(D_METHOD("font_supported_variation_list", "font_rid"), &TextServer::font_supported_variation_list);
@@ -989,9 +992,9 @@ Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start,
}
real_t char_adv = advance / (real_t)(glyphs[i].end - glyphs[i].start);
if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) {
- ranges.push_back(Vector2(off, off + char_adv * (start - glyphs[i].start)));
+ ranges.push_back(Vector2(off, off + char_adv * (glyphs[i].end - start)));
} else {
- ranges.push_back(Vector2(off + char_adv * (glyphs[i].end - start), off + advance));
+ ranges.push_back(Vector2(off + char_adv * (start - glyphs[i].start), off + advance));
}
}
// Selection range is within grapheme.
@@ -1099,6 +1102,31 @@ int TextServer::shaped_text_hit_test_position(RID p_shaped, float p_coords) cons
return glyphs[i].start;
}
}
+ // Ligature, handle mid-grapheme hit.
+ if (p_coords >= off && p_coords < off + advance && glyphs[i].end > glyphs[i].start + 1) {
+ int cnt = glyphs[i].end - glyphs[i].start;
+ real_t char_adv = advance / (real_t)(cnt);
+ real_t sub_off = off;
+ for (int j = 0; j < cnt; j++) {
+ // Place caret to the left of clicked sub-grapheme.
+ if (p_coords >= sub_off && p_coords < sub_off + char_adv / 2) {
+ if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) {
+ return glyphs[i].end - j;
+ } else {
+ return glyphs[i].start + j;
+ }
+ }
+ // Place caret to the right of clicked sub-grapheme.
+ if (p_coords >= sub_off + char_adv / 2 && p_coords < sub_off + char_adv) {
+ if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) {
+ return glyphs[i].start + (cnt - 1) - j;
+ } else {
+ return glyphs[i].end - (cnt - 1) + j;
+ }
+ }
+ sub_off += char_adv;
+ }
+ }
// Place caret to the left of clicked grapheme.
if (p_coords >= off && p_coords < off + advance / 2) {
if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) {