summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
authorbruvzg <7645683+bruvzg@users.noreply.github.com>2021-08-28 00:19:51 +0300
committerbruvzg <7645683+bruvzg@users.noreply.github.com>2021-10-01 15:13:29 +0300
commit0c0b5c84b06e64de6cab301994ac9cd1f845dd35 (patch)
tree9b0ea4d9718fe694b2b22d9e09a66b32db8c2cb9 /servers
parent06c1b40b84645b4460dd49d95694a7779d636f92 (diff)
Implement TextServer GDExtension interface, remove TextServer GDNative interface.
Diffstat (limited to 'servers')
-rw-r--r--servers/SCsub1
-rw-r--r--servers/register_server_types.cpp18
-rw-r--r--servers/rendering_server.cpp1
-rw-r--r--servers/text/SCsub5
-rw-r--r--servers/text/text_server_extension.cpp1281
-rw-r--r--servers/text/text_server_extension.h426
-rw-r--r--servers/text_server.cpp561
-rw-r--r--servers/text_server.h294
8 files changed, 2139 insertions, 448 deletions
diff --git a/servers/SCsub b/servers/SCsub
index 121990f2e1..76c11724d3 100644
--- a/servers/SCsub
+++ b/servers/SCsub
@@ -11,6 +11,7 @@ SConscript("physics_3d/SCsub")
SConscript("physics_2d/SCsub")
SConscript("rendering/SCsub")
SConscript("audio/SCsub")
+SConscript("text/SCsub")
lib = env.add_library("servers", env.servers_sources)
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 41c8b45113..d5eccce88e 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -70,6 +70,7 @@
#include "rendering/rendering_device_binds.h"
#include "rendering_server.h"
#include "servers/rendering/shader_types.h"
+#include "text/text_server_extension.h"
#include "text_server.h"
#include "xr/xr_interface.h"
#include "xr/xr_interface_extension.h"
@@ -107,15 +108,11 @@ static bool has_server_feature_callback(const String &p_feature) {
void preregister_server_types() {
shader_types = memnew(ShaderTypes);
- GLOBAL_DEF("internationalization/rendering/text_driver", "");
- String text_driver_options;
- for (int i = 0; i < TextServerManager::get_interface_count(); i++) {
- if (i > 0) {
- text_driver_options += ",";
- }
- text_driver_options += TextServerManager::get_interface_name(i);
- }
- ProjectSettings::get_singleton()->set_custom_property_info("internationalization/rendering/text_driver", PropertyInfo(Variant::STRING, "internationalization/rendering/text_driver", PROPERTY_HINT_ENUM, text_driver_options));
+ GDREGISTER_CLASS(TextServerManager);
+ GDREGISTER_VIRTUAL_CLASS(TextServer);
+ GDREGISTER_CLASS(TextServerExtension);
+
+ Engine::get_singleton()->add_singleton(Engine::Singleton("TextServerManager", TextServerManager::get_singleton(), "TextServerManager"));
}
void register_server_types() {
@@ -125,8 +122,6 @@ void register_server_types() {
GDREGISTER_VIRTUAL_CLASS(RenderingServer);
GDREGISTER_CLASS(AudioServer);
- GDREGISTER_CLASS(TextServerManager);
- GDREGISTER_VIRTUAL_CLASS(TextServer);
TextServer::initialize_hex_code_box_fonts();
GDREGISTER_VIRTUAL_CLASS(PhysicsServer2D);
@@ -255,7 +250,6 @@ void register_server_singletons() {
Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer3D", PhysicsServer3D::get_singleton(), "PhysicsServer3D"));
Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer2D", NavigationServer2D::get_singleton_mut(), "NavigationServer2D"));
Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationServer3D", NavigationServer3D::get_singleton_mut(), "NavigationServer3D"));
- Engine::get_singleton()->add_singleton(Engine::Singleton("TextServerManager", TextServerManager::get_singleton(), "TextServerManager"));
Engine::get_singleton()->add_singleton(Engine::Singleton("XRServer", XRServer::get_singleton(), "XRServer"));
Engine::get_singleton()->add_singleton(Engine::Singleton("CameraServer", CameraServer::get_singleton(), "CameraServer"));
}
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 1b10e4dcbe..58e99f0e91 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -2539,6 +2539,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("canvas_item_add_rect", "item", "rect", "color"), &RenderingServer::canvas_item_add_rect);
ClassDB::bind_method(D_METHOD("canvas_item_add_circle", "item", "pos", "radius", "color"), &RenderingServer::canvas_item_add_circle);
ClassDB::bind_method(D_METHOD("canvas_item_add_texture_rect", "item", "rect", "texture", "tile", "modulate", "transpose"), &RenderingServer::canvas_item_add_texture_rect, DEFVAL(false), DEFVAL(Color(1, 1, 1)), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("canvas_item_add_msdf_texture_rect_region", "item", "rect", "texture", "src_rect", "modulate", "outline_size", "px_range"), &RenderingServer::canvas_item_add_msdf_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(0), DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("canvas_item_add_texture_rect_region", "item", "rect", "texture", "src_rect", "modulate", "transpose", "clip_uv"), &RenderingServer::canvas_item_add_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(true));
ClassDB::bind_method(D_METHOD("canvas_item_add_nine_patch", "item", "rect", "source", "texture", "topleft", "bottomright", "x_axis_mode", "y_axis_mode", "draw_center", "modulate"), &RenderingServer::canvas_item_add_nine_patch, DEFVAL(NINE_PATCH_STRETCH), DEFVAL(NINE_PATCH_STRETCH), DEFVAL(true), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("canvas_item_add_primitive", "item", "points", "colors", "uvs", "texture", "width"), &RenderingServer::canvas_item_add_primitive, DEFVAL(1.0));
diff --git a/servers/text/SCsub b/servers/text/SCsub
new file mode 100644
index 0000000000..86681f9c74
--- /dev/null
+++ b/servers/text/SCsub
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+Import("env")
+
+env.add_source_files(env.servers_sources, "*.cpp")
diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp
new file mode 100644
index 0000000000..a44fee7c95
--- /dev/null
+++ b/servers/text/text_server_extension.cpp
@@ -0,0 +1,1281 @@
+/*************************************************************************/
+/* text_server_extension.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
+/* "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. */
+/*************************************************************************/
+
+#include "text_server_extension.h"
+
+void TextServerExtension::_bind_methods() {
+ GDVIRTUAL_BIND(_has_feature, "feature");
+ GDVIRTUAL_BIND(_get_name);
+ GDVIRTUAL_BIND(_get_features);
+
+ GDVIRTUAL_BIND(_free, "rid");
+ GDVIRTUAL_BIND(_has, "rid");
+ GDVIRTUAL_BIND(_load_support_data, "filename");
+
+ GDVIRTUAL_BIND(_get_support_data_filename);
+ GDVIRTUAL_BIND(_get_support_data_info);
+ GDVIRTUAL_BIND(_save_support_data, "filename");
+
+ GDVIRTUAL_BIND(_is_locale_right_to_left, "locale");
+
+ GDVIRTUAL_BIND(_name_to_tag, "name");
+ GDVIRTUAL_BIND(_tag_to_name, "tag");
+
+ /* Font interface */
+
+ GDVIRTUAL_BIND(_create_font);
+
+ GDVIRTUAL_BIND(_font_set_data, "font_rid", "data");
+ GDVIRTUAL_BIND(_font_set_data_ptr, "font_rid", "data_ptr", "data_size");
+
+ GDVIRTUAL_BIND(_font_set_antialiased, "font_rid", "antialiased");
+ GDVIRTUAL_BIND(_font_is_antialiased, "font_rid");
+
+ GDVIRTUAL_BIND(_font_set_multichannel_signed_distance_field, "font_rid", "msdf");
+ GDVIRTUAL_BIND(_font_is_multichannel_signed_distance_field, "font_rid");
+
+ GDVIRTUAL_BIND(_font_set_msdf_pixel_range, "font_rid", "msdf_pixel_range");
+ GDVIRTUAL_BIND(_font_get_msdf_pixel_range, "font_rid");
+
+ GDVIRTUAL_BIND(_font_set_msdf_size, "font_rid", "msdf_size");
+ GDVIRTUAL_BIND(_font_get_msdf_size, "font_rid");
+
+ GDVIRTUAL_BIND(_font_set_fixed_size, "font_rid", "fixed_size");
+ GDVIRTUAL_BIND(_font_get_fixed_size, "font_rid");
+
+ GDVIRTUAL_BIND(_font_set_force_autohinter, "font_rid", "force_autohinter");
+ GDVIRTUAL_BIND(_font_is_force_autohinter, "font_rid");
+
+ GDVIRTUAL_BIND(_font_set_hinting, "font_rid", "hinting");
+ GDVIRTUAL_BIND(_font_get_hinting, "font_rid");
+
+ GDVIRTUAL_BIND(_font_set_variation_coordinates, "font_rid", "variation_coordinates");
+ GDVIRTUAL_BIND(_font_get_variation_coordinates, "font_rid");
+
+ GDVIRTUAL_BIND(_font_set_oversampling, "font_rid", "oversampling");
+ GDVIRTUAL_BIND(_font_get_oversampling, "font_rid");
+
+ GDVIRTUAL_BIND(_font_get_size_cache_list, "font_rid");
+ GDVIRTUAL_BIND(_font_clear_size_cache, "font_rid");
+ GDVIRTUAL_BIND(_font_remove_size_cache, "font_rid", "size");
+
+ GDVIRTUAL_BIND(_font_set_ascent, "font_rid", "size", "ascent");
+ GDVIRTUAL_BIND(_font_get_ascent, "font_rid", "size");
+
+ GDVIRTUAL_BIND(_font_set_descent, "font_rid", "size", "descent");
+ GDVIRTUAL_BIND(_font_get_descent, "font_rid", "size");
+
+ GDVIRTUAL_BIND(_font_set_underline_position, "font_rid", "size", "underline_position");
+ GDVIRTUAL_BIND(_font_get_underline_position, "font_rid", "size");
+
+ GDVIRTUAL_BIND(_font_set_underline_thickness, "font_rid", "size", "underline_thickness");
+ GDVIRTUAL_BIND(_font_get_underline_thickness, "font_rid", "size");
+
+ GDVIRTUAL_BIND(_font_set_scale, "font_rid", "size", "scale");
+ GDVIRTUAL_BIND(_font_get_scale, "font_rid", "size");
+
+ GDVIRTUAL_BIND(_font_set_spacing, "font_rid", "size", "spacing", "value");
+ GDVIRTUAL_BIND(_font_get_spacing, "font_rid", "size", "spacing");
+
+ GDVIRTUAL_BIND(_font_get_texture_count, "font_rid", "size");
+ GDVIRTUAL_BIND(_font_clear_textures, "font_rid", "size");
+ GDVIRTUAL_BIND(_font_remove_texture, "font_rid", "size", "texture_index");
+
+ GDVIRTUAL_BIND(_font_set_texture_image, "font_rid", "size", "texture_index", "image");
+ GDVIRTUAL_BIND(_font_get_texture_image, "font_rid", "size", "texture_index");
+
+ GDVIRTUAL_BIND(_font_set_texture_offsets, "font_rid", "size", "texture_index", "offset");
+ GDVIRTUAL_BIND(_font_get_texture_offsets, "font_rid", "size", "texture_index");
+
+ GDVIRTUAL_BIND(_font_get_glyph_list, "font_rid", "size");
+ GDVIRTUAL_BIND(_font_clear_glyphs, "font_rid", "size");
+ GDVIRTUAL_BIND(_font_remove_glyph, "font_rid", "size", "glyph");
+
+ GDVIRTUAL_BIND(_font_get_glyph_advance, "font_rid", "size", "glyph");
+ GDVIRTUAL_BIND(_font_set_glyph_advance, "font_rid", "size", "glyph", "advance");
+
+ GDVIRTUAL_BIND(_font_get_glyph_offset, "font_rid", "size", "glyph");
+ GDVIRTUAL_BIND(_font_set_glyph_offset, "font_rid", "size", "glyph", "offset");
+
+ GDVIRTUAL_BIND(_font_get_glyph_size, "font_rid", "size", "glyph");
+ GDVIRTUAL_BIND(_font_set_glyph_size, "font_rid", "size", "glyph", "gl_size");
+
+ GDVIRTUAL_BIND(_font_get_glyph_uv_rect, "font_rid", "size", "glyph");
+ GDVIRTUAL_BIND(_font_set_glyph_uv_rect, "font_rid", "size", "glyph", "uv_rect");
+
+ GDVIRTUAL_BIND(_font_get_glyph_texture_idx, "font_rid", "size", "glyph");
+ GDVIRTUAL_BIND(_font_set_glyph_texture_idx, "font_rid", "size", "glyph", "texture_idx");
+
+ GDVIRTUAL_BIND(_font_get_glyph_contours, "font_rid", "size", "index");
+
+ GDVIRTUAL_BIND(_font_get_kerning_list, "font_rid", "size");
+ GDVIRTUAL_BIND(_font_clear_kerning_map, "font_rid", "size");
+ GDVIRTUAL_BIND(_font_remove_kerning, "font_rid", "size", "glyph_pair");
+
+ GDVIRTUAL_BIND(_font_set_kerning, "font_rid", "size", "glyph_pair", "kerning");
+ GDVIRTUAL_BIND(_font_get_kerning, "font_rid", "size", "glyph_pair");
+
+ GDVIRTUAL_BIND(_font_get_glyph_index, "font_rid", "size", "char", "variation_selector");
+
+ GDVIRTUAL_BIND(_font_has_char, "font_rid", "char");
+ GDVIRTUAL_BIND(_font_get_supported_chars, "font_rid");
+
+ GDVIRTUAL_BIND(_font_render_range, "font_rid", "size", "start", "end");
+ GDVIRTUAL_BIND(_font_render_glyph, "font_rid", "size", "index");
+
+ GDVIRTUAL_BIND(_font_draw_glyph, "font_rid", "canvas", "size", "pos", "index", "color");
+ GDVIRTUAL_BIND(_font_draw_glyph_outline, "font_rid", "canvas", "size", "outline_size", "pos", "index", "color");
+
+ GDVIRTUAL_BIND(_font_is_language_supported, "font_rid", "language");
+ GDVIRTUAL_BIND(_font_set_language_support_override, "font_rid", "language", "supported");
+ GDVIRTUAL_BIND(_font_get_language_support_override, "font_rid", "language");
+ GDVIRTUAL_BIND(_font_remove_language_support_override, "font_rid", "language");
+ GDVIRTUAL_BIND(_font_get_language_support_overrides, "font_rid");
+
+ GDVIRTUAL_BIND(_font_is_script_supported, "font_rid", "script");
+ GDVIRTUAL_BIND(_font_set_script_support_override, "font_rid", "script", "supported");
+ GDVIRTUAL_BIND(_font_get_script_support_override, "font_rid", "script");
+ GDVIRTUAL_BIND(_font_remove_script_support_override, "font_rid", "script");
+ GDVIRTUAL_BIND(_font_get_script_support_overrides, "font_rid");
+
+ GDVIRTUAL_BIND(_font_supported_feature_list, "font_rid");
+ GDVIRTUAL_BIND(_font_supported_variation_list, "font_rid");
+
+ GDVIRTUAL_BIND(_font_get_global_oversampling);
+ GDVIRTUAL_BIND(_font_set_global_oversampling, "oversampling");
+
+ GDVIRTUAL_BIND(_get_hex_code_box_size, "size", "index");
+ GDVIRTUAL_BIND(_draw_hex_code_box, "canvas", "size", "pos", "index", "color");
+
+ /* Shaped text buffer interface */
+
+ GDVIRTUAL_BIND(_create_shaped_text, "direction", "orientation");
+
+ GDVIRTUAL_BIND(_shaped_text_clear, "shaped");
+
+ GDVIRTUAL_BIND(_shaped_text_set_direction, "shaped", "direction");
+ GDVIRTUAL_BIND(_shaped_text_get_direction, "shaped");
+
+ GDVIRTUAL_BIND(_shaped_text_set_bidi_override, "shaped", "override");
+
+ GDVIRTUAL_BIND(_shaped_text_set_orientation, "shaped", "orientation");
+ GDVIRTUAL_BIND(_shaped_text_get_orientation, "shaped");
+
+ GDVIRTUAL_BIND(_shaped_text_set_preserve_invalid, "shaped", "enabled");
+ GDVIRTUAL_BIND(_shaped_text_get_preserve_invalid, "shaped");
+
+ GDVIRTUAL_BIND(_shaped_text_set_preserve_control, "shaped", "enabled");
+ GDVIRTUAL_BIND(_shaped_text_get_preserve_control, "shaped");
+
+ GDVIRTUAL_BIND(_shaped_text_add_string, "shaped", "text", "fonts", "size", "opentype_features", "language");
+ GDVIRTUAL_BIND(_shaped_text_add_object, "shaped", "key", "size", "inline_align", "length");
+ GDVIRTUAL_BIND(_shaped_text_resize_object, "shaped", "key", "size", "inline_align");
+
+ GDVIRTUAL_BIND(_shaped_text_substr, "shaped", "start", "length");
+ GDVIRTUAL_BIND(_shaped_text_get_parent, "shaped");
+
+ GDVIRTUAL_BIND(_shaped_text_fit_to_width, "shaped", "width", "jst_flags");
+ GDVIRTUAL_BIND(_shaped_text_tab_align, "shaped", "tab_stops");
+
+ GDVIRTUAL_BIND(_shaped_text_shape, "shaped");
+ GDVIRTUAL_BIND(_shaped_text_update_breaks, "shaped");
+ GDVIRTUAL_BIND(_shaped_text_update_justification_ops, "shaped");
+
+ GDVIRTUAL_BIND(_shaped_text_is_ready, "shaped");
+
+ GDVIRTUAL_BIND(_shaped_text_get_glyphs, "shaped", "r_glyphs");
+ GDVIRTUAL_BIND(_shaped_text_sort_logical, "shaped", "r_glyphs");
+ GDVIRTUAL_BIND(_shaped_text_get_glyph_count, "shaped");
+
+ GDVIRTUAL_BIND(_shaped_text_get_range, "shaped");
+
+ 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_trim_pos, "shaped");
+ GDVIRTUAL_BIND(_shaped_text_get_ellipsis_pos, "shaped");
+ GDVIRTUAL_BIND(_shaped_text_get_ellipsis_glyph_count, "shaped");
+ GDVIRTUAL_BIND(_shaped_text_get_ellipsis_glyphs, "shaped", "r_glyphs");
+
+ GDVIRTUAL_BIND(_shaped_text_overrun_trim_to_width, "shaped", "width", "trim_flags");
+
+ GDVIRTUAL_BIND(_shaped_text_get_objects, "shaped");
+ GDVIRTUAL_BIND(_shaped_text_get_object_rect, "shaped", "key");
+
+ GDVIRTUAL_BIND(_shaped_text_get_size, "shaped");
+ GDVIRTUAL_BIND(_shaped_text_get_ascent, "shaped");
+ GDVIRTUAL_BIND(_shaped_text_get_descent, "shaped");
+ GDVIRTUAL_BIND(_shaped_text_get_width, "shaped");
+ GDVIRTUAL_BIND(_shaped_text_get_underline_position, "shaped");
+ GDVIRTUAL_BIND(_shaped_text_get_underline_thickness, "shaped");
+
+ GDVIRTUAL_BIND(_shaped_text_get_dominant_direction_in_range, "shaped", "start", "end");
+
+ GDVIRTUAL_BIND(_shaped_text_get_carets, "shaped", "position", "caret");
+ GDVIRTUAL_BIND(_shaped_text_get_selection, "shaped", "start", "end");
+
+ GDVIRTUAL_BIND(_shaped_text_hit_test_grapheme, "shaped", "coord");
+ GDVIRTUAL_BIND(_shaped_text_hit_test_position, "shaped", "coord");
+
+ GDVIRTUAL_BIND(_shaped_text_draw, "shaped", "canvas", "pos", "clip_l", "clip_r", "color");
+ GDVIRTUAL_BIND(_shaped_text_draw_outline, "shaped", "canvas", "pos", "clip_l", "clip_r", "outline_size", "color");
+
+ GDVIRTUAL_BIND(_shaped_text_next_grapheme_pos, "shaped", "pos");
+ GDVIRTUAL_BIND(_shaped_text_prev_grapheme_pos, "shaped", "pos");
+
+ GDVIRTUAL_BIND(_format_number, "string", "language");
+ GDVIRTUAL_BIND(_parse_number, "string", "language");
+ GDVIRTUAL_BIND(_percent_sign, "language");
+}
+
+bool TextServerExtension::has_feature(Feature p_feature) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_has_feature, p_feature, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+String TextServerExtension::get_name() const {
+ String ret;
+ if (GDVIRTUAL_CALL(_get_name, ret)) {
+ return ret;
+ }
+ return "Unknown";
+}
+
+uint32_t TextServerExtension::get_features() const {
+ uint32_t ret;
+ if (GDVIRTUAL_CALL(_get_features, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+void TextServerExtension::free(RID p_rid) {
+ GDVIRTUAL_CALL(_free, p_rid);
+}
+
+bool TextServerExtension::has(RID p_rid) {
+ bool ret;
+ if (GDVIRTUAL_CALL(_has, p_rid, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+bool TextServerExtension::load_support_data(const String &p_filename) {
+ bool ret;
+ if (GDVIRTUAL_CALL(_load_support_data, p_filename, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+String TextServerExtension::get_support_data_filename() const {
+ String ret;
+ if (GDVIRTUAL_CALL(_get_support_data_filename, ret)) {
+ return ret;
+ }
+ return String();
+}
+
+String TextServerExtension::get_support_data_info() const {
+ String ret;
+ if (GDVIRTUAL_CALL(_get_support_data_info, ret)) {
+ return ret;
+ }
+ return String();
+}
+
+bool TextServerExtension::save_support_data(const String &p_filename) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_save_support_data, p_filename, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+bool TextServerExtension::is_locale_right_to_left(const String &p_locale) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_is_locale_right_to_left, p_locale, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+int32_t TextServerExtension::name_to_tag(const String &p_name) const {
+ int32_t ret;
+ if (GDVIRTUAL_CALL(_name_to_tag, p_name, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+String TextServerExtension::tag_to_name(int32_t p_tag) const {
+ String ret;
+ if (GDVIRTUAL_CALL(_tag_to_name, p_tag, ret)) {
+ return ret;
+ }
+ return "";
+}
+
+/*************************************************************************/
+/* Font */
+/*************************************************************************/
+
+RID TextServerExtension::create_font() {
+ RID ret;
+ if (GDVIRTUAL_CALL(_create_font, ret)) {
+ return ret;
+ }
+ return RID();
+}
+
+void TextServerExtension::font_set_data(RID p_font_rid, const PackedByteArray &p_data) {
+ GDVIRTUAL_CALL(_font_set_data, p_font_rid, p_data);
+}
+
+void TextServerExtension::font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) {
+ GDVIRTUAL_CALL(_font_set_data_ptr, p_font_rid, p_data_ptr, p_data_size);
+}
+
+void TextServerExtension::font_set_antialiased(RID p_font_rid, bool p_antialiased) {
+ GDVIRTUAL_CALL(_font_set_antialiased, p_font_rid, p_antialiased);
+}
+
+bool TextServerExtension::font_is_antialiased(RID p_font_rid) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_font_is_antialiased, p_font_rid, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+void TextServerExtension::font_set_multichannel_signed_distance_field(RID p_font_rid, bool p_msdf) {
+ GDVIRTUAL_CALL(_font_set_multichannel_signed_distance_field, p_font_rid, p_msdf);
+}
+
+bool TextServerExtension::font_is_multichannel_signed_distance_field(RID p_font_rid) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_font_is_multichannel_signed_distance_field, p_font_rid, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+void TextServerExtension::font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pixel_range) {
+ GDVIRTUAL_CALL(_font_set_msdf_pixel_range, p_font_rid, p_msdf_pixel_range);
+}
+
+int TextServerExtension::font_get_msdf_pixel_range(RID p_font_rid) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_font_get_msdf_pixel_range, p_font_rid, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+void TextServerExtension::font_set_msdf_size(RID p_font_rid, int p_msdf_size) {
+ GDVIRTUAL_CALL(_font_set_msdf_size, p_font_rid, p_msdf_size);
+}
+
+int TextServerExtension::font_get_msdf_size(RID p_font_rid) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_font_get_msdf_size, p_font_rid, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+void TextServerExtension::font_set_fixed_size(RID p_font_rid, int p_fixed_size) {
+ GDVIRTUAL_CALL(_font_set_fixed_size, p_font_rid, p_fixed_size);
+}
+
+int TextServerExtension::font_get_fixed_size(RID p_font_rid) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_font_get_fixed_size, p_font_rid, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+void TextServerExtension::font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) {
+ GDVIRTUAL_CALL(_font_set_force_autohinter, p_font_rid, p_force_autohinter);
+}
+
+bool TextServerExtension::font_is_force_autohinter(RID p_font_rid) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_font_is_force_autohinter, p_font_rid, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+void TextServerExtension::font_set_hinting(RID p_font_rid, TextServer::Hinting p_hinting) {
+ GDVIRTUAL_CALL(_font_set_hinting, p_font_rid, p_hinting);
+}
+
+TextServer::Hinting TextServerExtension::font_get_hinting(RID p_font_rid) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_font_get_hinting, p_font_rid, ret)) {
+ return (TextServer::Hinting)ret;
+ }
+ return TextServer::Hinting::HINTING_NONE;
+}
+
+void TextServerExtension::font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) {
+ GDVIRTUAL_CALL(_font_set_variation_coordinates, p_font_rid, p_variation_coordinates);
+}
+
+Dictionary TextServerExtension::font_get_variation_coordinates(RID p_font_rid) const {
+ Dictionary ret;
+ if (GDVIRTUAL_CALL(_font_get_variation_coordinates, p_font_rid, ret)) {
+ return ret;
+ }
+ return Dictionary();
+}
+
+void TextServerExtension::font_set_oversampling(RID p_font_rid, float p_oversampling) {
+ GDVIRTUAL_CALL(_font_set_oversampling, p_font_rid, p_oversampling);
+}
+
+float TextServerExtension::font_get_oversampling(RID p_font_rid) const {
+ float ret;
+ if (GDVIRTUAL_CALL(_font_get_oversampling, p_font_rid, ret)) {
+ return ret;
+ }
+ return 0.f;
+}
+
+Array TextServerExtension::font_get_size_cache_list(RID p_font_rid) const {
+ Array ret;
+ if (GDVIRTUAL_CALL(_font_get_size_cache_list, p_font_rid, ret)) {
+ return ret;
+ }
+ return Array();
+}
+
+void TextServerExtension::font_clear_size_cache(RID p_font_rid) {
+ GDVIRTUAL_CALL(_font_clear_size_cache, p_font_rid);
+}
+
+void TextServerExtension::font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) {
+ GDVIRTUAL_CALL(_font_remove_size_cache, p_font_rid, p_size);
+}
+
+void TextServerExtension::font_set_ascent(RID p_font_rid, int p_size, float p_ascent) {
+ GDVIRTUAL_CALL(_font_set_ascent, p_font_rid, p_size, p_ascent);
+}
+
+float TextServerExtension::font_get_ascent(RID p_font_rid, int p_size) const {
+ float ret;
+ if (GDVIRTUAL_CALL(_font_get_ascent, p_font_rid, p_size, ret)) {
+ return ret;
+ }
+ return 0.f;
+}
+
+void TextServerExtension::font_set_descent(RID p_font_rid, int p_size, float p_descent) {
+ GDVIRTUAL_CALL(_font_set_descent, p_font_rid, p_size, p_descent);
+}
+
+float TextServerExtension::font_get_descent(RID p_font_rid, int p_size) const {
+ float ret;
+ if (GDVIRTUAL_CALL(_font_get_descent, p_font_rid, p_size, ret)) {
+ return ret;
+ }
+ return 0.f;
+}
+
+void TextServerExtension::font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) {
+ GDVIRTUAL_CALL(_font_set_underline_position, p_font_rid, p_size, p_underline_position);
+}
+
+float TextServerExtension::font_get_underline_position(RID p_font_rid, int p_size) const {
+ float ret;
+ if (GDVIRTUAL_CALL(_font_get_underline_position, p_font_rid, p_size, ret)) {
+ return ret;
+ }
+ return 0.f;
+}
+
+void TextServerExtension::font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) {
+ GDVIRTUAL_CALL(_font_set_underline_thickness, p_font_rid, p_size, p_underline_thickness);
+}
+
+float TextServerExtension::font_get_underline_thickness(RID p_font_rid, int p_size) const {
+ float ret;
+ if (GDVIRTUAL_CALL(_font_get_underline_thickness, p_font_rid, p_size, ret)) {
+ return ret;
+ }
+ return 0.f;
+}
+
+void TextServerExtension::font_set_scale(RID p_font_rid, int p_size, float p_scale) {
+ GDVIRTUAL_CALL(_font_set_scale, p_font_rid, p_size, p_scale);
+}
+
+float TextServerExtension::font_get_scale(RID p_font_rid, int p_size) const {
+ float ret;
+ if (GDVIRTUAL_CALL(_font_get_scale, p_font_rid, p_size, ret)) {
+ return ret;
+ }
+ return 0.f;
+}
+
+void TextServerExtension::font_set_spacing(RID p_font_rid, int p_size, TextServer::SpacingType p_spacing, int p_value) {
+ GDVIRTUAL_CALL(_font_set_spacing, p_font_rid, p_size, p_spacing, p_value);
+}
+
+int TextServerExtension::font_get_spacing(RID p_font_rid, int p_size, TextServer::SpacingType p_spacing) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_font_get_spacing, p_font_rid, p_size, p_spacing, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+int TextServerExtension::font_get_texture_count(RID p_font_rid, const Vector2i &p_size) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_font_get_texture_count, p_font_rid, p_size, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+void TextServerExtension::font_clear_textures(RID p_font_rid, const Vector2i &p_size) {
+ GDVIRTUAL_CALL(_font_clear_textures, p_font_rid, p_size);
+}
+
+void TextServerExtension::font_remove_texture(RID p_font_rid, const Vector2i &p_size, int p_texture_index) {
+ GDVIRTUAL_CALL(_font_remove_texture, p_font_rid, p_size, p_texture_index);
+}
+
+void TextServerExtension::font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) {
+ GDVIRTUAL_CALL(_font_set_texture_image, p_font_rid, p_size, p_texture_index, p_image);
+}
+
+Ref<Image> TextServerExtension::font_get_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const {
+ Ref<Image> ret;
+ if (GDVIRTUAL_CALL(_font_get_texture_image, p_font_rid, p_size, p_texture_index, ret)) {
+ return ret;
+ }
+ return Ref<Image>();
+}
+
+void TextServerExtension::font_set_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) {
+ GDVIRTUAL_CALL(_font_set_texture_offsets, p_font_rid, p_size, p_texture_index, p_offset);
+}
+
+PackedInt32Array TextServerExtension::font_get_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const {
+ PackedInt32Array ret;
+ if (GDVIRTUAL_CALL(_font_get_texture_offsets, p_font_rid, p_size, p_texture_index, ret)) {
+ return ret;
+ }
+ return PackedInt32Array();
+}
+
+Array TextServerExtension::font_get_glyph_list(RID p_font_rid, const Vector2i &p_size) const {
+ Array ret;
+ if (GDVIRTUAL_CALL(_font_get_glyph_list, p_font_rid, p_size, ret)) {
+ return ret;
+ }
+ return Array();
+}
+
+void TextServerExtension::font_clear_glyphs(RID p_font_rid, const Vector2i &p_size) {
+ GDVIRTUAL_CALL(_font_clear_glyphs, p_font_rid, p_size);
+}
+
+void TextServerExtension::font_remove_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) {
+ GDVIRTUAL_CALL(_font_remove_glyph, p_font_rid, p_size, p_glyph);
+}
+
+Vector2 TextServerExtension::font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const {
+ Vector2 ret;
+ if (GDVIRTUAL_CALL(_font_get_glyph_advance, p_font_rid, p_size, p_glyph, ret)) {
+ return ret;
+ }
+ return Vector2();
+}
+
+void TextServerExtension::font_set_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph, const Vector2 &p_advance) {
+ GDVIRTUAL_CALL(_font_set_glyph_advance, p_font_rid, p_size, p_glyph, p_advance);
+}
+
+Vector2 TextServerExtension::font_get_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const {
+ Vector2 ret;
+ if (GDVIRTUAL_CALL(_font_get_glyph_offset, p_font_rid, p_size, p_glyph, ret)) {
+ return ret;
+ }
+ return Vector2();
+}
+
+void TextServerExtension::font_set_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) {
+ GDVIRTUAL_CALL(_font_set_glyph_offset, p_font_rid, p_size, p_glyph, p_offset);
+}
+
+Vector2 TextServerExtension::font_get_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const {
+ Vector2 ret;
+ if (GDVIRTUAL_CALL(_font_get_glyph_size, p_font_rid, p_size, p_glyph, ret)) {
+ return ret;
+ }
+ return Vector2();
+}
+
+void TextServerExtension::font_set_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) {
+ GDVIRTUAL_CALL(_font_set_glyph_size, p_font_rid, p_size, p_glyph, p_gl_size);
+}
+
+Rect2 TextServerExtension::font_get_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const {
+ Rect2 ret;
+ if (GDVIRTUAL_CALL(_font_get_glyph_uv_rect, p_font_rid, p_size, p_glyph, ret)) {
+ return ret;
+ }
+ return Rect2();
+}
+
+void TextServerExtension::font_set_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) {
+ GDVIRTUAL_CALL(_font_set_glyph_uv_rect, p_font_rid, p_size, p_glyph, p_uv_rect);
+}
+
+int TextServerExtension::font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_font_get_glyph_texture_idx, p_font_rid, p_size, p_glyph, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+void TextServerExtension::font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) {
+ GDVIRTUAL_CALL(_font_set_glyph_texture_idx, p_font_rid, p_size, p_glyph, p_texture_idx);
+}
+
+Dictionary TextServerExtension::font_get_glyph_contours(RID p_font_rid, int p_size, int32_t p_index) const {
+ Dictionary ret;
+ if (GDVIRTUAL_CALL(_font_get_glyph_contours, p_font_rid, p_size, p_index, ret)) {
+ return ret;
+ }
+ return Dictionary();
+}
+
+Array TextServerExtension::font_get_kerning_list(RID p_font_rid, int p_size) const {
+ Array ret;
+ if (GDVIRTUAL_CALL(_font_get_kerning_list, p_font_rid, p_size, ret)) {
+ return ret;
+ }
+ return Array();
+}
+
+void TextServerExtension::font_clear_kerning_map(RID p_font_rid, int p_size) {
+ GDVIRTUAL_CALL(_font_clear_kerning_map, p_font_rid, p_size);
+}
+
+void TextServerExtension::font_remove_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) {
+ GDVIRTUAL_CALL(_font_remove_kerning, p_font_rid, p_size, p_glyph_pair);
+}
+
+void TextServerExtension::font_set_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) {
+ GDVIRTUAL_CALL(_font_set_kerning, p_font_rid, p_size, p_glyph_pair, p_kerning);
+}
+
+Vector2 TextServerExtension::font_get_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) const {
+ Vector2 ret;
+ if (GDVIRTUAL_CALL(_font_get_kerning, p_font_rid, p_size, p_glyph_pair, ret)) {
+ return ret;
+ }
+ return Vector2();
+}
+
+int32_t TextServerExtension::font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector) const {
+ int32_t ret;
+ if (GDVIRTUAL_CALL(_font_get_glyph_index, p_font_rid, p_size, p_char, p_variation_selector, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+bool TextServerExtension::font_has_char(RID p_font_rid, char32_t p_char) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_font_has_char, p_font_rid, p_char, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+String TextServerExtension::font_get_supported_chars(RID p_font_rid) const {
+ String ret;
+ if (GDVIRTUAL_CALL(_font_get_supported_chars, p_font_rid, ret)) {
+ return ret;
+ }
+ return String();
+}
+
+void TextServerExtension::font_render_range(RID p_font_rid, const Vector2i &p_size, char32_t p_start, char32_t p_end) {
+ GDVIRTUAL_CALL(_font_render_range, p_font_rid, p_size, p_start, p_end);
+}
+
+void TextServerExtension::font_render_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_index) {
+ GDVIRTUAL_CALL(_font_render_glyph, p_font_rid, p_size, p_index);
+}
+
+void TextServerExtension::font_draw_glyph(RID p_font_rid, RID p_canvas, int p_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color) const {
+ GDVIRTUAL_CALL(_font_draw_glyph, p_font_rid, p_canvas, p_size, p_pos, p_index, p_color);
+}
+
+void TextServerExtension::font_draw_glyph_outline(RID p_font_rid, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color) const {
+ GDVIRTUAL_CALL(_font_draw_glyph_outline, p_font_rid, p_canvas, p_size, p_outline_size, p_pos, p_index, p_color);
+}
+
+bool TextServerExtension::font_is_language_supported(RID p_font_rid, const String &p_language) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_font_is_language_supported, p_font_rid, p_language, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+void TextServerExtension::font_set_language_support_override(RID p_font_rid, const String &p_language, bool p_supported) {
+ GDVIRTUAL_CALL(_font_set_language_support_override, p_font_rid, p_language, p_supported);
+}
+
+bool TextServerExtension::font_get_language_support_override(RID p_font_rid, const String &p_language) {
+ bool ret;
+ if (GDVIRTUAL_CALL(_font_get_language_support_override, p_font_rid, p_language, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+void TextServerExtension::font_remove_language_support_override(RID p_font_rid, const String &p_language) {
+ GDVIRTUAL_CALL(_font_remove_language_support_override, p_font_rid, p_language);
+}
+
+Vector<String> TextServerExtension::font_get_language_support_overrides(RID p_font_rid) {
+ Vector<String> ret;
+ if (GDVIRTUAL_CALL(_font_get_language_support_overrides, p_font_rid, ret)) {
+ return ret;
+ }
+ return Vector<String>();
+}
+
+bool TextServerExtension::font_is_script_supported(RID p_font_rid, const String &p_script) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_font_is_script_supported, p_font_rid, p_script, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+void TextServerExtension::font_set_script_support_override(RID p_font_rid, const String &p_script, bool p_supported) {
+ GDVIRTUAL_CALL(_font_set_script_support_override, p_font_rid, p_script, p_supported);
+}
+
+bool TextServerExtension::font_get_script_support_override(RID p_font_rid, const String &p_script) {
+ bool ret;
+ if (GDVIRTUAL_CALL(_font_get_script_support_override, p_font_rid, p_script, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+void TextServerExtension::font_remove_script_support_override(RID p_font_rid, const String &p_script) {
+ GDVIRTUAL_CALL(_font_remove_script_support_override, p_font_rid, p_script);
+}
+
+Vector<String> TextServerExtension::font_get_script_support_overrides(RID p_font_rid) {
+ Vector<String> ret;
+ if (GDVIRTUAL_CALL(_font_get_script_support_overrides, p_font_rid, ret)) {
+ return ret;
+ }
+ return Vector<String>();
+}
+
+Dictionary TextServerExtension::font_supported_feature_list(RID p_font_rid) const {
+ Dictionary ret;
+ if (GDVIRTUAL_CALL(_font_supported_feature_list, p_font_rid, ret)) {
+ return ret;
+ }
+ return Dictionary();
+}
+
+Dictionary TextServerExtension::font_supported_variation_list(RID p_font_rid) const {
+ Dictionary ret;
+ if (GDVIRTUAL_CALL(_font_supported_variation_list, p_font_rid, ret)) {
+ return ret;
+ }
+ return Dictionary();
+}
+
+float TextServerExtension::font_get_global_oversampling() const {
+ float ret;
+ if (GDVIRTUAL_CALL(_font_get_global_oversampling, ret)) {
+ return ret;
+ }
+ return 0.f;
+}
+
+void TextServerExtension::font_set_global_oversampling(float p_oversampling) {
+ GDVIRTUAL_CALL(_font_set_global_oversampling, p_oversampling);
+}
+
+Vector2 TextServerExtension::get_hex_code_box_size(int p_size, char32_t p_index) const {
+ Vector2 ret;
+ if (GDVIRTUAL_CALL(_get_hex_code_box_size, p_size, p_index, ret)) {
+ return ret;
+ }
+ return TextServer::get_hex_code_box_size(p_size, p_index);
+}
+
+void TextServerExtension::draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const {
+ if (!GDVIRTUAL_CALL(_draw_hex_code_box, p_canvas, p_size, p_pos, p_index, p_color)) {
+ TextServer::draw_hex_code_box(p_canvas, p_size, p_pos, p_index, p_color);
+ }
+}
+
+/*************************************************************************/
+/* Shaped text buffer interface */
+/*************************************************************************/
+
+RID TextServerExtension::create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
+ RID ret;
+ if (GDVIRTUAL_CALL(_create_shaped_text, p_direction, p_orientation, ret)) {
+ return ret;
+ }
+ return RID();
+}
+
+void TextServerExtension::shaped_text_clear(RID p_shaped) {
+ GDVIRTUAL_CALL(_shaped_text_clear, p_shaped);
+}
+
+void TextServerExtension::shaped_text_set_direction(RID p_shaped, TextServer::Direction p_direction) {
+ GDVIRTUAL_CALL(_shaped_text_set_direction, p_shaped, p_direction);
+}
+
+TextServer::Direction TextServerExtension::shaped_text_get_direction(RID p_shaped) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_direction, p_shaped, ret)) {
+ return (TextServer::Direction)ret;
+ }
+ return TextServer::Direction::DIRECTION_AUTO;
+}
+
+void TextServerExtension::shaped_text_set_orientation(RID p_shaped, TextServer::Orientation p_orientation) {
+ GDVIRTUAL_CALL(_shaped_text_set_orientation, p_shaped, p_orientation);
+}
+
+TextServer::Orientation TextServerExtension::shaped_text_get_orientation(RID p_shaped) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_orientation, p_shaped, ret)) {
+ return (TextServer::Orientation)ret;
+ }
+ return TextServer::Orientation::ORIENTATION_HORIZONTAL;
+}
+
+void TextServerExtension::shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) {
+ GDVIRTUAL_CALL(_shaped_text_set_bidi_override, p_shaped, p_override);
+}
+
+void TextServerExtension::shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) {
+ GDVIRTUAL_CALL(_shaped_text_set_preserve_invalid, p_shaped, p_enabled);
+}
+
+bool TextServerExtension::shaped_text_get_preserve_invalid(RID p_shaped) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_preserve_invalid, p_shaped, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+void TextServerExtension::shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) {
+ GDVIRTUAL_CALL(_shaped_text_set_preserve_control, p_shaped, p_enabled);
+}
+
+bool TextServerExtension::shaped_text_get_preserve_control(RID p_shaped) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_preserve_control, p_shaped, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+bool TextServerExtension::shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) {
+ bool ret;
+ Array fonts;
+ for (int i = 0; i < p_fonts.size(); i++) {
+ fonts.push_back(p_fonts[i]);
+ }
+ if (GDVIRTUAL_CALL(_shaped_text_add_string, p_shaped, p_text, fonts, p_size, p_opentype_features, p_language, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+bool TextServerExtension::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) {
+ bool ret;
+ if (GDVIRTUAL_CALL(_shaped_text_add_object, p_shaped, p_key, p_size, p_inline_align, p_length, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+bool TextServerExtension::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) {
+ bool ret;
+ if (GDVIRTUAL_CALL(_shaped_text_resize_object, p_shaped, p_key, p_size, p_inline_align, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+RID TextServerExtension::shaped_text_substr(RID p_shaped, int p_start, int p_length) const {
+ RID ret;
+ if (GDVIRTUAL_CALL(_shaped_text_substr, p_shaped, p_start, p_length, ret)) {
+ return ret;
+ }
+ return RID();
+}
+
+RID TextServerExtension::shaped_text_get_parent(RID p_shaped) const {
+ RID ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_parent, p_shaped, ret)) {
+ return ret;
+ }
+ return RID();
+}
+
+float TextServerExtension::shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t p_jst_flags) {
+ float ret;
+ if (GDVIRTUAL_CALL(_shaped_text_fit_to_width, p_shaped, p_width, p_jst_flags, ret)) {
+ return ret;
+ }
+ return 0.f;
+}
+
+float TextServerExtension::shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) {
+ float ret;
+ if (GDVIRTUAL_CALL(_shaped_text_tab_align, p_shaped, p_tab_stops, ret)) {
+ return ret;
+ }
+ return 0.f;
+}
+
+bool TextServerExtension::shaped_text_shape(RID p_shaped) {
+ bool ret;
+ if (GDVIRTUAL_CALL(_shaped_text_shape, p_shaped, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+bool TextServerExtension::shaped_text_update_breaks(RID p_shaped) {
+ bool ret;
+ if (GDVIRTUAL_CALL(_shaped_text_update_breaks, p_shaped, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+bool TextServerExtension::shaped_text_update_justification_ops(RID p_shaped) {
+ bool ret;
+ if (GDVIRTUAL_CALL(_shaped_text_update_justification_ops, p_shaped, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+bool TextServerExtension::shaped_text_is_ready(RID p_shaped) const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_shaped_text_is_ready, p_shaped, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+const Glyph *TextServerExtension::shaped_text_get_glyphs(RID p_shaped) const {
+ const Glyph *ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_glyphs, p_shaped, &ret)) {
+ return ret;
+ }
+ return nullptr;
+}
+
+const Glyph *TextServerExtension::shaped_text_sort_logical(RID p_shaped) {
+ const Glyph *ret;
+ if (GDVIRTUAL_CALL(_shaped_text_sort_logical, p_shaped, &ret)) {
+ return ret;
+ }
+ return nullptr;
+}
+
+int TextServerExtension::shaped_text_get_glyph_count(RID p_shaped) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_glyph_count, p_shaped, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+Vector2i TextServerExtension::shaped_text_get_range(RID p_shaped) const {
+ Vector2i ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_range, p_shaped, ret)) {
+ return ret;
+ }
+ return Vector2i();
+}
+
+PackedInt32Array TextServerExtension::shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start, bool p_once, uint16_t p_break_flags) const {
+ PackedInt32Array ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_line_breaks_adv, p_shaped, p_width, p_start, p_once, p_break_flags, ret)) {
+ return ret;
+ }
+ return TextServer::shaped_text_get_line_breaks_adv(p_shaped, p_width, p_start, p_once, p_break_flags);
+}
+
+PackedInt32Array TextServerExtension::shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start, uint16_t p_break_flags) const {
+ PackedInt32Array ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_line_breaks, p_shaped, p_width, p_start, p_break_flags, ret)) {
+ return ret;
+ }
+ return TextServer::shaped_text_get_line_breaks(p_shaped, p_width, p_start, p_break_flags);
+}
+
+PackedInt32Array TextServerExtension::shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags) const {
+ PackedInt32Array ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_word_breaks, p_shaped, p_grapheme_flags, ret)) {
+ return ret;
+ }
+ return TextServer::shaped_text_get_word_breaks(p_shaped, p_grapheme_flags);
+}
+
+int TextServerExtension::shaped_text_get_trim_pos(RID p_shaped) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_trim_pos, p_shaped, ret)) {
+ return ret;
+ }
+ return -1;
+}
+
+int TextServerExtension::shaped_text_get_ellipsis_pos(RID p_shaped) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_ellipsis_pos, p_shaped, ret)) {
+ return ret;
+ }
+ return -1;
+}
+
+const Glyph *TextServerExtension::shaped_text_get_ellipsis_glyphs(RID p_shaped) const {
+ const Glyph *ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyphs, p_shaped, &ret)) {
+ return ret;
+ }
+ return nullptr;
+}
+
+int TextServerExtension::shaped_text_get_ellipsis_glyph_count(RID p_shaped) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyph_count, p_shaped, ret)) {
+ return ret;
+ }
+ return -1;
+}
+
+void TextServerExtension::shaped_text_overrun_trim_to_width(RID p_shaped_line, float p_width, uint16_t p_trim_flags) {
+ GDVIRTUAL_CALL(_shaped_text_overrun_trim_to_width, p_shaped_line, p_width, p_trim_flags);
+}
+
+Array TextServerExtension::shaped_text_get_objects(RID p_shaped) const {
+ Array ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_objects, p_shaped, ret)) {
+ return ret;
+ }
+ return Array();
+}
+
+Rect2 TextServerExtension::shaped_text_get_object_rect(RID p_shaped, Variant p_key) const {
+ Rect2 ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_object_rect, p_shaped, p_key, ret)) {
+ return ret;
+ }
+ return Rect2();
+}
+
+Size2 TextServerExtension::shaped_text_get_size(RID p_shaped) const {
+ Size2 ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_size, p_shaped, ret)) {
+ return ret;
+ }
+ return Size2();
+}
+
+float TextServerExtension::shaped_text_get_ascent(RID p_shaped) const {
+ float ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_ascent, p_shaped, ret)) {
+ return ret;
+ }
+ return 0.f;
+}
+
+float TextServerExtension::shaped_text_get_descent(RID p_shaped) const {
+ float ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_descent, p_shaped, ret)) {
+ return ret;
+ }
+ return 0.f;
+}
+
+float TextServerExtension::shaped_text_get_width(RID p_shaped) const {
+ float ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_width, p_shaped, ret)) {
+ return ret;
+ }
+ return 0.f;
+}
+
+float TextServerExtension::shaped_text_get_underline_position(RID p_shaped) const {
+ float ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_underline_position, p_shaped, ret)) {
+ return ret;
+ }
+ return 0.f;
+}
+
+float TextServerExtension::shaped_text_get_underline_thickness(RID p_shaped) const {
+ float ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_underline_thickness, p_shaped, ret)) {
+ return ret;
+ }
+ return 0.f;
+}
+
+TextServer::Direction TextServerExtension::shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_dominant_direction_in_range, p_shaped, p_start, p_end, ret)) {
+ return (TextServer::Direction)ret;
+ }
+ return TextServer::shaped_text_get_dominant_direction_in_range(p_shaped, p_start, p_end);
+}
+
+CaretInfo TextServerExtension::shaped_text_get_carets(RID p_shaped, int p_position) const {
+ CaretInfo ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_carets, p_shaped, p_position, &ret)) {
+ return ret;
+ }
+ return TextServer::shaped_text_get_carets(p_shaped, p_position);
+}
+
+Vector<Vector2> TextServerExtension::shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const {
+ Vector<Vector2> ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_selection, p_shaped, p_start, p_end, ret)) {
+ return ret;
+ }
+ return TextServer::shaped_text_get_selection(p_shaped, p_start, p_end);
+}
+
+int TextServerExtension::shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_shaped_text_hit_test_grapheme, p_shaped, p_coords, ret)) {
+ return ret;
+ }
+ return TextServer::shaped_text_hit_test_grapheme(p_shaped, p_coords);
+}
+
+int TextServerExtension::shaped_text_hit_test_position(RID p_shaped, float p_coords) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_shaped_text_hit_test_position, p_shaped, p_coords, ret)) {
+ return ret;
+ }
+ return TextServer::shaped_text_hit_test_position(p_shaped, p_coords);
+}
+
+void TextServerExtension::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l, float p_clip_r, const Color &p_color) const {
+ if (GDVIRTUAL_CALL(_shaped_text_draw, p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_color)) {
+ return;
+ }
+ TextServer::shaped_text_draw(p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_color);
+}
+
+void TextServerExtension::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l, float p_clip_r, int p_outline_size, const Color &p_color) const {
+ if (GDVIRTUAL_CALL(_shaped_text_draw_outline, p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_outline_size, p_color)) {
+ return;
+ }
+ shaped_text_draw_outline(p_shaped, p_canvas, p_pos, p_clip_l, p_clip_r, p_outline_size, p_color);
+}
+
+int TextServerExtension::shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_shaped_text_next_grapheme_pos, p_shaped, p_pos, ret)) {
+ return ret;
+ }
+ return TextServer::shaped_text_next_grapheme_pos(p_shaped, p_pos);
+}
+
+int TextServerExtension::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_shaped_text_prev_grapheme_pos, p_shaped, p_pos, ret)) {
+ return ret;
+ }
+ return TextServer::shaped_text_prev_grapheme_pos(p_shaped, p_pos);
+}
+
+String TextServerExtension::format_number(const String &p_string, const String &p_language) const {
+ String ret;
+ if (GDVIRTUAL_CALL(_format_number, p_string, p_language, ret)) {
+ return ret;
+ }
+ return TextServer::format_number(p_string, p_language);
+}
+
+String TextServerExtension::parse_number(const String &p_string, const String &p_language) const {
+ String ret;
+ if (GDVIRTUAL_CALL(_parse_number, p_string, p_language, ret)) {
+ return ret;
+ }
+ return TextServer::parse_number(p_string, p_language);
+}
+
+String TextServerExtension::percent_sign(const String &p_language) const {
+ String ret;
+ if (GDVIRTUAL_CALL(_percent_sign, p_language, ret)) {
+ return ret;
+ }
+ return TextServer::percent_sign(p_language);
+}
+
+TextServerExtension::TextServerExtension() {
+ //NOP
+}
+
+TextServerExtension::~TextServerExtension() {
+ //NOP
+}
diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h
new file mode 100644
index 0000000000..88a8c0cb0c
--- /dev/null
+++ b/servers/text/text_server_extension.h
@@ -0,0 +1,426 @@
+/*************************************************************************/
+/* text_server_extension.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 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 */
+/* "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 TEXT_SERVER_EXTENSION_H
+#define TEXT_SERVER_EXTENSION_H
+
+#include "core/object/gdvirtual.gen.inc"
+#include "core/object/script_language.h"
+#include "core/variant/native_ptr.h"
+#include "servers/text_server.h"
+
+class TextServerExtension : public TextServer {
+ GDCLASS(TextServerExtension, TextServer);
+
+protected:
+ _THREAD_SAFE_CLASS_
+
+ static void _bind_methods();
+
+public:
+ virtual bool has_feature(Feature p_feature) const override;
+ virtual String get_name() const override;
+ virtual uint32_t get_features() const override;
+ GDVIRTUAL1RC(bool, _has_feature, Feature);
+ GDVIRTUAL0RC(String, _get_name);
+ GDVIRTUAL0RC(uint32_t, _get_features);
+
+ virtual void free(RID p_rid) override;
+ virtual bool has(RID p_rid) override;
+ virtual bool load_support_data(const String &p_filename) override;
+ GDVIRTUAL1(_free, RID);
+ GDVIRTUAL1R(bool, _has, RID);
+ GDVIRTUAL1R(bool, _load_support_data, const String &);
+
+ virtual String get_support_data_filename() const override;
+ virtual String get_support_data_info() const override;
+ virtual bool save_support_data(const String &p_filename) const override;
+ GDVIRTUAL0RC(String, _get_support_data_filename);
+ GDVIRTUAL0RC(String, _get_support_data_info);
+ GDVIRTUAL1RC(bool, _save_support_data, const String &);
+
+ virtual bool is_locale_right_to_left(const String &p_locale) const override;
+ GDVIRTUAL1RC(bool, _is_locale_right_to_left, const String &);
+
+ virtual int32_t name_to_tag(const String &p_name) const override;
+ virtual String tag_to_name(int32_t p_tag) const override;
+ GDVIRTUAL1RC(int32_t, _name_to_tag, const String &);
+ GDVIRTUAL1RC(String, _tag_to_name, int32_t);
+
+ /* Font interface */
+ virtual RID create_font() override;
+ GDVIRTUAL0R(RID, _create_font);
+
+ virtual void font_set_data(RID p_font_rid, const PackedByteArray &p_data) override;
+ virtual void font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) override;
+ GDVIRTUAL2(_font_set_data, RID, const PackedByteArray &);
+ GDVIRTUAL3(_font_set_data_ptr, RID, GDNativeConstPtr<const uint8_t>, uint64_t);
+
+ virtual void font_set_antialiased(RID p_font_rid, bool p_antialiased) override;
+ virtual bool font_is_antialiased(RID p_font_rid) const override;
+ GDVIRTUAL2(_font_set_antialiased, RID, bool);
+ GDVIRTUAL1RC(bool, _font_is_antialiased, RID);
+
+ virtual void font_set_multichannel_signed_distance_field(RID p_font_rid, bool p_msdf) override;
+ virtual bool font_is_multichannel_signed_distance_field(RID p_font_rid) const override;
+ GDVIRTUAL2(_font_set_multichannel_signed_distance_field, RID, bool);
+ GDVIRTUAL1RC(bool, _font_is_multichannel_signed_distance_field, RID);
+
+ virtual void font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pixel_range) override;
+ virtual int font_get_msdf_pixel_range(RID p_font_rid) const override;
+ GDVIRTUAL2(_font_set_msdf_pixel_range, RID, int);
+ GDVIRTUAL1RC(int, _font_get_msdf_pixel_range, RID);
+
+ virtual void font_set_msdf_size(RID p_font_rid, int p_msdf_size) override;
+ virtual int font_get_msdf_size(RID p_font_rid) const override;
+ GDVIRTUAL2(_font_set_msdf_size, RID, int);
+ GDVIRTUAL1RC(int, _font_get_msdf_size, RID);
+
+ virtual void font_set_fixed_size(RID p_font_rid, int p_fixed_size) override;
+ virtual int font_get_fixed_size(RID p_font_rid) const override;
+ GDVIRTUAL2(_font_set_fixed_size, RID, int);
+ GDVIRTUAL1RC(int, _font_get_fixed_size, RID);
+
+ virtual void font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) override;
+ virtual bool font_is_force_autohinter(RID p_font_rid) const override;
+ GDVIRTUAL2(_font_set_force_autohinter, RID, bool);
+ GDVIRTUAL1RC(bool, _font_is_force_autohinter, RID);
+
+ virtual void font_set_hinting(RID p_font_rid, Hinting p_hinting) override;
+ virtual Hinting font_get_hinting(RID p_font_rid) const override;
+ GDVIRTUAL2(_font_set_hinting, RID, Hinting);
+ GDVIRTUAL1RC(/*Hinting*/ int, _font_get_hinting, RID);
+
+ virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) override;
+ virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const override;
+ GDVIRTUAL2(_font_set_variation_coordinates, RID, Dictionary);
+ GDVIRTUAL1RC(Dictionary, _font_get_variation_coordinates, RID);
+
+ virtual void font_set_oversampling(RID p_font_rid, float p_oversampling) override;
+ virtual float font_get_oversampling(RID p_font_rid) const override;
+ GDVIRTUAL2(_font_set_oversampling, RID, float);
+ GDVIRTUAL1RC(float, _font_get_oversampling, RID);
+
+ virtual Array font_get_size_cache_list(RID p_font_rid) const override;
+ virtual void font_clear_size_cache(RID p_font_rid) override;
+ virtual void font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) override;
+ GDVIRTUAL1RC(Array, _font_get_size_cache_list, RID);
+ GDVIRTUAL1(_font_clear_size_cache, RID);
+ GDVIRTUAL2(_font_remove_size_cache, RID, const Vector2i &);
+
+ virtual void font_set_ascent(RID p_font_rid, int p_size, float p_ascent) override;
+ virtual float font_get_ascent(RID p_font_rid, int p_size) const override;
+ GDVIRTUAL3(_font_set_ascent, RID, int, float);
+ GDVIRTUAL2RC(float, _font_get_ascent, RID, int);
+
+ virtual void font_set_descent(RID p_font_rid, int p_size, float p_descent) override;
+ virtual float font_get_descent(RID p_font_rid, int p_size) const override;
+ GDVIRTUAL3(_font_set_descent, RID, int, float);
+ GDVIRTUAL2RC(float, _font_get_descent, RID, int);
+
+ virtual void font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) override;
+ virtual float font_get_underline_position(RID p_font_rid, int p_size) const override;
+ GDVIRTUAL3(_font_set_underline_position, RID, int, float);
+ GDVIRTUAL2RC(float, _font_get_underline_position, RID, int);
+
+ virtual void font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) override;
+ virtual float font_get_underline_thickness(RID p_font_rid, int p_size) const override;
+ GDVIRTUAL3(_font_set_underline_thickness, RID, int, float);
+ GDVIRTUAL2RC(float, _font_get_underline_thickness, RID, int);
+
+ virtual void font_set_scale(RID p_font_rid, int p_size, float p_scale) override;
+ virtual float font_get_scale(RID p_font_rid, int p_size) const override;
+ GDVIRTUAL3(_font_set_scale, RID, int, float);
+ GDVIRTUAL2RC(float, _font_get_scale, RID, int);
+
+ virtual void font_set_spacing(RID p_font_rid, int p_size, SpacingType p_spacing, int p_value) override;
+ virtual int font_get_spacing(RID p_font_rid, int p_size, SpacingType p_spacing) const override;
+ GDVIRTUAL4(_font_set_spacing, RID, int, SpacingType, int);
+ GDVIRTUAL3RC(int, _font_get_spacing, RID, int, SpacingType);
+
+ virtual int font_get_texture_count(RID p_font_rid, const Vector2i &p_size) const override;
+ virtual void font_clear_textures(RID p_font_rid, const Vector2i &p_size) override;
+ virtual void font_remove_texture(RID p_font_rid, const Vector2i &p_size, int p_texture_index) override;
+ GDVIRTUAL2RC(int, _font_get_texture_count, RID, const Vector2i &);
+ GDVIRTUAL2(_font_clear_textures, RID, const Vector2i &);
+ GDVIRTUAL3(_font_remove_texture, RID, const Vector2i &, int);
+
+ virtual void font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) override;
+ virtual Ref<Image> font_get_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const override;
+ GDVIRTUAL4(_font_set_texture_image, RID, const Vector2i &, int, const Ref<Image> &);
+ GDVIRTUAL3RC(Ref<Image>, _font_get_texture_image, RID, const Vector2i &, int);
+
+ virtual void font_set_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) override;
+ virtual PackedInt32Array font_get_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const override;
+ GDVIRTUAL4(_font_set_texture_offsets, RID, const Vector2i &, int, const PackedInt32Array &);
+ GDVIRTUAL3RC(PackedInt32Array, _font_get_texture_offsets, RID, const Vector2i &, int);
+
+ virtual Array font_get_glyph_list(RID p_font_rid, const Vector2i &p_size) const override;
+ virtual void font_clear_glyphs(RID p_font_rid, const Vector2i &p_size) override;
+ virtual void font_remove_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) override;
+ GDVIRTUAL2RC(Array, _font_get_glyph_list, RID, const Vector2i &);
+ GDVIRTUAL2(_font_clear_glyphs, RID, const Vector2i &);
+ GDVIRTUAL3(_font_remove_glyph, RID, const Vector2i &, int32_t);
+
+ virtual Vector2 font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const override;
+ virtual void font_set_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph, const Vector2 &p_advance) override;
+ GDVIRTUAL3RC(Vector2, _font_get_glyph_advance, RID, int, int32_t);
+ GDVIRTUAL4(_font_set_glyph_advance, RID, int, int32_t, const Vector2 &);
+
+ virtual Vector2 font_get_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override;
+ virtual void font_set_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) override;
+ GDVIRTUAL3RC(Vector2, _font_get_glyph_offset, RID, const Vector2i &, int32_t);
+ GDVIRTUAL4(_font_set_glyph_offset, RID, const Vector2i &, int32_t, const Vector2 &);
+
+ virtual Vector2 font_get_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override;
+ virtual void font_set_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) override;
+ GDVIRTUAL3RC(Vector2, _font_get_glyph_size, RID, const Vector2i &, int32_t);
+ GDVIRTUAL4(_font_set_glyph_size, RID, const Vector2i &, int32_t, const Vector2 &);
+
+ virtual Rect2 font_get_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override;
+ virtual void font_set_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) override;
+ GDVIRTUAL3RC(Rect2, _font_get_glyph_uv_rect, RID, const Vector2i &, int32_t);
+ GDVIRTUAL4(_font_set_glyph_uv_rect, RID, const Vector2i &, int32_t, const Rect2 &);
+
+ virtual int font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const override;
+ virtual void font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) override;
+ GDVIRTUAL3RC(int, _font_get_glyph_texture_idx, RID, const Vector2i &, int32_t);
+ GDVIRTUAL4(_font_set_glyph_texture_idx, RID, const Vector2i &, int32_t, int);
+
+ virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const override;
+ GDVIRTUAL3RC(Dictionary, _font_get_glyph_contours, RID, int, int32_t);
+
+ virtual Array font_get_kerning_list(RID p_font_rid, int p_size) const override;
+ virtual void font_clear_kerning_map(RID p_font_rid, int p_size) override;
+ virtual void font_remove_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) override;
+ GDVIRTUAL2RC(Array, _font_get_kerning_list, RID, int);
+ GDVIRTUAL2(_font_clear_kerning_map, RID, int);
+ GDVIRTUAL3(_font_remove_kerning, RID, int, const Vector2i &);
+
+ virtual void font_set_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) override;
+ virtual Vector2 font_get_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) const override;
+ GDVIRTUAL4(_font_set_kerning, RID, int, const Vector2i &, const Vector2 &);
+ GDVIRTUAL3RC(Vector2, _font_get_kerning, RID, int, const Vector2i &);
+
+ virtual int32_t font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector = 0) const override;
+ GDVIRTUAL4RC(int32_t, _font_get_glyph_index, RID, int, char32_t, char32_t);
+
+ virtual bool font_has_char(RID p_font_rid, char32_t p_char) const override;
+ virtual String font_get_supported_chars(RID p_font_rid) const override;
+ GDVIRTUAL2RC(bool, _font_has_char, RID, char32_t);
+ GDVIRTUAL1RC(String, _font_get_supported_chars, RID);
+
+ virtual void font_render_range(RID p_font, const Vector2i &p_size, char32_t p_start, char32_t p_end) override;
+ virtual void font_render_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_index) override;
+ GDVIRTUAL4(_font_render_range, RID, const Vector2i &, char32_t, char32_t);
+ GDVIRTUAL3(_font_render_glyph, RID, const Vector2i &, int32_t);
+
+ virtual void font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
+ virtual void font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, int32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
+ GDVIRTUAL6C(_font_draw_glyph, RID, RID, int, const Vector2 &, int32_t, const Color &);
+ GDVIRTUAL7C(_font_draw_glyph_outline, RID, RID, int, int, const Vector2 &, int32_t, const Color &);
+
+ virtual bool font_is_language_supported(RID p_font_rid, const String &p_language) const override;
+ virtual void font_set_language_support_override(RID p_font_rid, const String &p_language, bool p_supported) override;
+ virtual bool font_get_language_support_override(RID p_font_rid, const String &p_language) override;
+ virtual void font_remove_language_support_override(RID p_font_rid, const String &p_language) override;
+ virtual Vector<String> font_get_language_support_overrides(RID p_font_rid) override;
+ GDVIRTUAL2RC(bool, _font_is_language_supported, RID, const String &);
+ GDVIRTUAL3(_font_set_language_support_override, RID, const String &, bool);
+ GDVIRTUAL2R(bool, _font_get_language_support_override, RID, const String &);
+ GDVIRTUAL2(_font_remove_language_support_override, RID, const String &);
+ GDVIRTUAL1R(Vector<String>, _font_get_language_support_overrides, RID);
+
+ virtual bool font_is_script_supported(RID p_font_rid, const String &p_script) const override;
+ virtual void font_set_script_support_override(RID p_font_rid, const String &p_script, bool p_supported) override;
+ virtual bool font_get_script_support_override(RID p_font_rid, const String &p_script) override;
+ virtual void font_remove_script_support_override(RID p_font_rid, const String &p_script) override;
+ virtual Vector<String> font_get_script_support_overrides(RID p_font_rid) override;
+ GDVIRTUAL2RC(bool, _font_is_script_supported, RID, const String &);
+ GDVIRTUAL3(_font_set_script_support_override, RID, const String &, bool);
+ GDVIRTUAL2R(bool, _font_get_script_support_override, RID, const String &);
+ GDVIRTUAL2(_font_remove_script_support_override, RID, const String &);
+ GDVIRTUAL1R(Vector<String>, _font_get_script_support_overrides, RID);
+
+ virtual Dictionary font_supported_feature_list(RID p_font_rid) const override;
+ virtual Dictionary font_supported_variation_list(RID p_font_rid) const override;
+ GDVIRTUAL1RC(Dictionary, _font_supported_feature_list, RID);
+ GDVIRTUAL1RC(Dictionary, _font_supported_variation_list, RID);
+
+ virtual float font_get_global_oversampling() const override;
+ virtual void font_set_global_oversampling(float p_oversampling) override;
+ GDVIRTUAL0RC(float, _font_get_global_oversampling);
+ GDVIRTUAL1(_font_set_global_oversampling, float);
+
+ virtual Vector2 get_hex_code_box_size(int p_size, char32_t p_index) const override;
+ virtual void draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const override;
+ GDVIRTUAL2RC(Vector2, _get_hex_code_box_size, int, char32_t);
+ GDVIRTUAL5C(_draw_hex_code_box, RID, int, const Vector2 &, char32_t, const Color &);
+
+ /* Shaped text buffer interface */
+
+ virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
+ GDVIRTUAL2R(RID, _create_shaped_text, Direction, Orientation);
+
+ virtual void shaped_text_clear(RID p_shaped) override;
+ GDVIRTUAL1(_shaped_text_clear, RID);
+
+ virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) override;
+ virtual Direction shaped_text_get_direction(RID p_shaped) const override;
+ GDVIRTUAL2(_shaped_text_set_direction, RID, Direction);
+ GDVIRTUAL1RC(/*Direction*/ int, _shaped_text_get_direction, RID);
+
+ virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override;
+ GDVIRTUAL2(_shaped_text_set_bidi_override, RID, const Array &);
+
+ virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
+ virtual Orientation shaped_text_get_orientation(RID p_shaped) const override;
+ GDVIRTUAL2(_shaped_text_set_orientation, RID, Orientation);
+ GDVIRTUAL1RC(/*Orientation*/ int, _shaped_text_get_orientation, RID);
+
+ virtual void shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) override;
+ virtual bool shaped_text_get_preserve_invalid(RID p_shaped) const override;
+ GDVIRTUAL2(_shaped_text_set_preserve_invalid, RID, bool);
+ GDVIRTUAL1RC(bool, _shaped_text_get_preserve_invalid, RID);
+
+ virtual void shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) override;
+ virtual bool shaped_text_get_preserve_control(RID p_shaped) const override;
+ GDVIRTUAL2(_shaped_text_set_preserve_control, RID, bool);
+ GDVIRTUAL1RC(bool, _shaped_text_get_preserve_control, RID);
+
+ virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") override;
+ virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1) override;
+ virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER) override;
+ GDVIRTUAL6R(bool, _shaped_text_add_string, RID, const String &, const Array &, int, const Dictionary &, const String &);
+ GDVIRTUAL5R(bool, _shaped_text_add_object, RID, Variant, const Size2 &, InlineAlign, int);
+ GDVIRTUAL4R(bool, _shaped_text_resize_object, RID, Variant, const Size2 &, InlineAlign);
+
+ virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override;
+ virtual RID shaped_text_get_parent(RID p_shaped) const override;
+ GDVIRTUAL3RC(RID, _shaped_text_substr, RID, int, int);
+ GDVIRTUAL1RC(RID, _shaped_text_get_parent, RID);
+
+ virtual float shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
+ virtual float shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) override;
+ GDVIRTUAL3R(float, _shaped_text_fit_to_width, RID, float, uint16_t);
+ GDVIRTUAL2R(float, _shaped_text_tab_align, RID, const PackedFloat32Array &);
+
+ virtual bool shaped_text_shape(RID p_shaped) override;
+ virtual bool shaped_text_update_breaks(RID p_shaped) override;
+ virtual bool shaped_text_update_justification_ops(RID p_shaped) override;
+ GDVIRTUAL1R(bool, _shaped_text_shape, RID);
+ GDVIRTUAL1R(bool, _shaped_text_update_breaks, RID);
+ GDVIRTUAL1R(bool, _shaped_text_update_justification_ops, RID);
+
+ virtual bool shaped_text_is_ready(RID p_shaped) const override;
+ GDVIRTUAL1RC(bool, _shaped_text_is_ready, RID);
+
+ virtual const Glyph *shaped_text_get_glyphs(RID p_shaped) const override;
+ virtual const Glyph *shaped_text_sort_logical(RID p_shaped) override;
+ virtual int shaped_text_get_glyph_count(RID p_shaped) const override;
+ GDVIRTUAL2C(_shaped_text_get_glyphs, RID, GDNativePtr<const Glyph *>);
+ GDVIRTUAL2(_shaped_text_sort_logical, RID, GDNativePtr<const Glyph *>);
+ GDVIRTUAL1RC(int, _shaped_text_get_glyph_count, RID);
+
+ virtual Vector2i shaped_text_get_range(RID p_shaped) const override;
+ GDVIRTUAL1RC(Vector2i, _shaped_text_get_range, RID);
+
+ virtual PackedInt32Array shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start = 0, bool p_once = true, uint16_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
+ virtual PackedInt32Array shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start = 0, uint16_t p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
+ virtual PackedInt32Array shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const override;
+ GDVIRTUAL5RC(PackedInt32Array, _shaped_text_get_line_breaks_adv, RID, const PackedFloat32Array &, int, bool, uint16_t);
+ GDVIRTUAL4RC(PackedInt32Array, _shaped_text_get_line_breaks, RID, float, int, uint16_t);
+ GDVIRTUAL2RC(PackedInt32Array, _shaped_text_get_word_breaks, RID, int);
+
+ virtual int shaped_text_get_trim_pos(RID p_shaped) const override;
+ virtual int shaped_text_get_ellipsis_pos(RID p_shaped) const override;
+ virtual const Glyph *shaped_text_get_ellipsis_glyphs(RID p_shaped) const override;
+ virtual int shaped_text_get_ellipsis_glyph_count(RID p_shaped) const override;
+ GDVIRTUAL1RC(int, _shaped_text_get_trim_pos, RID);
+ GDVIRTUAL1RC(int, _shaped_text_get_ellipsis_pos, RID);
+ GDVIRTUAL2C(_shaped_text_get_ellipsis_glyphs, RID, GDNativePtr<const Glyph *>);
+ GDVIRTUAL1RC(int, _shaped_text_get_ellipsis_glyph_count, RID);
+
+ virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) override;
+ GDVIRTUAL3(_shaped_text_overrun_trim_to_width, RID, float, uint16_t);
+
+ virtual Array shaped_text_get_objects(RID p_shaped) const override;
+ virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const override;
+ GDVIRTUAL1RC(Array, _shaped_text_get_objects, RID);
+ GDVIRTUAL2RC(Rect2, _shaped_text_get_object_rect, RID, Variant);
+
+ virtual Size2 shaped_text_get_size(RID p_shaped) const override;
+ virtual float shaped_text_get_ascent(RID p_shaped) const override;
+ virtual float shaped_text_get_descent(RID p_shaped) const override;
+ virtual float shaped_text_get_width(RID p_shaped) const override;
+ virtual float shaped_text_get_underline_position(RID p_shaped) const override;
+ virtual float shaped_text_get_underline_thickness(RID p_shaped) const override;
+ GDVIRTUAL1RC(Size2, _shaped_text_get_size, RID);
+ GDVIRTUAL1RC(float, _shaped_text_get_ascent, RID);
+ GDVIRTUAL1RC(float, _shaped_text_get_descent, RID);
+ GDVIRTUAL1RC(float, _shaped_text_get_width, RID);
+ GDVIRTUAL1RC(float, _shaped_text_get_underline_position, RID);
+ GDVIRTUAL1RC(float, _shaped_text_get_underline_thickness, RID);
+
+ virtual Direction shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const override;
+ GDVIRTUAL3RC(int, _shaped_text_get_dominant_direction_in_range, RID, int, int);
+
+ virtual CaretInfo shaped_text_get_carets(RID p_shaped, int p_position) const override;
+ virtual Vector<Vector2> shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const override;
+ GDVIRTUAL3C(_shaped_text_get_carets, RID, int, GDNativePtr<CaretInfo>);
+ GDVIRTUAL3RC(Vector<Vector2>, _shaped_text_get_selection, RID, int, int);
+
+ virtual int shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const override;
+ virtual int shaped_text_hit_test_position(RID p_shaped, float p_coords) const override;
+ GDVIRTUAL2RC(int, _shaped_text_hit_test_grapheme, RID, float);
+ GDVIRTUAL2RC(int, _shaped_text_hit_test_position, RID, float);
+
+ virtual void shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, const Color &p_color = Color(1, 1, 1)) const override;
+ virtual void shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const override;
+ GDVIRTUAL6C(_shaped_text_draw, RID, RID, const Vector2 &, float, float, const Color &);
+ GDVIRTUAL7C(_shaped_text_draw_outline, RID, RID, const Vector2 &, float, float, int, const Color &);
+
+ virtual int shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const override;
+ virtual int shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const override;
+ GDVIRTUAL2RC(int, _shaped_text_next_grapheme_pos, RID, int);
+ GDVIRTUAL2RC(int, _shaped_text_prev_grapheme_pos, RID, int);
+
+ virtual String format_number(const String &p_string, const String &p_language = "") const override;
+ virtual String parse_number(const String &p_string, const String &p_language = "") const override;
+ virtual String percent_sign(const String &p_language = "") const override;
+ GDVIRTUAL2RC(String, _format_number, const String &, const String &);
+ GDVIRTUAL2RC(String, _parse_number, const String &, const String &);
+ GDVIRTUAL1RC(String, _percent_sign, const String &);
+
+ TextServerExtension();
+ ~TextServerExtension();
+};
+
+#endif // TEXT_SERVER_EXTENSION_H
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index 4886a6f582..a365fde64a 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -32,122 +32,108 @@
#include "scene/main/canvas_item.h"
TextServerManager *TextServerManager::singleton = nullptr;
-TextServer *TextServerManager::server = nullptr;
-TextServerManager::TextServerCreate TextServerManager::server_create_functions[TextServerManager::MAX_SERVERS];
-int TextServerManager::server_create_count = 0;
void TextServerManager::_bind_methods() {
- ClassDB::bind_method(D_METHOD("get_interface_count"), &TextServerManager::_get_interface_count);
- ClassDB::bind_method(D_METHOD("get_interface_name", "index"), &TextServerManager::_get_interface_name);
- ClassDB::bind_method(D_METHOD("get_interface_features", "index"), &TextServerManager::_get_interface_features);
- ClassDB::bind_method(D_METHOD("get_interface", "index"), &TextServerManager::_get_interface);
- ClassDB::bind_method(D_METHOD("get_interfaces"), &TextServerManager::_get_interfaces);
- ClassDB::bind_method(D_METHOD("find_interface", "name"), &TextServerManager::_find_interface);
-
- ClassDB::bind_method(D_METHOD("set_primary_interface", "index"), &TextServerManager::_set_primary_interface);
+ ClassDB::bind_method(D_METHOD("add_interface", "interface"), &TextServerManager::add_interface);
+ ClassDB::bind_method(D_METHOD("get_interface_count"), &TextServerManager::get_interface_count);
+ ClassDB::bind_method(D_METHOD("remove_interface", "interface"), &TextServerManager::remove_interface);
+ ClassDB::bind_method(D_METHOD("get_interface", "idx"), &TextServerManager::get_interface);
+ ClassDB::bind_method(D_METHOD("get_interfaces"), &TextServerManager::get_interfaces);
+ ClassDB::bind_method(D_METHOD("find_interface", "name"), &TextServerManager::find_interface);
+
+ ClassDB::bind_method(D_METHOD("set_primary_interface", "index"), &TextServerManager::set_primary_interface);
ClassDB::bind_method(D_METHOD("get_primary_interface"), &TextServerManager::_get_primary_interface);
-}
-void TextServerManager::register_create_function(const String &p_name, uint32_t p_features, TextServerManager::CreateFunction p_function, void *p_user_data) {
- ERR_FAIL_COND(server_create_count == MAX_SERVERS);
- server_create_functions[server_create_count].name = p_name;
- server_create_functions[server_create_count].create_function = p_function;
- server_create_functions[server_create_count].user_data = p_user_data;
- server_create_functions[server_create_count].features = p_features;
- server_create_count++;
+ ADD_SIGNAL(MethodInfo("interface_added", PropertyInfo(Variant::STRING_NAME, "interface_name")));
+ ADD_SIGNAL(MethodInfo("interface_removed", PropertyInfo(Variant::STRING_NAME, "interface_name")));
}
-int TextServerManager::get_interface_count() {
- return server_create_count;
-}
+void TextServerManager::add_interface(const Ref<TextServer> &p_interface) {
+ ERR_FAIL_COND(p_interface.is_null());
-String TextServerManager::get_interface_name(int p_index) {
- ERR_FAIL_INDEX_V(p_index, server_create_count, String());
- return server_create_functions[p_index].name;
-}
+ for (int i = 0; i < interfaces.size(); i++) {
+ if (interfaces[i] == p_interface) {
+ ERR_PRINT("TextServer: Interface was already added.");
+ return;
+ };
+ };
-uint32_t TextServerManager::get_interface_features(int p_index) {
- ERR_FAIL_INDEX_V(p_index, server_create_count, 0);
- return server_create_functions[p_index].features;
+ interfaces.push_back(p_interface);
+ print_verbose("TextServer: Added interface \"" + p_interface->get_name() + "\"");
+ emit_signal(SNAME("interface_added"), p_interface->get_name());
}
-TextServer *TextServerManager::initialize(int p_index, Error &r_error) {
- ERR_FAIL_INDEX_V(p_index, server_create_count, nullptr);
- if (server_create_functions[p_index].instance == nullptr) {
- server_create_functions[p_index].instance = server_create_functions[p_index].create_function(r_error, server_create_functions[p_index].user_data);
- if (server_create_functions[p_index].instance != nullptr) {
- server_create_functions[p_index].instance->load_support_data(""); // Try loading default data.
- }
- }
- if (server_create_functions[p_index].instance != nullptr) {
- server = server_create_functions[p_index].instance;
- if (OS::get_singleton()->get_main_loop()) {
- OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TEXT_SERVER_CHANGED);
- }
- }
- return server_create_functions[p_index].instance;
-}
+void TextServerManager::remove_interface(const Ref<TextServer> &p_interface) {
+ ERR_FAIL_COND(p_interface.is_null());
+ ERR_FAIL_COND_MSG(p_interface == primary_interface, "TextServer: Can't remove primary interface.");
-TextServer *TextServerManager::get_primary_interface() {
- return server;
-}
+ int idx = -1;
+ for (int i = 0; i < interfaces.size(); i++) {
+ if (interfaces[i] == p_interface) {
+ idx = i;
+ break;
+ };
+ };
-int TextServerManager::_get_interface_count() const {
- return server_create_count;
+ ERR_FAIL_COND(idx == -1);
+ print_verbose("TextServer: Removed interface \"" + p_interface->get_name() + "\"");
+ emit_signal(SNAME("interface_removed"), p_interface->get_name());
+ interfaces.remove(idx);
}
-String TextServerManager::_get_interface_name(int p_index) const {
- return get_interface_name(p_index);
+int TextServerManager::get_interface_count() const {
+ return interfaces.size();
}
-uint32_t TextServerManager::_get_interface_features(int p_index) const {
- return get_interface_features(p_index);
+Ref<TextServer> TextServerManager::get_interface(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, interfaces.size(), nullptr);
+ return interfaces[p_index];
}
-TextServer *TextServerManager::_get_interface(int p_index) const {
- ERR_FAIL_INDEX_V(p_index, server_create_count, nullptr);
- if (server_create_functions[p_index].instance == nullptr) {
- Error error;
- server_create_functions[p_index].instance = server_create_functions[p_index].create_function(error, server_create_functions[p_index].user_data);
- if (server_create_functions[p_index].instance != nullptr) {
- server_create_functions[p_index].instance->load_support_data(""); // Try loading default data.
- }
- }
- return server_create_functions[p_index].instance;
-}
+Ref<TextServer> TextServerManager::find_interface(const String &p_name) const {
+ int idx = -1;
+ for (int i = 0; i < interfaces.size(); i++) {
+ if (interfaces[i]->get_name() == p_name) {
+ idx = i;
+ break;
+ };
+ };
-TextServer *TextServerManager::_find_interface(const String &p_name) const {
- for (int i = 0; i < server_create_count; i++) {
- if (server_create_functions[i].name == p_name) {
- return _get_interface(i);
- }
- }
- return nullptr;
+ ERR_FAIL_COND_V(idx == -1, nullptr);
+ return interfaces[idx];
}
-Array TextServerManager::_get_interfaces() const {
+Array TextServerManager::get_interfaces() const {
Array ret;
- for (int i = 0; i < server_create_count; i++) {
+ for (int i = 0; i < interfaces.size(); i++) {
Dictionary iface_info;
iface_info["id"] = i;
- iface_info["name"] = server_create_functions[i].name;
+ iface_info["name"] = interfaces[i]->get_name();
ret.push_back(iface_info);
};
return ret;
-};
+}
-bool TextServerManager::_set_primary_interface(int p_index) {
- Error error;
- TextServerManager::initialize(p_index, error);
- return (error == OK);
+Ref<TextServer> TextServerManager::_get_primary_interface() const {
+ return primary_interface;
}
-TextServer *TextServerManager::_get_primary_interface() const {
- return server;
+void TextServerManager::set_primary_interface(const Ref<TextServer> &p_primary_interface) {
+ if (p_primary_interface.is_null()) {
+ print_verbose("TextServer: Clearing primary interface");
+ primary_interface.unref();
+ } else {
+ primary_interface = p_primary_interface;
+ print_verbose("TextServer: Primary interface set to: \"" + primary_interface->get_name() + "\".");
+
+ if (OS::get_singleton()->get_main_loop()) {
+ OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TEXT_SERVER_CHANGED);
+ }
+ }
}
TextServerManager::TextServerManager() {
@@ -155,29 +141,29 @@ TextServerManager::TextServerManager() {
}
TextServerManager::~TextServerManager() {
- singleton = nullptr;
- for (int i = 0; i < server_create_count; i++) {
- if (server_create_functions[i].instance != nullptr) {
- memdelete(server_create_functions[i].instance);
- server_create_functions[i].instance = nullptr;
- }
+ if (primary_interface.is_valid()) {
+ primary_interface.unref();
}
+ while (interfaces.size() > 0) {
+ interfaces.remove(0);
+ }
+ singleton = nullptr;
}
/*************************************************************************/
-bool TextServer::Glyph::operator==(const Glyph &p_a) const {
+bool Glyph::operator==(const Glyph &p_a) const {
return (p_a.index == index) && (p_a.font_rid == font_rid) && (p_a.font_size == font_size) && (p_a.start == start);
}
-bool TextServer::Glyph::operator!=(const Glyph &p_a) const {
+bool Glyph::operator!=(const Glyph &p_a) const {
return (p_a.index != index) || (p_a.font_rid != font_rid) || (p_a.font_size != font_size) || (p_a.start != start);
}
-bool TextServer::Glyph::operator<(const Glyph &p_a) const {
+bool Glyph::operator<(const Glyph &p_a) const {
if (p_a.start == start) {
if (p_a.count == count) {
- if ((p_a.flags & GRAPHEME_IS_VIRTUAL) == GRAPHEME_IS_VIRTUAL) {
+ if ((p_a.flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL) {
return true;
} else {
return false;
@@ -188,10 +174,10 @@ bool TextServer::Glyph::operator<(const Glyph &p_a) const {
return p_a.start < start;
}
-bool TextServer::Glyph::operator>(const Glyph &p_a) const {
+bool Glyph::operator>(const Glyph &p_a) const {
if (p_a.start == start) {
if (p_a.count == count) {
- if ((p_a.flags & GRAPHEME_IS_VIRTUAL) == GRAPHEME_IS_VIRTUAL) {
+ if ((p_a.flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL) {
return false;
} else {
return true;
@@ -205,8 +191,13 @@ bool TextServer::Glyph::operator>(const Glyph &p_a) const {
void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_feature", "feature"), &TextServer::has_feature);
ClassDB::bind_method(D_METHOD("get_name"), &TextServer::get_name);
+ ClassDB::bind_method(D_METHOD("get_features"), &TextServer::get_features);
ClassDB::bind_method(D_METHOD("load_support_data", "filename"), &TextServer::load_support_data);
+ ClassDB::bind_method(D_METHOD("get_support_data_filename"), &TextServer::get_support_data_filename);
+ ClassDB::bind_method(D_METHOD("get_support_data_info"), &TextServer::get_support_data_info);
+ ClassDB::bind_method(D_METHOD("save_support_data", "filename"), &TextServer::save_support_data);
+
ClassDB::bind_method(D_METHOD("is_locale_right_to_left", "locale"), &TextServer::is_locale_right_to_left);
ClassDB::bind_method(D_METHOD("name_to_tag", "name"), &TextServer::name_to_tag);
@@ -219,7 +210,7 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_font"), &TextServer::create_font);
- ClassDB::bind_method(D_METHOD("font_set_data", "data"), &TextServer::font_set_data);
+ ClassDB::bind_method(D_METHOD("font_set_data", "font_rid", "data"), &TextServer::font_set_data);
ClassDB::bind_method(D_METHOD("font_set_antialiased", "font_rid", "antialiased"), &TextServer::font_set_antialiased);
ClassDB::bind_method(D_METHOD("font_is_antialiased", "font_rid"), &TextServer::font_is_antialiased);
@@ -299,7 +290,7 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("font_get_glyph_texture_idx", "font_rid", "size", "glyph"), &TextServer::font_get_glyph_texture_idx);
ClassDB::bind_method(D_METHOD("font_set_glyph_texture_idx", "font_rid", "size", "glyph", "texture_idx"), &TextServer::font_set_glyph_texture_idx);
- ClassDB::bind_method(D_METHOD("font_get_glyph_contours", "font", "size", "index"), &TextServer::_font_get_glyph_contours);
+ ClassDB::bind_method(D_METHOD("font_get_glyph_contours", "font", "size", "index"), &TextServer::font_get_glyph_contours);
ClassDB::bind_method(D_METHOD("font_get_kerning_list", "font_rid", "size"), &TextServer::font_get_kerning_list);
ClassDB::bind_method(D_METHOD("font_clear_kerning_map", "font_rid", "size"), &TextServer::font_clear_kerning_map);
@@ -349,7 +340,7 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("shaped_text_set_direction", "shaped", "direction"), &TextServer::shaped_text_set_direction, DEFVAL(DIRECTION_AUTO));
ClassDB::bind_method(D_METHOD("shaped_text_get_direction", "shaped"), &TextServer::shaped_text_get_direction);
- ClassDB::bind_method(D_METHOD("shaped_text_set_bidi_override", "shaped", "override"), &TextServer::_shaped_text_set_bidi_override);
+ ClassDB::bind_method(D_METHOD("shaped_text_set_bidi_override", "shaped", "override"), &TextServer::shaped_text_set_bidi_override);
ClassDB::bind_method(D_METHOD("shaped_text_set_orientation", "shaped", "orientation"), &TextServer::shaped_text_set_orientation, DEFVAL(ORIENTATION_HORIZONTAL));
ClassDB::bind_method(D_METHOD("shaped_text_get_orientation", "shaped"), &TextServer::shaped_text_get_orientation);
@@ -372,12 +363,19 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("shaped_text_shape", "shaped"), &TextServer::shaped_text_shape);
ClassDB::bind_method(D_METHOD("shaped_text_is_ready", "shaped"), &TextServer::shaped_text_is_ready);
- ClassDB::bind_method(D_METHOD("shaped_text_get_glyphs", "shaped"), &TextServer::_shaped_text_get_glyphs);
+ ClassDB::bind_method(D_METHOD("shaped_text_get_glyphs", "shaped"), &TextServer::_shaped_text_get_glyphs_wrapper);
+ ClassDB::bind_method(D_METHOD("shaped_text_sort_logical", "shaped"), &TextServer::_shaped_text_sort_logical_wrapper);
+ ClassDB::bind_method(D_METHOD("shaped_text_get_glyph_count", "shaped"), &TextServer::shaped_text_get_glyph_count);
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"), &TextServer::_shaped_text_get_word_breaks);
+ 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);
+
+ 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);
+ ClassDB::bind_method(D_METHOD("shaped_text_get_ellipsis_glyphs", "shaped"), &TextServer::_shaped_text_get_ellipsis_glyphs_wrapper);
+ ClassDB::bind_method(D_METHOD("shaped_text_get_ellipsis_glyph_count", "shaped"), &TextServer::shaped_text_get_ellipsis_glyph_count);
ClassDB::bind_method(D_METHOD("shaped_text_overrun_trim_to_width", "shaped", "width", "overrun_trim_flags"), &TextServer::shaped_text_overrun_trim_to_width, DEFVAL(0), DEFVAL(OVERRUN_NO_TRIMMING));
@@ -391,8 +389,8 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("shaped_text_get_underline_position", "shaped"), &TextServer::shaped_text_get_underline_position);
ClassDB::bind_method(D_METHOD("shaped_text_get_underline_thickness", "shaped"), &TextServer::shaped_text_get_underline_thickness);
- ClassDB::bind_method(D_METHOD("shaped_text_get_carets", "shaped", "position"), &TextServer::_shaped_text_get_carets);
- ClassDB::bind_method(D_METHOD("shaped_text_get_selection", "shaped", "start", "end"), &TextServer::_shaped_text_get_selection);
+ ClassDB::bind_method(D_METHOD("shaped_text_get_carets", "shaped", "position"), &TextServer::_shaped_text_get_carets_wrapper);
+ ClassDB::bind_method(D_METHOD("shaped_text_get_selection", "shaped", "start", "end"), &TextServer::shaped_text_get_selection);
ClassDB::bind_method(D_METHOD("shaped_text_hit_test_grapheme", "shaped", "coords"), &TextServer::shaped_text_hit_test_grapheme);
ClassDB::bind_method(D_METHOD("shaped_text_hit_test_position", "shaped", "coords"), &TextServer::shaped_text_hit_test_position);
@@ -403,7 +401,7 @@ void TextServer::_bind_methods() {
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)));
- ClassDB::bind_method(D_METHOD("shaped_text_get_dominant_direciton_in_range", "shaped", "start", "end"), &TextServer::shaped_text_get_dominant_direciton_in_range);
+ ClassDB::bind_method(D_METHOD("shaped_text_get_dominant_direction_in_range", "shaped", "start", "end"), &TextServer::shaped_text_get_dominant_direction_in_range);
ClassDB::bind_method(D_METHOD("format_number", "number", "language"), &TextServer::format_number, DEFVAL(""));
ClassDB::bind_method(D_METHOD("parse_number", "number", "language"), &TextServer::parse_number, DEFVAL(""));
@@ -424,12 +422,14 @@ void TextServer::_bind_methods() {
BIND_ENUM_CONSTANT(JUSTIFICATION_WORD_BOUND);
BIND_ENUM_CONSTANT(JUSTIFICATION_TRIM_EDGE_SPACES);
BIND_ENUM_CONSTANT(JUSTIFICATION_AFTER_LAST_TAB);
+ BIND_ENUM_CONSTANT(JUSTIFICATION_CONSTRAIN_ELLIPSIS);
/* LineBreakFlag */
BIND_ENUM_CONSTANT(BREAK_NONE);
BIND_ENUM_CONSTANT(BREAK_MANDATORY);
BIND_ENUM_CONSTANT(BREAK_WORD_BOUND);
BIND_ENUM_CONSTANT(BREAK_GRAPHEME_BOUND);
+ BIND_ENUM_CONSTANT(BREAK_WORD_BOUND_ADAPTIVE);
/* TextOverrunFlag */
BIND_ENUM_CONSTANT(OVERRUN_NO_TRIMMING);
@@ -437,8 +437,10 @@ void TextServer::_bind_methods() {
BIND_ENUM_CONSTANT(OVERRUN_TRIM_WORD_ONLY);
BIND_ENUM_CONSTANT(OVERRUN_ADD_ELLIPSIS);
BIND_ENUM_CONSTANT(OVERRUN_ENFORCE_ELLIPSIS);
+ BIND_ENUM_CONSTANT(OVERRUN_JUSTIFICATION_AWARE);
/* GraphemeFlag */
+ BIND_ENUM_CONSTANT(GRAPHEME_IS_VALID);
BIND_ENUM_CONSTANT(GRAPHEME_IS_RTL);
BIND_ENUM_CONSTANT(GRAPHEME_IS_VIRTUAL);
BIND_ENUM_CONSTANT(GRAPHEME_IS_SPACE);
@@ -578,6 +580,9 @@ void TextServer::draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_po
int fnt = (p_size < 20) ? 0 : 1;
ERR_FAIL_COND(hex_code_box_font_tex[fnt].is_null());
+ if (p_index == 0) {
+ return;
+ }
uint8_t a = p_index & 0x0F;
uint8_t b = (p_index >> 4) & 0x0F;
@@ -592,12 +597,12 @@ void TextServer::draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_po
real_t w = ((p_index <= 0xFF) ? 1 : ((p_index <= 0xFFFF) ? 2 : 3)) * hex_code_box_font_size[fnt].x;
real_t h = 2 * hex_code_box_font_size[fnt].y;
- pos.y -= Math::floor((h + 3 + hex_code_box_font_size[fnt].z) * 0.75);
+ pos.y -= Math::floor((h + 3 + hex_code_box_font_size[fnt].z));
RenderingServer::get_singleton()->canvas_item_add_rect(p_canvas, Rect2(pos + Point2(0, 0), Size2(1, h + 2 + 2 * hex_code_box_font_size[fnt].z)), p_color);
RenderingServer::get_singleton()->canvas_item_add_rect(p_canvas, Rect2(pos + Point2(w + 2, 0), Size2(1, h + 2 + 2 * hex_code_box_font_size[fnt].z)), p_color);
- RenderingServer::get_singleton()->canvas_item_add_rect(p_canvas, Rect2(pos + Point2(0, 0), Size2(w + 2, 1)), p_color);
- RenderingServer::get_singleton()->canvas_item_add_rect(p_canvas, Rect2(pos + Point2(0, h + 2 + 2 * hex_code_box_font_size[fnt].z), Size2(w + 2, 1)), p_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(p_canvas, Rect2(pos + Point2(0, 0), Size2(w + 3, 1)), p_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(p_canvas, Rect2(pos + Point2(0, h + 2 + 2 * hex_code_box_font_size[fnt].z), Size2(w + 3, 1)), p_color);
pos += Point2(2, 2);
if (p_index <= 0xFF) {
@@ -630,13 +635,12 @@ void TextServer::draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_po
}
}
-Vector<Vector2i> TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const Vector<real_t> &p_width, int p_start, bool p_once, uint8_t /*TextBreakFlag*/ p_break_flags) const {
- Vector<Vector2i> lines;
+PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start, bool p_once, uint16_t /*TextBreakFlag*/ p_break_flags) const {
+ PackedInt32Array lines;
ERR_FAIL_COND_V(p_width.is_empty(), lines);
const_cast<TextServer *>(this)->shaped_text_update_breaks(p_shaped);
- const Vector<Glyph> &logical = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped);
const Vector2i &range = shaped_text_get_range(p_shaped);
real_t width = 0.f;
@@ -644,8 +648,8 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const
int last_safe_break = -1;
int chunk = 0;
- int l_size = logical.size();
- const Glyph *l_gl = logical.ptr();
+ int l_size = shaped_text_get_glyph_count(p_shaped);
+ const Glyph *l_gl = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped);
for (int i = 0; i < l_size; i++) {
if (l_gl[i].start < p_start) {
@@ -653,7 +657,8 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const
}
if (l_gl[i].count > 0) {
if ((p_width[chunk] > 0) && (width + l_gl[i].advance > p_width[chunk]) && (last_safe_break >= 0)) {
- lines.push_back(Vector2i(line_start, l_gl[last_safe_break].end));
+ lines.push_back(line_start);
+ lines.push_back(l_gl[last_safe_break].end);
line_start = l_gl[last_safe_break].end;
i = last_safe_break;
last_safe_break = -1;
@@ -669,7 +674,8 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const
}
if ((p_break_flags & BREAK_MANDATORY) == BREAK_MANDATORY) {
if ((l_gl[i].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD) {
- lines.push_back(Vector2i(line_start, l_gl[i].end));
+ lines.push_back(line_start);
+ lines.push_back(l_gl[i].end);
line_start = l_gl[i].end;
last_safe_break = -1;
width = 0;
@@ -693,27 +699,31 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const
}
if (l_size > 0) {
- lines.push_back(Vector2i(line_start, range.y));
+ if (lines.size() == 0 || lines[lines.size() - 1] < range.y) {
+ lines.push_back(line_start);
+ lines.push_back(range.y);
+ }
} else {
- lines.push_back(Vector2i(0, 0));
+ lines.push_back(0);
+ lines.push_back(0);
}
return lines;
}
-Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start, uint8_t /*TextBreakFlag*/ p_break_flags) const {
- Vector<Vector2i> lines;
+PackedInt32Array TextServer::shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start, uint16_t /*TextBreakFlag*/ p_break_flags) const {
+ PackedInt32Array lines;
const_cast<TextServer *>(this)->shaped_text_update_breaks(p_shaped);
- const Vector<Glyph> &logical = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped);
const Vector2i &range = shaped_text_get_range(p_shaped);
real_t width = 0.f;
int line_start = MAX(p_start, range.x);
int last_safe_break = -1;
int word_count = 0;
- int l_size = logical.size();
- const Glyph *l_gl = logical.ptr();
+
+ int l_size = shaped_text_get_glyph_count(p_shaped);
+ const Glyph *l_gl = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped);
for (int i = 0; i < l_size; i++) {
if (l_gl[i].start < p_start) {
@@ -721,7 +731,8 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, real_t p_
}
if (l_gl[i].count > 0) {
if ((p_width > 0) && (width + l_gl[i].advance * l_gl[i].repeat > p_width) && (last_safe_break >= 0)) {
- lines.push_back(Vector2i(line_start, l_gl[last_safe_break].end));
+ lines.push_back(line_start);
+ lines.push_back(l_gl[last_safe_break].end);
line_start = l_gl[last_safe_break].end;
i = last_safe_break;
last_safe_break = -1;
@@ -731,7 +742,8 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, real_t p_
}
if ((p_break_flags & BREAK_MANDATORY) == BREAK_MANDATORY) {
if ((l_gl[i].flags & GRAPHEME_IS_BREAK_HARD) == GRAPHEME_IS_BREAK_HARD) {
- lines.push_back(Vector2i(line_start, l_gl[i].end));
+ lines.push_back(line_start);
+ lines.push_back(l_gl[i].end);
line_start = l_gl[i].end;
last_safe_break = -1;
width = 0;
@@ -755,51 +767,49 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, real_t p_
}
if (l_size > 0) {
- if (lines.size() == 0 || lines[lines.size() - 1].y < range.y) {
- lines.push_back(Vector2i(line_start, range.y));
+ if (lines.size() == 0 || lines[lines.size() - 1] < range.y) {
+ lines.push_back(line_start);
+ lines.push_back(range.y);
}
} else {
- lines.push_back(Vector2i(0, 0));
+ lines.push_back(0);
+ lines.push_back(0);
}
return lines;
}
-Vector<Vector2i> TextServer::shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags) const {
- Vector<Vector2i> words;
+PackedInt32Array TextServer::shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags) const {
+ PackedInt32Array words;
const_cast<TextServer *>(this)->shaped_text_update_justification_ops(p_shaped);
- const Vector<Glyph> &logical = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped);
const Vector2i &range = shaped_text_get_range(p_shaped);
int word_start = range.x;
- int l_size = logical.size();
- const Glyph *l_gl = logical.ptr();
+ int l_size = shaped_text_get_glyph_count(p_shaped);
+ const Glyph *l_gl = const_cast<TextServer *>(this)->shaped_text_sort_logical(p_shaped);
for (int i = 0; i < l_size; i++) {
if (l_gl[i].count > 0) {
if ((l_gl[i].flags & p_grapheme_flags) != 0) {
- words.push_back(Vector2i(word_start, l_gl[i].start));
+ words.push_back(word_start);
+ words.push_back(l_gl[i].start);
word_start = l_gl[i].end;
}
}
}
if (l_size > 0) {
- words.push_back(Vector2i(word_start, range.y));
+ words.push_back(word_start);
+ words.push_back(range.y);
}
return words;
}
-TextServer::TrimData TextServer::shaped_text_get_trim_data(RID p_shaped) const {
- WARN_PRINT("Getting overrun data not supported by this TextServer.");
- return TrimData();
-}
-
-void TextServer::shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_leading_caret, Direction &p_leading_dir, Rect2 &p_trailing_caret, Direction &p_trailing_dir) const {
+CaretInfo TextServer::shaped_text_get_carets(RID p_shaped, int p_position) const {
Vector<Rect2> carets;
- const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped);
+
TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped);
const Vector2 &range = shaped_text_get_range(p_shaped);
real_t ascent = shaped_text_get_ascent(p_shaped);
@@ -807,11 +817,12 @@ void TextServer::shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_l
real_t height = (ascent + descent) / 2;
real_t off = 0.0f;
- p_leading_dir = DIRECTION_AUTO;
- p_trailing_dir = DIRECTION_AUTO;
+ CaretInfo caret;
+ caret.l_dir = DIRECTION_AUTO;
+ caret.t_dir = DIRECTION_AUTO;
- int v_size = visual.size();
- const Glyph *glyphs = visual.ptr();
+ int v_size = shaped_text_get_glyph_count(p_shaped);
+ const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
for (int i = 0; i < v_size; i++) {
if (glyphs[i].count > 0) {
@@ -827,13 +838,13 @@ void TextServer::shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_l
cr.position.y = -ascent;
cr.position.x = off;
if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) {
- p_trailing_dir = DIRECTION_RTL;
+ caret.t_dir = DIRECTION_RTL;
for (int j = 0; j < glyphs[i].count; j++) {
cr.position.x += glyphs[i + j].advance * glyphs[i + j].repeat;
cr.size.x -= glyphs[i + j].advance * glyphs[i + j].repeat;
}
} else {
- p_trailing_dir = DIRECTION_LTR;
+ caret.t_dir = DIRECTION_LTR;
for (int j = 0; j < glyphs[i].count; j++) {
cr.size.x += glyphs[i + j].advance * glyphs[i + j].repeat;
}
@@ -847,19 +858,19 @@ void TextServer::shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_l
cr.position.x = -ascent;
cr.position.y = off;
if ((glyphs[i].flags & GRAPHEME_IS_RTL) == GRAPHEME_IS_RTL) {
- p_trailing_dir = DIRECTION_RTL;
+ caret.t_dir = DIRECTION_RTL;
for (int j = 0; j < glyphs[i].count; j++) {
cr.position.y += glyphs[i + j].advance * glyphs[i + j].repeat;
cr.size.y -= glyphs[i + j].advance * glyphs[i + j].repeat;
}
} else {
- p_trailing_dir = DIRECTION_LTR;
+ caret.t_dir = DIRECTION_LTR;
for (int j = 0; j < glyphs[i].count; j++) {
cr.size.y += glyphs[i + j].advance * glyphs[i + j].repeat;
}
}
}
- p_trailing_caret = cr;
+ caret.t_caret = cr;
}
// Caret after grapheme (bottom / right).
if (p_position == glyphs[i].end && ((glyphs[i].flags & GRAPHEME_IS_VIRTUAL) != GRAPHEME_IS_VIRTUAL)) {
@@ -874,13 +885,13 @@ void TextServer::shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_l
}
cr.position.x = off;
if ((glyphs[i].flags & GRAPHEME_IS_RTL) != GRAPHEME_IS_RTL) {
- p_leading_dir = DIRECTION_LTR;
+ caret.l_dir = DIRECTION_LTR;
for (int j = 0; j < glyphs[i].count; j++) {
cr.position.x += glyphs[i + j].advance * glyphs[i + j].repeat;
cr.size.x -= glyphs[i + j].advance * glyphs[i + j].repeat;
}
} else {
- p_leading_dir = DIRECTION_RTL;
+ caret.l_dir = DIRECTION_RTL;
for (int j = 0; j < glyphs[i].count; j++) {
cr.size.x += glyphs[i + j].advance * glyphs[i + j].repeat;
}
@@ -896,19 +907,19 @@ void TextServer::shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_l
}
cr.position.y = off;
if ((glyphs[i].flags & GRAPHEME_IS_RTL) != GRAPHEME_IS_RTL) {
- p_leading_dir = DIRECTION_LTR;
+ caret.l_dir = DIRECTION_LTR;
for (int j = 0; j < glyphs[i].count; j++) {
cr.position.y += glyphs[i + j].advance * glyphs[i + j].repeat;
cr.size.y -= glyphs[i + j].advance * glyphs[i + j].repeat;
}
} else {
- p_leading_dir = DIRECTION_RTL;
+ caret.l_dir = DIRECTION_RTL;
for (int j = 0; j < glyphs[i].count; j++) {
cr.size.y += glyphs[i + j].advance * glyphs[i + j].repeat;
}
}
}
- p_leading_caret = cr;
+ caret.l_caret = cr;
}
// Caret inside grapheme (middle).
if (p_position > glyphs[i].start && p_position < glyphs[i].end && (glyphs[i].flags & GRAPHEME_IS_VIRTUAL) != GRAPHEME_IS_VIRTUAL) {
@@ -937,17 +948,29 @@ void TextServer::shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_l
cr.position.y = off + char_adv * (p_position - glyphs[i].start);
}
}
- p_trailing_caret = cr;
- p_leading_caret = cr;
+ caret.t_caret = cr;
+ caret.l_caret = cr;
}
}
off += glyphs[i].advance * glyphs[i].repeat;
}
+ return caret;
}
-TextServer::Direction TextServer::shaped_text_get_dominant_direciton_in_range(RID p_shaped, int p_start, int p_end) const {
- const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped);
+Dictionary TextServer::_shaped_text_get_carets_wrapper(RID p_shaped, int p_position) const {
+ Dictionary ret;
+
+ CaretInfo caret = shaped_text_get_carets(p_shaped, p_position);
+
+ ret["leading_rect"] = caret.l_caret;
+ ret["leading_direction"] = caret.l_dir;
+ ret["trailing_rect"] = caret.t_caret;
+ ret["trailing_direction"] = caret.t_dir;
+
+ return ret;
+}
+TextServer::Direction TextServer::shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const {
if (p_start == p_end) {
return DIRECTION_AUTO;
}
@@ -958,8 +981,8 @@ TextServer::Direction TextServer::shaped_text_get_dominant_direciton_in_range(RI
int rtl = 0;
int ltr = 0;
- int v_size = visual.size();
- const Glyph *glyphs = visual.ptr();
+ int v_size = shaped_text_get_glyph_count(p_shaped);
+ const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
for (int i = 0; i < v_size; i++) {
if ((glyphs[i].end > start) && (glyphs[i].start < end)) {
@@ -983,7 +1006,6 @@ TextServer::Direction TextServer::shaped_text_get_dominant_direciton_in_range(RI
Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const {
Vector<Vector2> ranges;
- const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped);
if (p_start == p_end) {
return ranges;
@@ -992,8 +1014,8 @@ Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start,
int start = MIN(p_start, p_end);
int end = MAX(p_start, p_end);
- int v_size = visual.size();
- const Glyph *glyphs = visual.ptr();
+ int v_size = shaped_text_get_glyph_count(p_shaped);
+ const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
real_t off = 0.0f;
for (int i = 0; i < v_size; i++) {
@@ -1076,13 +1098,11 @@ Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start,
}
int TextServer::shaped_text_hit_test_grapheme(RID p_shaped, real_t p_coords) const {
- const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped);
-
// Exact grapheme hit test, return -1 if missed.
real_t off = 0.0f;
- int v_size = visual.size();
- const Glyph *glyphs = visual.ptr();
+ int v_size = shaped_text_get_glyph_count(p_shaped);
+ const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
for (int i = 0; i < v_size; i++) {
for (int j = 0; j < glyphs[i].repeat; j++) {
@@ -1096,10 +1116,8 @@ int TextServer::shaped_text_hit_test_grapheme(RID p_shaped, real_t p_coords) con
}
int TextServer::shaped_text_hit_test_position(RID p_shaped, real_t p_coords) const {
- const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped);
-
- int v_size = visual.size();
- const Glyph *glyphs = visual.ptr();
+ int v_size = shaped_text_get_glyph_count(p_shaped);
+ const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
// Cursor placement hit test.
@@ -1165,10 +1183,9 @@ int TextServer::shaped_text_hit_test_position(RID p_shaped, real_t p_coords) con
return 0;
}
-int TextServer::shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) {
- const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped);
- int v_size = visual.size();
- const Glyph *glyphs = visual.ptr();
+int TextServer::shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const {
+ int v_size = shaped_text_get_glyph_count(p_shaped);
+ const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
for (int i = 0; i < v_size; i++) {
if (p_pos >= glyphs[i].start && p_pos < glyphs[i].end) {
return glyphs[i].end;
@@ -1177,10 +1194,9 @@ int TextServer::shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) {
return p_pos;
}
-int TextServer::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) {
- const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped);
- int v_size = visual.size();
- const Glyph *glyphs = visual.ptr();
+int TextServer::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const {
+ int v_size = shaped_text_get_glyph_count(p_shaped);
+ const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
for (int i = 0; i < v_size; i++) {
if (p_pos > glyphs[i].start && p_pos <= glyphs[i].end) {
return glyphs[i].start;
@@ -1191,26 +1207,30 @@ int TextServer::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) {
}
void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, real_t p_clip_l, real_t p_clip_r, const Color &p_color) const {
- const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped);
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);
bool rtl = shaped_text_get_direction(p_shaped) == DIRECTION_RTL;
- TrimData trim_data = shaped_text_get_trim_data(p_shaped);
- int v_size = visual.size();
- const Glyph *glyphs = visual.ptr();
+ int ellipsis_pos = shaped_text_get_ellipsis_pos(p_shaped);
+ int trim_pos = shaped_text_get_trim_pos(p_shaped);
+
+ const Glyph *ellipsis_glyphs = shaped_text_get_ellipsis_glyphs(p_shaped);
+ int ellipsis_gl_size = shaped_text_get_ellipsis_glyph_count(p_shaped);
+
+ int v_size = shaped_text_get_glyph_count(p_shaped);
+ const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
Vector2 ofs = p_pos;
// Draw RTL ellipsis string when needed.
- if (rtl && trim_data.ellipsis_pos >= 0) {
- for (int i = trim_data.ellipsis_glyph_buf.size() - 1; i >= 0; i--) {
- for (int j = 0; j < trim_data.ellipsis_glyph_buf[i].repeat; j++) {
- font_draw_glyph(trim_data.ellipsis_glyph_buf[i].font_rid, p_canvas, trim_data.ellipsis_glyph_buf[i].font_size, ofs + Vector2(trim_data.ellipsis_glyph_buf[i].x_off, trim_data.ellipsis_glyph_buf[i].y_off), trim_data.ellipsis_glyph_buf[i].index, p_color);
+ if (rtl && ellipsis_pos >= 0) {
+ for (int i = ellipsis_gl_size - 1; i >= 0; i--) {
+ for (int j = 0; j < ellipsis_glyphs[i].repeat; j++) {
+ font_draw_glyph(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, ofs + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color);
if (orientation == ORIENTATION_HORIZONTAL) {
- ofs.x += trim_data.ellipsis_glyph_buf[i].advance;
+ ofs.x += ellipsis_glyphs[i].advance;
} else {
- ofs.y += trim_data.ellipsis_glyph_buf[i].advance;
+ ofs.y += ellipsis_glyphs[i].advance;
}
}
}
@@ -1244,13 +1264,13 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p
}
}
}
- if (trim_data.trim_pos >= 0) {
+ if (trim_pos >= 0) {
if (rtl) {
- if (i < trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
+ if (i < trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
continue;
}
} else {
- if (i >= trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
+ if (i >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
break;
}
}
@@ -1269,14 +1289,14 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p
}
}
// Draw LTR ellipsis string when needed.
- if (!rtl && trim_data.ellipsis_pos >= 0) {
- for (int i = 0; i < trim_data.ellipsis_glyph_buf.size(); i++) {
- for (int j = 0; j < trim_data.ellipsis_glyph_buf[i].repeat; j++) {
- font_draw_glyph(trim_data.ellipsis_glyph_buf[i].font_rid, p_canvas, trim_data.ellipsis_glyph_buf[i].font_size, ofs + Vector2(trim_data.ellipsis_glyph_buf[i].x_off, trim_data.ellipsis_glyph_buf[i].y_off), trim_data.ellipsis_glyph_buf[i].index, p_color);
+ if (!rtl && ellipsis_pos >= 0) {
+ for (int i = 0; i < ellipsis_gl_size; i++) {
+ for (int j = 0; j < ellipsis_glyphs[i].repeat; j++) {
+ font_draw_glyph(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, ofs + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color);
if (orientation == ORIENTATION_HORIZONTAL) {
- ofs.x += trim_data.ellipsis_glyph_buf[i].advance;
+ ofs.x += ellipsis_glyphs[i].advance;
} else {
- ofs.y += trim_data.ellipsis_glyph_buf[i].advance;
+ ofs.y += ellipsis_glyphs[i].advance;
}
}
}
@@ -1284,24 +1304,28 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p
}
void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, real_t p_clip_l, real_t p_clip_r, int p_outline_size, const Color &p_color) const {
- const Vector<TextServer::Glyph> visual = shaped_text_get_glyphs(p_shaped);
TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped);
bool rtl = (shaped_text_get_direction(p_shaped) == DIRECTION_RTL);
- TrimData trim_data = shaped_text_get_trim_data(p_shaped);
- int v_size = visual.size();
- const Glyph *glyphs = visual.ptr();
+ int ellipsis_pos = shaped_text_get_ellipsis_pos(p_shaped);
+ int trim_pos = shaped_text_get_trim_pos(p_shaped);
+
+ const Glyph *ellipsis_glyphs = shaped_text_get_ellipsis_glyphs(p_shaped);
+ int ellipsis_gl_size = shaped_text_get_ellipsis_glyph_count(p_shaped);
+
+ int v_size = shaped_text_get_glyph_count(p_shaped);
+ const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
Vector2 ofs = p_pos;
// Draw RTL ellipsis string when needed.
- if (rtl && trim_data.ellipsis_pos >= 0) {
- for (int i = trim_data.ellipsis_glyph_buf.size() - 1; i >= 0; i--) {
- for (int j = 0; j < trim_data.ellipsis_glyph_buf[i].repeat; j++) {
- font_draw_glyph(trim_data.ellipsis_glyph_buf[i].font_rid, p_canvas, trim_data.ellipsis_glyph_buf[i].font_size, ofs + Vector2(trim_data.ellipsis_glyph_buf[i].x_off, trim_data.ellipsis_glyph_buf[i].y_off), trim_data.ellipsis_glyph_buf[i].index, p_color);
+ if (rtl && ellipsis_pos >= 0) {
+ for (int i = ellipsis_gl_size - 1; i >= 0; i--) {
+ for (int j = 0; j < ellipsis_glyphs[i].repeat; j++) {
+ font_draw_glyph(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, ofs + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color);
if (orientation == ORIENTATION_HORIZONTAL) {
- ofs.x += trim_data.ellipsis_glyph_buf[i].advance;
+ ofs.x += ellipsis_glyphs[i].advance;
} else {
- ofs.y += trim_data.ellipsis_glyph_buf[i].advance;
+ ofs.y += ellipsis_glyphs[i].advance;
}
}
}
@@ -1335,13 +1359,13 @@ void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vect
}
}
}
- if (trim_data.trim_pos >= 0) {
+ if (trim_pos >= 0) {
if (rtl) {
- if (i < trim_data.trim_pos) {
+ if (i < trim_pos) {
continue;
}
} else {
- if (i >= trim_data.trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
+ if (i >= trim_pos && (glyphs[j].flags & TextServer::GRAPHEME_IS_VIRTUAL) != TextServer::GRAPHEME_IS_VIRTUAL) {
break;
}
}
@@ -1357,48 +1381,26 @@ void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vect
}
}
// Draw LTR ellipsis string when needed.
- if (!rtl && trim_data.ellipsis_pos >= 0) {
- for (int i = 0; i < trim_data.ellipsis_glyph_buf.size(); i++) {
- for (int j = 0; j < trim_data.ellipsis_glyph_buf[i].repeat; j++) {
- font_draw_glyph(trim_data.ellipsis_glyph_buf[i].font_rid, p_canvas, trim_data.ellipsis_glyph_buf[i].font_size, ofs + Vector2(trim_data.ellipsis_glyph_buf[i].x_off, trim_data.ellipsis_glyph_buf[i].y_off), trim_data.ellipsis_glyph_buf[i].index, p_color);
+ if (!rtl && ellipsis_pos >= 0) {
+ for (int i = 0; i < ellipsis_gl_size; i++) {
+ for (int j = 0; j < ellipsis_glyphs[i].repeat; j++) {
+ font_draw_glyph(ellipsis_glyphs[i].font_rid, p_canvas, ellipsis_glyphs[i].font_size, ofs + Vector2(ellipsis_glyphs[i].x_off, ellipsis_glyphs[i].y_off), ellipsis_glyphs[i].index, p_color);
if (orientation == ORIENTATION_HORIZONTAL) {
- ofs.x += trim_data.ellipsis_glyph_buf[i].advance;
+ ofs.x += ellipsis_glyphs[i].advance;
} else {
- ofs.y += trim_data.ellipsis_glyph_buf[i].advance;
+ ofs.y += ellipsis_glyphs[i].advance;
}
}
}
}
}
-Dictionary TextServer::_font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const {
- Vector<Vector3> points;
- Vector<int32_t> contours;
- bool orientation;
- bool ok = font_get_glyph_contours(p_font, p_size, p_index, points, contours, orientation);
- Dictionary out;
-
- if (ok) {
- out["points"] = points;
- out["contours"] = contours;
- out["orientation"] = orientation;
- }
- return out;
-}
-
-void TextServer::_shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) {
- Vector<Vector2i> overrides;
- for (int i = 0; i < p_override.size(); i++) {
- overrides.push_back(p_override[i]);
- }
- shaped_text_set_bidi_override(p_shaped, overrides);
-}
-
-Array TextServer::_shaped_text_get_glyphs(RID p_shaped) const {
+Array TextServer::_shaped_text_get_glyphs_wrapper(RID p_shaped) const {
Array ret;
- Vector<Glyph> glyphs = shaped_text_get_glyphs(p_shaped);
- for (int i = 0; i < glyphs.size(); i++) {
+ const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
+ int gl_size = shaped_text_get_glyph_count(p_shaped);
+ for (int i = 0; i < gl_size; i++) {
Dictionary glyph;
glyph["start"] = glyphs[i].start;
@@ -1418,60 +1420,51 @@ Array TextServer::_shaped_text_get_glyphs(RID p_shaped) const {
return ret;
}
-Array TextServer::_shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start, bool p_once, uint8_t p_break_flags) const {
+Array TextServer::_shaped_text_sort_logical_wrapper(RID p_shaped) {
Array ret;
- Vector<Vector2i> lines = shaped_text_get_line_breaks_adv(p_shaped, p_width, p_start, p_once, p_break_flags);
- for (int i = 0; i < lines.size(); i++) {
- ret.push_back(lines[i]);
- }
-
- return ret;
-}
+ const Glyph *glyphs = shaped_text_sort_logical(p_shaped);
+ int gl_size = shaped_text_get_glyph_count(p_shaped);
+ for (int i = 0; i < gl_size; i++) {
+ Dictionary glyph;
-Array TextServer::_shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start, uint8_t p_break_flags) const {
- Array ret;
+ glyph["start"] = glyphs[i].start;
+ glyph["end"] = glyphs[i].end;
+ glyph["repeat"] = glyphs[i].repeat;
+ glyph["count"] = glyphs[i].count;
+ glyph["flags"] = glyphs[i].flags;
+ glyph["offset"] = Vector2(glyphs[i].x_off, glyphs[i].y_off);
+ glyph["advance"] = glyphs[i].advance;
+ glyph["font_rid"] = glyphs[i].font_rid;
+ glyph["font_size"] = glyphs[i].font_size;
+ glyph["index"] = glyphs[i].index;
- Vector<Vector2i> lines = shaped_text_get_line_breaks(p_shaped, p_width, p_start, p_break_flags);
- for (int i = 0; i < lines.size(); i++) {
- ret.push_back(lines[i]);
+ ret.push_back(glyph);
}
return ret;
}
-Array TextServer::_shaped_text_get_word_breaks(RID p_shaped) const {
+Array TextServer::_shaped_text_get_ellipsis_glyphs_wrapper(RID p_shaped) const {
Array ret;
- Vector<Vector2i> words = shaped_text_get_word_breaks(p_shaped);
- for (int i = 0; i < words.size(); i++) {
- ret.push_back(words[i]);
- }
-
- return ret;
-}
-
-Dictionary TextServer::_shaped_text_get_carets(RID p_shaped, int p_position) const {
- Dictionary ret;
-
- Rect2 l_caret, t_caret;
- Direction l_dir, t_dir;
- shaped_text_get_carets(p_shaped, p_position, l_caret, l_dir, t_caret, t_dir);
-
- ret["leading_rect"] = l_caret;
- ret["leading_direction"] = l_dir;
- ret["trailing_rect"] = t_caret;
- ret["trailing_direction"] = t_dir;
-
- return ret;
-}
+ const Glyph *glyphs = shaped_text_get_ellipsis_glyphs(p_shaped);
+ int gl_size = shaped_text_get_ellipsis_glyph_count(p_shaped);
+ for (int i = 0; i < gl_size; i++) {
+ Dictionary glyph;
-Array TextServer::_shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const {
- Array ret;
+ glyph["start"] = glyphs[i].start;
+ glyph["end"] = glyphs[i].end;
+ glyph["repeat"] = glyphs[i].repeat;
+ glyph["count"] = glyphs[i].count;
+ glyph["flags"] = glyphs[i].flags;
+ glyph["offset"] = Vector2(glyphs[i].x_off, glyphs[i].y_off);
+ glyph["advance"] = glyphs[i].advance;
+ glyph["font_rid"] = glyphs[i].font_rid;
+ glyph["font_size"] = glyphs[i].font_size;
+ glyph["index"] = glyphs[i].index;
- Vector<Vector2> ranges = shaped_text_get_selection(p_shaped, p_start, p_end);
- for (int i = 0; i < ranges.size(); i++) {
- ret.push_back(ranges[i]);
+ ret.push_back(glyph);
}
return ret;
diff --git a/servers/text_server.h b/servers/text_server.h
index 90ad9b493b..da62ff8ef4 100644
--- a/servers/text_server.h
+++ b/servers/text_server.h
@@ -34,13 +34,17 @@
#include "core/object/ref_counted.h"
#include "core/os/os.h"
#include "core/templates/rid.h"
+#include "core/variant/native_ptr.h"
#include "core/variant/variant.h"
#include "scene/resources/texture.h"
class CanvasTexture;
-class TextServer : public Object {
- GDCLASS(TextServer, Object);
+struct Glyph;
+struct CaretInfo;
+
+class TextServer : public RefCounted {
+ GDCLASS(TextServer, RefCounted);
public:
enum Direction {
@@ -63,12 +67,12 @@ public:
JUSTIFICATION_CONSTRAIN_ELLIPSIS = 1 << 4,
};
- enum LineBreakFlag {
+ enum LineBreakFlag { // LineBreakFlag can be passed in the same value as the JustificationFlag, do not use the same values.
BREAK_NONE = 0,
- BREAK_MANDATORY = 1 << 4,
- BREAK_WORD_BOUND = 1 << 5,
- BREAK_GRAPHEME_BOUND = 1 << 6,
- BREAK_WORD_BOUND_ADAPTIVE = 1 << 5 | 1 << 7,
+ BREAK_MANDATORY = 1 << 5,
+ BREAK_WORD_BOUND = 1 << 6,
+ BREAK_GRAPHEME_BOUND = 1 << 7,
+ BREAK_WORD_BOUND_ADAPTIVE = 1 << 6 | 1 << 8,
};
enum TextOverrunFlag {
@@ -124,50 +128,11 @@ public:
SPACING_BOTTOM,
};
- struct Glyph {
- int start = -1; // Start offset in the source string.
- int end = -1; // End offset in the source string.
-
- uint8_t count = 0; // Number of glyphs in the grapheme, set in the first glyph only.
- uint8_t repeat = 1; // Draw multiple times in the row.
- uint16_t flags = 0; // Grapheme flags (valid, rtl, virtual), set in the first glyph only.
-
- real_t x_off = 0.f; // Offset from the origin of the glyph on baseline.
- real_t y_off = 0.f;
- real_t advance = 0.f; // Advance to the next glyph along baseline(x for horizontal layout, y for vertical).
-
- RID font_rid; // Font resource.
- int font_size = 0; // Font size;
- int32_t index = 0; // Glyph index (font specific) or UTF-32 codepoint (for the invalid glyphs).
-
- bool operator==(const Glyph &p_a) const;
- bool operator!=(const Glyph &p_a) const;
-
- bool operator<(const Glyph &p_a) const;
- bool operator>(const Glyph &p_a) const;
- };
-
- struct GlyphCompare { // For line breaking reordering.
- _FORCE_INLINE_ bool operator()(const Glyph &l, const Glyph &r) const {
- if (l.start == r.start) {
- if (l.count == r.count) {
- if ((l.flags & GRAPHEME_IS_VIRTUAL) == GRAPHEME_IS_VIRTUAL) {
- return false;
- } else {
- return true;
- }
- }
- return l.count > r.count; // Sort first glyph with count & flags, order of the rest are irrelevant.
- } else {
- return l.start < r.start;
- }
- }
- };
-
+protected:
struct TrimData {
int trim_pos = -1;
int ellipsis_pos = -1;
- Vector<TextServer::Glyph> ellipsis_glyph_buf;
+ Vector<Glyph> ellipsis_glyph_buf;
};
struct ShapedTextData {
@@ -215,22 +180,21 @@ public:
bool preserve_invalid = true; // Draw hex code box instead of missing characters.
bool preserve_control = false; // Draw control characters.
- real_t ascent = 0.f; // Ascent for horizontal layout, 1/2 of width for vertical.
- real_t descent = 0.f; // Descent for horizontal layout, 1/2 of width for vertical.
- real_t width = 0.f; // Width for horizontal layout, height for vertical.
- real_t width_trimmed = 0.f;
+ float ascent = 0.f; // Ascent for horizontal layout, 1/2 of width for vertical.
+ float descent = 0.f; // Descent for horizontal layout, 1/2 of width for vertical.
+ float width = 0.f; // Width for horizontal layout, height for vertical.
+ float width_trimmed = 0.f;
- real_t upos = 0.f;
- real_t uthk = 0.f;
+ float upos = 0.f;
+ float uthk = 0.f;
TrimData overrun_trim_data;
bool fit_width_minimum_reached = false;
- Vector<TextServer::Glyph> glyphs;
- Vector<TextServer::Glyph> glyphs_logical;
+ Vector<Glyph> glyphs;
+ Vector<Glyph> glyphs_logical;
};
-protected:
static void _bind_methods();
static Vector3 hex_code_box_font_size[2];
@@ -240,20 +204,19 @@ public:
static void initialize_hex_code_box_fonts();
static void finish_hex_code_box_fonts();
- virtual bool has_feature(Feature p_feature) = 0;
+ virtual bool has_feature(Feature p_feature) const = 0;
virtual String get_name() const = 0;
+ virtual uint32_t get_features() const = 0;
virtual void free(RID p_rid) = 0;
virtual bool has(RID p_rid) = 0;
virtual bool load_support_data(const String &p_filename) = 0;
-#ifdef TOOLS_ENABLED
- virtual String get_support_data_filename() = 0;
- virtual String get_support_data_info() = 0;
- virtual bool save_support_data(const String &p_filename) = 0;
-#endif
+ virtual String get_support_data_filename() const = 0;
+ virtual String get_support_data_info() const = 0;
+ virtual bool save_support_data(const String &p_filename) const = 0;
- virtual bool is_locale_right_to_left(const String &p_locale) = 0;
+ virtual bool is_locale_right_to_left(const String &p_locale) const = 0;
virtual int32_t name_to_tag(const String &p_name) const { return 0; };
virtual String tag_to_name(int32_t p_tag) const { return ""; };
@@ -282,33 +245,33 @@ public:
virtual void font_set_force_autohinter(RID p_font_rid, bool p_force_autohinter) = 0;
virtual bool font_is_force_autohinter(RID p_font_rid) const = 0;
- virtual void font_set_hinting(RID p_font_rid, TextServer::Hinting p_hinting) = 0;
- virtual TextServer::Hinting font_get_hinting(RID p_font_rid) const = 0;
+ virtual void font_set_hinting(RID p_font_rid, Hinting p_hinting) = 0;
+ virtual Hinting font_get_hinting(RID p_font_rid) const = 0;
virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) = 0;
virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const = 0;
- virtual void font_set_oversampling(RID p_font_rid, real_t p_oversampling) = 0;
- virtual real_t font_get_oversampling(RID p_font_rid) const = 0;
+ virtual void font_set_oversampling(RID p_font_rid, float p_oversampling) = 0;
+ virtual float font_get_oversampling(RID p_font_rid) const = 0;
virtual Array font_get_size_cache_list(RID p_font_rid) const = 0;
virtual void font_clear_size_cache(RID p_font_rid) = 0;
virtual void font_remove_size_cache(RID p_font_rid, const Vector2i &p_size) = 0;
- virtual void font_set_ascent(RID p_font_rid, int p_size, real_t p_ascent) = 0;
- virtual real_t font_get_ascent(RID p_font_rid, int p_size) const = 0;
+ virtual void font_set_ascent(RID p_font_rid, int p_size, float p_ascent) = 0;
+ virtual float font_get_ascent(RID p_font_rid, int p_size) const = 0;
- virtual void font_set_descent(RID p_font_rid, int p_size, real_t p_descent) = 0;
- virtual real_t font_get_descent(RID p_font_rid, int p_size) const = 0;
+ virtual void font_set_descent(RID p_font_rid, int p_size, float p_descent) = 0;
+ virtual float font_get_descent(RID p_font_rid, int p_size) const = 0;
- virtual void font_set_underline_position(RID p_font_rid, int p_size, real_t p_underline_position) = 0;
- virtual real_t font_get_underline_position(RID p_font_rid, int p_size) const = 0;
+ virtual void font_set_underline_position(RID p_font_rid, int p_size, float p_underline_position) = 0;
+ virtual float font_get_underline_position(RID p_font_rid, int p_size) const = 0;
- virtual void font_set_underline_thickness(RID p_font_rid, int p_size, real_t p_underline_thickness) = 0;
- virtual real_t font_get_underline_thickness(RID p_font_rid, int p_size) const = 0;
+ virtual void font_set_underline_thickness(RID p_font_rid, int p_size, float p_underline_thickness) = 0;
+ virtual float font_get_underline_thickness(RID p_font_rid, int p_size) const = 0;
- virtual void font_set_scale(RID p_font_rid, int p_size, real_t p_scale) = 0;
- virtual real_t font_get_scale(RID p_font_rid, int p_size) const = 0;
+ virtual void font_set_scale(RID p_font_rid, int p_size, float p_scale) = 0;
+ virtual float font_get_scale(RID p_font_rid, int p_size) const = 0;
virtual void font_set_spacing(RID p_font_rid, int p_size, SpacingType p_spacing, int p_value) = 0;
virtual int font_get_spacing(RID p_font_rid, int p_size, SpacingType p_spacing) const = 0;
@@ -342,7 +305,7 @@ public:
virtual int font_get_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const = 0;
virtual void font_set_glyph_texture_idx(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, int p_texture_idx) = 0;
- virtual bool font_get_glyph_contours(RID p_font, int p_size, int32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const = 0;
+ virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const = 0;
virtual Array font_get_kerning_list(RID p_font_rid, int p_size) const = 0;
virtual void font_clear_kerning_map(RID p_font_rid, int p_size) = 0;
@@ -377,11 +340,11 @@ public:
virtual Dictionary font_supported_feature_list(RID p_font_rid) const = 0;
virtual Dictionary font_supported_variation_list(RID p_font_rid) const = 0;
- virtual real_t font_get_global_oversampling() const = 0;
- virtual void font_set_global_oversampling(real_t p_oversampling) = 0;
+ virtual float font_get_global_oversampling() const = 0;
+ virtual void font_set_global_oversampling(float p_oversampling) = 0;
- Vector2 get_hex_code_box_size(int p_size, char32_t p_index) const;
- void draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const;
+ virtual Vector2 get_hex_code_box_size(int p_size, char32_t p_index) const;
+ virtual void draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const;
/* Shaped text buffer interface */
@@ -392,7 +355,7 @@ public:
virtual void shaped_text_set_direction(RID p_shaped, Direction p_direction = DIRECTION_AUTO) = 0;
virtual Direction shaped_text_get_direction(RID p_shaped) const = 0;
- virtual void shaped_text_set_bidi_override(RID p_shaped, const Vector<Vector2i> &p_override) = 0;
+ virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) = 0;
virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) = 0;
virtual Orientation shaped_text_get_orientation(RID p_shaped) const = 0;
@@ -410,8 +373,8 @@ public:
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const = 0; // Copy shaped substring (e.g. line break) without reshaping, but correctly reordered, preservers range.
virtual RID shaped_text_get_parent(RID p_shaped) const = 0;
- virtual real_t shaped_text_fit_to_width(RID p_shaped, real_t p_width, uint8_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) = 0;
- virtual real_t shaped_text_tab_align(RID p_shaped, const Vector<real_t> &p_tab_stops) = 0;
+ virtual float shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) = 0;
+ virtual float shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) = 0;
virtual bool shaped_text_shape(RID p_shaped) = 0;
virtual bool shaped_text_update_breaks(RID p_shaped) = 0;
@@ -419,66 +382,109 @@ public:
virtual bool shaped_text_is_ready(RID p_shaped) const = 0;
- virtual Vector<Glyph> shaped_text_get_glyphs(RID p_shaped) const = 0;
+ virtual const Glyph *shaped_text_get_glyphs(RID p_shaped) const = 0;
+ Array _shaped_text_get_glyphs_wrapper(RID p_shaped) const;
+ virtual const Glyph *shaped_text_sort_logical(RID p_shaped) = 0;
+ Array _shaped_text_sort_logical_wrapper(RID p_shaped);
+ virtual int shaped_text_get_glyph_count(RID p_shaped) const = 0;
virtual Vector2i shaped_text_get_range(RID p_shaped) const = 0;
- virtual Vector<Glyph> shaped_text_sort_logical(RID p_shaped) = 0;
+ virtual PackedInt32Array shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start = 0, bool p_once = true, uint16_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
+ virtual PackedInt32Array shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start = 0, uint16_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
+ virtual PackedInt32Array shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const;
- virtual Vector<Vector2i> shaped_text_get_line_breaks_adv(RID p_shaped, const Vector<real_t> &p_width, int p_start = 0, bool p_once = true, uint8_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
- virtual Vector<Vector2i> shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start = 0, uint8_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
- virtual Vector<Vector2i> shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const;
+ virtual int shaped_text_get_trim_pos(RID p_shaped) const = 0;
+ virtual int shaped_text_get_ellipsis_pos(RID p_shaped) const = 0;
+ virtual const Glyph *shaped_text_get_ellipsis_glyphs(RID p_shaped) const = 0;
+ Array _shaped_text_get_ellipsis_glyphs_wrapper(RID p_shaped) const;
+ virtual int shaped_text_get_ellipsis_glyph_count(RID p_shaped) const = 0;
+
+ virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) = 0;
- virtual TrimData shaped_text_get_trim_data(RID p_shaped) const;
- virtual void shaped_text_overrun_trim_to_width(RID p_shaped, real_t p_width, uint8_t p_trim_flags) = 0;
virtual Array shaped_text_get_objects(RID p_shaped) const = 0;
virtual Rect2 shaped_text_get_object_rect(RID p_shaped, Variant p_key) const = 0;
virtual Size2 shaped_text_get_size(RID p_shaped) const = 0;
- virtual real_t shaped_text_get_ascent(RID p_shaped) const = 0;
- virtual real_t shaped_text_get_descent(RID p_shaped) const = 0;
- virtual real_t shaped_text_get_width(RID p_shaped) const = 0;
- virtual real_t shaped_text_get_underline_position(RID p_shaped) const = 0;
- virtual real_t shaped_text_get_underline_thickness(RID p_shaped) const = 0;
+ virtual float shaped_text_get_ascent(RID p_shaped) const = 0;
+ virtual float shaped_text_get_descent(RID p_shaped) const = 0;
+ virtual float shaped_text_get_width(RID p_shaped) const = 0;
+ virtual float shaped_text_get_underline_position(RID p_shaped) const = 0;
+ virtual float shaped_text_get_underline_thickness(RID p_shaped) const = 0;
+
+ virtual Direction shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const;
- virtual Direction shaped_text_get_dominant_direciton_in_range(RID p_shaped, int p_start, int p_end) const;
+ virtual CaretInfo shaped_text_get_carets(RID p_shaped, int p_position) const;
+ Dictionary _shaped_text_get_carets_wrapper(RID p_shaped, int p_position) const;
- virtual void shaped_text_get_carets(RID p_shaped, int p_position, Rect2 &p_leading_caret, Direction &p_leading_dir, Rect2 &p_trailing_caret, Direction &p_trailing_dir) const;
virtual Vector<Vector2> shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const;
- virtual int shaped_text_hit_test_grapheme(RID p_shaped, real_t p_coords) const; // Return grapheme index.
- virtual int shaped_text_hit_test_position(RID p_shaped, real_t p_coords) const; // Return caret/selection position.
+ virtual int shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const; // Return grapheme index.
+ virtual int shaped_text_hit_test_position(RID p_shaped, float p_coords) const; // Return caret/selection position.
- virtual int shaped_text_next_grapheme_pos(RID p_shaped, int p_pos);
- virtual int shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos);
+ virtual int shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const;
+ virtual int shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const;
// The pen position is always placed on the baseline and moveing left to right.
- virtual void shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, real_t p_clip_l = -1.f, real_t p_clip_r = -1.f, const Color &p_color = Color(1, 1, 1)) const;
- virtual void shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, real_t p_clip_l = -1.f, real_t p_clip_r = -1.f, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
+ virtual void shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, const Color &p_color = Color(1, 1, 1)) const;
+ virtual void shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l = -1.f, float p_clip_r = -1.f, int p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const;
// Number conversion.
virtual String format_number(const String &p_string, const String &p_language = "") const { return p_string; };
virtual String parse_number(const String &p_string, const String &p_language = "") const { return p_string; };
virtual String percent_sign(const String &p_language = "") const { return "%"; };
- /* GDScript wrappers */
- RID _create_font_memory(const PackedByteArray &p_data, int p_base_size = 16);
+ TextServer();
+ ~TextServer();
+};
+
+/*************************************************************************/
- Dictionary _font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const;
+struct Glyph {
+ int start = -1; // Start offset in the source string.
+ int end = -1; // End offset in the source string.
- Array _shaped_text_get_glyphs(RID p_shaped) const;
- Dictionary _shaped_text_get_carets(RID p_shaped, int p_position) const;
+ uint8_t count = 0; // Number of glyphs in the grapheme, set in the first glyph only.
+ uint8_t repeat = 1; // Draw multiple times in the row.
+ uint16_t flags = 0; // Grapheme flags (valid, rtl, virtual), set in the first glyph only.
- void _shaped_text_set_bidi_override(RID p_shaped, const Array &p_override);
+ float x_off = 0.f; // Offset from the origin of the glyph on baseline.
+ float y_off = 0.f;
+ float advance = 0.f; // Advance to the next glyph along baseline(x for horizontal layout, y for vertical).
- Array _shaped_text_get_line_breaks_adv(RID p_shaped, const PackedFloat32Array &p_width, int p_start, bool p_once, uint8_t p_break_flags) const;
- Array _shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start, uint8_t p_break_flags) const;
- Array _shaped_text_get_word_breaks(RID p_shaped) const;
+ RID font_rid; // Font resource.
+ int font_size = 0; // Font size;
+ int32_t index = 0; // Glyph index (font specific) or UTF-32 codepoint (for the invalid glyphs).
- Array _shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const;
+ bool operator==(const Glyph &p_a) const;
+ bool operator!=(const Glyph &p_a) const;
- TextServer();
- ~TextServer();
+ bool operator<(const Glyph &p_a) const;
+ bool operator>(const Glyph &p_a) const;
+};
+
+struct CaretInfo {
+ Rect2 l_caret;
+ Rect2 t_caret;
+ TextServer::Direction l_dir;
+ TextServer::Direction t_dir;
+};
+
+struct GlyphCompare { // For line breaking reordering.
+ _FORCE_INLINE_ bool operator()(const Glyph &l, const Glyph &r) const {
+ if (l.start == r.start) {
+ if (l.count == r.count) {
+ if ((l.flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+ return l.count > r.count; // Sort first glyph with count & flags, order of the rest are irrelevant.
+ } else {
+ return l.start < r.start;
+ }
+ }
};
/*************************************************************************/
@@ -486,52 +492,32 @@ public:
class TextServerManager : public Object {
GDCLASS(TextServerManager, Object);
-public:
- typedef TextServer *(*CreateFunction)(Error &r_error, void *p_user_data);
-
protected:
static void _bind_methods();
private:
static TextServerManager *singleton;
- static TextServer *server;
- enum {
- MAX_SERVERS = 64
- };
- struct TextServerCreate {
- String name;
- CreateFunction create_function = nullptr;
- uint32_t features = 0;
- TextServer *instance = nullptr;
- void *user_data = nullptr;
- };
-
- static TextServerCreate server_create_functions[MAX_SERVERS];
- static int server_create_count;
+ Ref<TextServer> primary_interface;
+ Vector<Ref<TextServer>> interfaces;
public:
_FORCE_INLINE_ static TextServerManager *get_singleton() {
return singleton;
}
- static void register_create_function(const String &p_name, uint32_t p_features, CreateFunction p_function, void *p_user_data);
- static int get_interface_count();
- static String get_interface_name(int p_index);
- static uint32_t get_interface_features(int p_index);
- static TextServer *initialize(int p_index, Error &r_error);
- static TextServer *get_primary_interface();
-
- /* GDScript wrappers */
- int _get_interface_count() const;
- String _get_interface_name(int p_index) const;
- uint32_t _get_interface_features(int p_index) const;
- TextServer *_get_interface(int p_index) const;
- Array _get_interfaces() const;
- TextServer *_find_interface(const String &p_name) const;
+ void add_interface(const Ref<TextServer> &p_interface);
+ void remove_interface(const Ref<TextServer> &p_interface);
+ int get_interface_count() const;
+ Ref<TextServer> get_interface(int p_index) const;
+ Ref<TextServer> find_interface(const String &p_name) const;
+ Array get_interfaces() const;
- bool _set_primary_interface(int p_index);
- TextServer *_get_primary_interface() const;
+ _FORCE_INLINE_ Ref<TextServer> get_primary_interface() const {
+ return primary_interface;
+ }
+ Ref<TextServer> _get_primary_interface() const;
+ void set_primary_interface(const Ref<TextServer> &p_primary_interface);
TextServerManager();
~TextServerManager();
@@ -539,7 +525,7 @@ public:
/*************************************************************************/
-#define TS TextServerManager::get_primary_interface()
+#define TS TextServerManager::get_singleton()->get_primary_interface()
VARIANT_ENUM_CAST(TextServer::Direction);
VARIANT_ENUM_CAST(TextServer::Orientation);
@@ -552,4 +538,8 @@ VARIANT_ENUM_CAST(TextServer::Feature);
VARIANT_ENUM_CAST(TextServer::ContourPointTag);
VARIANT_ENUM_CAST(TextServer::SpacingType);
+GDVIRTUAL_NATIVE_PTR(Glyph);
+GDVIRTUAL_NATIVE_PTR(Glyph *);
+GDVIRTUAL_NATIVE_PTR(CaretInfo);
+
#endif // TEXT_SERVER_H