diff options
author | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2021-08-28 00:19:51 +0300 |
---|---|---|
committer | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2021-10-01 15:13:29 +0300 |
commit | 0c0b5c84b06e64de6cab301994ac9cd1f845dd35 (patch) | |
tree | 9b0ea4d9718fe694b2b22d9e09a66b32db8c2cb9 /servers | |
parent | 06c1b40b84645b4460dd49d95694a7779d636f92 (diff) |
Implement TextServer GDExtension interface, remove TextServer GDNative interface.
Diffstat (limited to 'servers')
-rw-r--r-- | servers/SCsub | 1 | ||||
-rw-r--r-- | servers/register_server_types.cpp | 18 | ||||
-rw-r--r-- | servers/rendering_server.cpp | 1 | ||||
-rw-r--r-- | servers/text/SCsub | 5 | ||||
-rw-r--r-- | servers/text/text_server_extension.cpp | 1281 | ||||
-rw-r--r-- | servers/text/text_server_extension.h | 426 | ||||
-rw-r--r-- | servers/text_server.cpp | 561 | ||||
-rw-r--r-- | servers/text_server.h | 294 |
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 |