Quellcode durchsuchen

Merge pull request #58233 from bruvzg/gde_ts

Rémi Verschelde vor 3 Jahren
Ursprung
Commit
5c8bd6fd71
49 geänderte Dateien mit 4031 neuen und 2390 gelöschten Zeilen
  1. 1 1
      SConstruct
  2. 2 2
      core/io/image.cpp
  3. 8 8
      core/io/image.h
  4. 6 0
      core/string/ustring.cpp
  5. 1 0
      core/string/ustring.h
  6. 2 0
      core/variant/variant_call.cpp
  7. 1 0
      core/variant/variant_op.cpp
  8. 6 0
      doc/classes/Font.xml
  9. 24 0
      doc/classes/String.xml
  10. 36 17
      doc/classes/TextServer.xml
  11. 9 0
      doc/classes/TextServerDummy.xml
  12. 130 138
      doc/classes/TextServerExtension.xml
  13. 1 1
      editor/debugger/script_editor_debugger.cpp
  14. 1 1
      editor/editor_spin_slider.cpp
  15. 1 1
      editor/import/dynamic_font_import_settings.cpp
  16. 34 3
      main/main.cpp
  17. 2 0
      modules/text_server_adv/.gitignore
  18. 1 0
      modules/text_server_adv/SCsub
  19. 1 1
      modules/text_server_adv/doc_classes/TextServerAdvanced.xml
  20. 638 0
      modules/text_server_adv/gdextension_build/SConstruct
  21. 130 0
      modules/text_server_adv/gdextension_build/methods.py
  22. 12 0
      modules/text_server_adv/gdextension_build/text_server_adv.gdextension
  23. 26 2
      modules/text_server_adv/register_types.cpp
  24. 16 1
      modules/text_server_adv/script_iterator.h
  25. 381 316
      modules/text_server_adv/text_server_adv.cpp
  26. 291 177
      modules/text_server_adv/text_server_adv.h
  27. 2 0
      modules/text_server_fb/.gitignore
  28. 1 1
      modules/text_server_fb/doc_classes/TextServerFallback.xml
  29. 205 0
      modules/text_server_fb/gdextension_build/SConstruct
  30. 130 0
      modules/text_server_fb/gdextension_build/methods.py
  31. 12 0
      modules/text_server_fb/gdextension_build/text_server_fb.gdextension
  32. 26 2
      modules/text_server_fb/register_types.cpp
  33. 188 128
      modules/text_server_fb/text_server_fb.cpp
  34. 262 167
      modules/text_server_fb/text_server_fb.h
  35. 3 3
      scene/gui/label.cpp
  36. 1 1
      scene/gui/line_edit.cpp
  37. 10 4
      scene/resources/font.cpp
  38. 1 1
      scene/resources/font.h
  39. 1 1
      scene/resources/text_line.cpp
  40. 6 6
      scene/resources/text_paragraph.cpp
  41. 2 0
      servers/register_server_types.cpp
  42. 48 0
      servers/text/text_server_dummy.h
  43. 420 418
      servers/text/text_server_extension.cpp
  44. 407 404
      servers/text/text_server_extension.h
  45. 29 23
      servers/text_server.cpp
  46. 188 254
      servers/text_server.h
  47. 0 4
      tests/core/object/test_class_db.h
  48. 285 281
      tests/scene/test_code_edit.h
  49. 43 23
      tests/servers/test_text_server.h

+ 1 - 1
SConstruct

@@ -741,7 +741,7 @@ if selected_platform in platform_list:
     if env["minizip"]:
         env.Append(CPPDEFINES=["MINIZIP_ENABLED"])
 
-    editor_module_list = ["freetype"]
+    editor_module_list = []
     if env["tools"] and not env.module_check_dependencies("tools", editor_module_list):
         print(
             "Build option 'module_"

+ 2 - 2
core/io/image.cpp

@@ -3112,8 +3112,8 @@ void Image::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("generate_mipmaps", "renormalize"), &Image::generate_mipmaps, DEFVAL(false));
 	ClassDB::bind_method(D_METHOD("clear_mipmaps"), &Image::clear_mipmaps);
 
-	ClassDB::bind_method(D_METHOD("create", "width", "height", "use_mipmaps", "format"), &Image::_create_empty);
-	ClassDB::bind_method(D_METHOD("create_from_data", "width", "height", "use_mipmaps", "format", "data"), &Image::_create_from_data);
+	ClassDB::bind_method(D_METHOD("create", "width", "height", "use_mipmaps", "format"), &Image::create_empty);
+	ClassDB::bind_method(D_METHOD("create_from_data", "width", "height", "use_mipmaps", "format", "data"), &Image::create_from_data);
 
 	ClassDB::bind_method(D_METHOD("is_empty"), &Image::is_empty);
 

+ 8 - 8
core/io/image.h

@@ -155,14 +155,6 @@ protected:
 	static void _bind_methods();
 
 private:
-	void _create_empty(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
-		create(p_width, p_height, p_use_mipmaps, p_format);
-	}
-
-	void _create_from_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) {
-		create(p_width, p_height, p_use_mipmaps, p_format, p_data);
-	}
-
 	Format format = FORMAT_L8;
 	Vector<uint8_t> data;
 	int width = 0;
@@ -289,6 +281,14 @@ public:
 	Vector<uint8_t> save_png_to_buffer() const;
 	Error save_exr(const String &p_path, bool p_grayscale) const;
 
+	void create_empty(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
+		create(p_width, p_height, p_use_mipmaps, p_format);
+	}
+
+	void create_from_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) {
+		create(p_width, p_height, p_use_mipmaps, p_format, p_data);
+	}
+
 	/**
 	 * create an empty image
 	 */

+ 6 - 0
core/string/ustring.cpp

@@ -463,6 +463,12 @@ String String::operator+(const String &p_str) const {
 	return res;
 }
 
+String String::operator+(char32_t p_char) const {
+	String res = *this;
+	res += p_char;
+	return res;
+}
+
 String operator+(const char *p_chr, const String &p_str) {
 	String tmp = p_chr;
 	tmp += p_str;

+ 1 - 0
core/string/ustring.h

@@ -225,6 +225,7 @@ public:
 	bool operator==(const String &p_str) const;
 	bool operator!=(const String &p_str) const;
 	String operator+(const String &p_str) const;
+	String operator+(char32_t p_char) const;
 
 	String &operator+=(const String &);
 	String &operator+=(char32_t p_char);

+ 2 - 0
core/variant/variant_call.cpp

@@ -1467,6 +1467,8 @@ static void _register_variant_builtin_methods() {
 
 	bind_static_method(String, num_scientific, sarray("number"), varray());
 	bind_static_method(String, num, sarray("number", "decimals"), varray(-1));
+	bind_static_method(String, num_int64, sarray("number", "base", "capitalize_hex"), varray(10, false));
+	bind_static_method(String, num_uint64, sarray("number", "base", "capitalize_hex"), varray(10, false));
 	bind_static_method(String, chr, sarray("char"), varray());
 	bind_static_method(String, humanize_size, sarray("size"), varray());
 

+ 1 - 0
core/variant/variant_op.cpp

@@ -177,6 +177,7 @@ void Variant::_register_variant_operators() {
 	register_op<OperatorEvaluatorAdd<double, double, double>>(Variant::OP_ADD, Variant::FLOAT, Variant::FLOAT);
 	register_op<OperatorEvaluatorAdd<String, String, String>>(Variant::OP_ADD, Variant::STRING, Variant::STRING);
 	register_op<OperatorEvaluatorAdd<String, char32_t, String>>(Variant::OP_ADD, Variant::INT, Variant::STRING);
+	register_op<OperatorEvaluatorAdd<String, String, char32_t>>(Variant::OP_ADD, Variant::STRING, Variant::INT);
 	register_op<OperatorEvaluatorAdd<Vector2, Vector2, Vector2>>(Variant::OP_ADD, Variant::VECTOR2, Variant::VECTOR2);
 	register_op<OperatorEvaluatorAdd<Vector2i, Vector2i, Vector2i>>(Variant::OP_ADD, Variant::VECTOR2I, Variant::VECTOR2I);
 	register_op<OperatorEvaluatorAdd<Vector3, Vector3, Vector3>>(Variant::OP_ADD, Variant::VECTOR3, Variant::VECTOR3);

+ 6 - 0
doc/classes/Font.xml

@@ -191,6 +191,12 @@
 				See also [method draw_multiline_string].
 			</description>
 		</method>
+		<method name="get_rids" qualifiers="const">
+			<return type="Array" />
+			<description>
+				Returns [Array] of valid [FontData] [RID]s, which can be passsed to the [TextServer] methods.
+			</description>
+		</method>
 		<method name="get_spacing" qualifiers="const">
 			<return type="int" />
 			<argument index="0" name="spacing" type="int" enum="TextServer.SpacingType" />

+ 24 - 0
doc/classes/String.xml

@@ -514,12 +514,30 @@
 				[/codeblock]
 			</description>
 		</method>
+		<method name="num_int64" qualifiers="static">
+			<return type="String" />
+			<argument index="0" name="number" type="int" />
+			<argument index="1" name="base" type="int" default="10" />
+			<argument index="2" name="capitalize_hex" type="bool" default="false" />
+			<description>
+				Converts a signed [int] to a string representation of a number.
+			</description>
+		</method>
 		<method name="num_scientific" qualifiers="static">
 			<return type="String" />
 			<argument index="0" name="number" type="float" />
 			<description>
 			</description>
 		</method>
+		<method name="num_uint64" qualifiers="static">
+			<return type="String" />
+			<argument index="0" name="number" type="int" />
+			<argument index="1" name="base" type="int" default="10" />
+			<argument index="2" name="capitalize_hex" type="bool" default="false" />
+			<description>
+				Converts a unsigned [int] to a string representation of a number.
+			</description>
+		</method>
 		<method name="pad_decimals" qualifiers="const">
 			<return type="String" />
 			<argument index="0" name="digits" type="int" />
@@ -887,6 +905,12 @@
 			<description>
 			</description>
 		</operator>
+		<operator name="operator +">
+			<return type="String" />
+			<argument index="0" name="right" type="int" />
+			<description>
+			</description>
+		</operator>
 		<operator name="operator &lt;">
 			<return type="bool" />
 			<argument index="0" name="right" type="String" />

+ 36 - 17
doc/classes/TextServer.xml

@@ -57,7 +57,7 @@
 			<return type="void" />
 			<argument index="0" name="font_rid" type="RID" />
 			<description>
-				Removes all font sizes from the cache entry
+				Removes all font sizes from the cache entry.
 			</description>
 		</method>
 		<method name="font_clear_textures">
@@ -509,7 +509,7 @@
 			<argument index="1" name="size" type="Vector2i" />
 			<argument index="2" name="index" type="int" />
 			<description>
-				Renders specified glyph the the font cache texture.
+				Renders specified glyph to the font cache texture.
 			</description>
 		</method>
 		<method name="font_render_range">
@@ -1112,7 +1112,7 @@
 			<return type="Array" />
 			<argument index="0" name="shaped" type="RID" />
 			<description>
-				Returns text glyphs in the visual order.
+				Returns an array of glyphs in the visual order.
 			</description>
 		</method>
 		<method name="shaped_text_get_grapheme_bounds" qualifiers="const">
@@ -1177,7 +1177,7 @@
 			<return type="RID" />
 			<argument index="0" name="shaped" type="RID" />
 			<description>
-				Sets text orientation.
+				Returns the parent buffer from which the substring originates.
 			</description>
 		</method>
 		<method name="shaped_text_get_preserve_control" qualifiers="const">
@@ -1222,7 +1222,7 @@
 			<return type="int" />
 			<argument index="0" name="shaped" type="RID" />
 			<description>
-				Returns position of the trim.
+				Returns the position of the overrun trim.
 			</description>
 		</method>
 		<method name="shaped_text_get_underline_position" qualifiers="const">
@@ -1420,6 +1420,7 @@
 			<argument index="0" name="string" type="String" />
 			<description>
 				Strips diacritics from the string.
+				[b]Note:[/b] The result may be longer or shorter than the original.
 			</description>
 		</method>
 		<method name="tag_to_name" qualifiers="const">
@@ -1544,8 +1545,8 @@
 		</constant>
 		<constant name="SUBPIXEL_POSITIONING_AUTO" value="1" enum="SubpixelPositioning">
 			Glyph horizontal position is rounded based on font size.
-			- To one quarter of the pixel size if font size is smaller or equal to [code]16[/code].
-			- To one half of the pixel size if font size is smaller or equal to [code]20[/code].
+			- To one quarter of the pixel size if font size is smaller or equal to [constant SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE].
+			- To one half of the pixel size if font size is smaller or equal to [constant SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE].
 			- To the whole pixel size for larger fonts.
 		</constant>
 		<constant name="SUBPIXEL_POSITIONING_ONE_HALF" value="2" enum="SubpixelPositioning">
@@ -1554,31 +1555,49 @@
 		<constant name="SUBPIXEL_POSITIONING_ONE_QUARTER" value="3" enum="SubpixelPositioning">
 			Glyph horizontal position is rounded to one quarter of the pixel size, each glyph is rasterized up to four times.
 		</constant>
-		<constant name="FEATURE_BIDI_LAYOUT" value="1" enum="Feature">
-			TextServer supports bidirectional layouts.
+		<constant name="SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE" value="20" enum="SubpixelPositioning">
+			Maximum font size which will use one half of the pixel subpixel positioning in [constants SUBPIXEL_POSITIONING_AUTO] mode.
+		</constant>
+		<constant name="SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE" value="16" enum="SubpixelPositioning">
+			Maximum font size which will use one quarter of the pixel subpixel positioning in [constants SUBPIXEL_POSITIONING_AUTO] mode.
+		</constant>
+		<constant name="FEATURE_SIMPLE_LAYOUT" value="1" enum="Feature">
+			TextServer supports simple text layouts.
+		</constant>
+		<constant name="FEATURE_BIDI_LAYOUT" value="2" enum="Feature">
+			TextServer supports bidirectional text layouts.
 		</constant>
-		<constant name="FEATURE_VERTICAL_LAYOUT" value="2" enum="Feature">
+		<constant name="FEATURE_VERTICAL_LAYOUT" value="4" enum="Feature">
 			TextServer supports vertical layouts.
 		</constant>
-		<constant name="FEATURE_SHAPING" value="4" enum="Feature">
+		<constant name="FEATURE_SHAPING" value="8" enum="Feature">
 			TextServer supports complex text shaping.
 		</constant>
-		<constant name="FEATURE_KASHIDA_JUSTIFICATION" value="8" enum="Feature">
+		<constant name="FEATURE_KASHIDA_JUSTIFICATION" value="16" enum="Feature">
 			TextServer supports justification using kashidas.
 		</constant>
-		<constant name="FEATURE_BREAK_ITERATORS" value="16" enum="Feature">
+		<constant name="FEATURE_BREAK_ITERATORS" value="32" enum="Feature">
 			TextServer supports complex line/word breaking rules (e.g. dictionary based).
 		</constant>
-		<constant name="FEATURE_FONT_SYSTEM" value="32" enum="Feature">
+		<constant name="FEATURE_FONT_BITMAP" value="64" enum="Feature">
+			TextServer supports loading bitmap fonts.
+		</constant>
+		<constant name="FEATURE_FONT_DYNAMIC" value="128" enum="Feature">
+			TextServer supports loading dynamic (TrueType, OpeType, etc.) fonts.
+		</constant>
+		<constant name="FEATURE_FONT_MSDF" value="256" enum="Feature">
+			TextServer supports multichannel signed distance field dynamic font rendering.
+		</constant>
+		<constant name="FEATURE_FONT_SYSTEM" value="512" enum="Feature">
 			TextServer supports loading system fonts.
 		</constant>
-		<constant name="FEATURE_FONT_VARIABLE" value="64" enum="Feature">
+		<constant name="FEATURE_FONT_VARIABLE" value="1024" enum="Feature">
 			TextServer supports variable fonts.
 		</constant>
-		<constant name="FEATURE_CONTEXT_SENSITIVE_CASE_CONVERSION" value="128" enum="Feature">
+		<constant name="FEATURE_CONTEXT_SENSITIVE_CASE_CONVERSION" value="2048" enum="Feature">
 			TextServer supports locale dependent and context sensitive case conversion.
 		</constant>
-		<constant name="FEATURE_USE_SUPPORT_DATA" value="256" enum="Feature">
+		<constant name="FEATURE_USE_SUPPORT_DATA" value="4096" enum="Feature">
 			TextServer require external data file for some features.
 		</constant>
 		<constant name="CONTOUR_CURVE_TAG_ON" value="1" enum="ContourPointTag">

+ 9 - 0
doc/classes/TextServerDummy.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="TextServerDummy" inherits="TextServerExtension" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
+	<brief_description>
+	</brief_description>
+	<description>
+	</description>
+	<tutorials>
+	</tutorials>
+</class>

Datei-Diff unterdrückt, da er zu groß ist
+ 130 - 138
doc/classes/TextServerExtension.xml


+ 1 - 1
editor/debugger/script_editor_debugger.cpp

@@ -392,7 +392,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
 			stack_dump_info.push_back(d);
 			s->set_metadata(0, d);
 
-			String line = itos(i) + " - " + String(d["file"]) + ":" + itos(d["line"]) + " - at function: " + d["function"];
+			String line = itos(i) + " - " + String(d["file"]) + ":" + itos(d["line"]) + " - at function: " + String(d["function"]);
 			s->set_text(0, line);
 
 			if (i == 0) {

+ 1 - 1
editor/editor_spin_slider.cpp

@@ -346,7 +346,7 @@ void EditorSpinSlider::_draw_spin_slider() {
 			text_ofs.x += glyphs[i].advance;
 		}
 	}
-	TS->free(num_rid);
+	TS->free_rid(num_rid);
 
 	if (get_step() == 1) {
 		Ref<Texture2D> updown2 = get_theme_icon(is_read_only() ? SNAME("updown_disabled") : SNAME("updown"), SNAME("SpinBox"));

+ 1 - 1
editor/import/dynamic_font_import_settings.cpp

@@ -645,7 +645,7 @@ void DynamicFontImportSettings::_glyph_text_selected() {
 				selected_glyphs.insert(gl[i].index);
 			}
 		}
-		TS->free(text_rid);
+		TS->free_rid(text_rid);
 		label_glyphs->set_text(TTR("Preloaded glyphs: ") + itos(selected_glyphs.size()));
 	}
 	_range_selected();

+ 34 - 3
main/main.cpp

@@ -70,6 +70,7 @@
 #include "servers/physics_server_3d.h"
 #include "servers/register_server_types.h"
 #include "servers/rendering/rendering_server_default.h"
+#include "servers/text/text_server_dummy.h"
 #include "servers/text_server.h"
 #include "servers/xr_server.h"
 
@@ -399,6 +400,12 @@ Error Main::test_setup() {
 	translation_server = memnew(TranslationServer);
 	tsman = memnew(TextServerManager);
 
+	if (tsman) {
+		Ref<TextServerDummy> ts;
+		ts.instantiate();
+		tsman->add_interface(ts);
+	}
+
 	register_core_extensions();
 
 	// From `Main::setup2()`.
@@ -435,7 +442,26 @@ Error Main::test_setup() {
 	initialize_theme();
 
 	ERR_FAIL_COND_V(TextServerManager::get_singleton()->get_interface_count() == 0, ERR_CANT_CREATE);
-	TextServerManager::get_singleton()->set_primary_interface(TextServerManager::get_singleton()->get_interface(0));
+
+	/* Use one with the most features available. */
+	int max_features = 0;
+	for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) {
+		uint32_t features = TextServerManager::get_singleton()->get_interface(i)->get_features();
+		int feature_number = 0;
+		while (features) {
+			feature_number += features & 1;
+			features >>= 1;
+		}
+		if (feature_number >= max_features) {
+			max_features = feature_number;
+			text_driver_idx = i;
+		}
+	}
+	if (text_driver_idx >= 0) {
+		TextServerManager::get_singleton()->set_primary_interface(TextServerManager::get_singleton()->get_interface(text_driver_idx));
+	} else {
+		ERR_FAIL_V_MSG(ERR_CANT_CREATE, "TextServer: Unable to create TextServer interface.");
+	}
 
 	ClassDB::set_current_api(ClassDB::API_NONE);
 
@@ -1532,6 +1558,12 @@ error:
 Error Main::setup2(Thread::ID p_main_tid_override) {
 	tsman = memnew(TextServerManager);
 
+	if (tsman) {
+		Ref<TextServerDummy> ts;
+		ts.instantiate();
+		tsman->add_interface(ts);
+	}
+
 	preregister_module_types();
 	preregister_server_types();
 
@@ -1867,8 +1899,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
 	if (text_driver_idx >= 0) {
 		TextServerManager::get_singleton()->set_primary_interface(TextServerManager::get_singleton()->get_interface(text_driver_idx));
 	} else {
-		ERR_PRINT("TextServer: Unable to create TextServer interface.");
-		return ERR_CANT_CREATE;
+		ERR_FAIL_V_MSG(ERR_CANT_CREATE, "TextServer: Unable to create TextServer interface.");
 	}
 
 	MAIN_PRINT("Main: Load Scene Types");

+ 2 - 0
modules/text_server_adv/.gitignore

@@ -0,0 +1,2 @@
+# Godot-cpp headers
+gdextension_build/godot-cpp

+ 1 - 0
modules/text_server_adv/SCsub

@@ -455,6 +455,7 @@ if env["builtin_icu"]:
     if env_icu["tools"]:
         env_icu.Depends("#thirdparty/icu4c/icudata.gen.h", "#thirdparty/icu4c/" + icu_data_name)
         env_icu.Command("#thirdparty/icu4c/icudata.gen.h", "#thirdparty/icu4c/" + icu_data_name, make_icu_data)
+        env_text_server_adv.Append(CPPPATH=["#thirdparty/icu4c/"])
     else:
         thirdparty_sources += ["icu_data/icudata_stub.cpp"]
 

+ 1 - 1
modules/text_server_adv/doc_classes/TextServerAdvanced.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<class name="TextServerAdvanced" inherits="TextServer" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
+<class name="TextServerAdvanced" inherits="TextServerExtension" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
 	<brief_description>
 		Text Server using HarfBuzz, ICU and SIL Graphite to support BiDi, complex text layouts and contextual OpenType features.
 	</brief_description>

+ 638 - 0
modules/text_server_adv/gdextension_build/SConstruct

@@ -0,0 +1,638 @@
+#!/usr/bin/env python
+import atexit
+import os
+import sys
+import methods
+import time
+
+# For the reference:
+# - CCFLAGS are compilation flags shared between C and C++
+# - CFLAGS are for C-specific compilation flags
+# - CXXFLAGS are for C++-specific compilation flags
+# - CPPFLAGS are for pre-processor flags
+# - CPPDEFINES are for pre-processor defines
+# - LINKFLAGS are for linking flags
+
+time_at_start = time.time()
+
+env = SConscript("./godot-cpp/SConstruct")
+env.__class__.disable_warnings = methods.disable_warnings
+
+opts = Variables([], ARGUMENTS)
+opts.Add(BoolVariable("freetype_enabled", "Use FreeType library", True))
+opts.Add(BoolVariable("msdfgen_enabled", "Use MSDFgen library (require FreeType)", True))
+opts.Add(BoolVariable("graphite_enabled", "Use Graphite library (require FreeType)", True))
+opts.Add(BoolVariable("static_icu_data", "Use built-in ICU data", True))
+opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))
+
+opts.Update(env)
+
+if not env["verbose"]:
+    methods.no_verbose(sys, env)
+
+if env["platform"] == "windows" and not env["use_mingw"]:
+    env.AppendUnique(CCFLAGS=["/utf-8"])  # Force to use Unicode encoding.
+
+# MSDFGEN
+if env["msdfgen_enabled"] and env["freetype_enabled"]:
+    env_msdfgen = env.Clone()
+    env_msdfgen.disable_warnings()
+
+    thirdparty_msdfgen_dir = "../../../thirdparty/msdfgen/"
+    thirdparty_msdfgen_sources = [
+        "core/Contour.cpp",
+        "core/EdgeHolder.cpp",
+        "core/MSDFErrorCorrection.cpp",
+        "core/Projection.cpp",
+        "core/Scanline.cpp",
+        "core/Shape.cpp",
+        "core/SignedDistance.cpp",
+        "core/Vector2.cpp",
+        "core/contour-combiners.cpp",
+        "core/edge-coloring.cpp",
+        "core/edge-segments.cpp",
+        "core/edge-selectors.cpp",
+        "core/equation-solver.cpp",
+        "core/msdf-error-correction.cpp",
+        "core/msdfgen.cpp",
+        "core/rasterization.cpp",
+        "core/render-sdf.cpp",
+        "core/sdf-error-estimation.cpp",
+        "core/shape-description.cpp",
+    ]
+    thirdparty_msdfgen_sources = [thirdparty_msdfgen_dir + file for file in thirdparty_msdfgen_sources]
+
+    env_msdfgen.Append(CPPPATH=["../../../thirdparty/freetype/include", "../../../thirdparty/msdfgen"])
+    env.Append(CPPPATH=["../../../thirdparty/msdfgen"])
+    env.Append(CPPDEFINES=["MODULE_MSDFGEN_ENABLED"])
+
+    lib = env_msdfgen.Library(
+        f'msdfgen_builtin.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["LIBSUFFIX"]}',
+        thirdparty_msdfgen_sources,
+    )
+    env.Append(LIBS=[lib])
+
+# FreeType
+if env["freetype_enabled"]:
+    env_freetype = env.Clone()
+    env_freetype.disable_warnings()
+
+    thirdparty_freetype_dir = "../../../thirdparty/freetype/"
+    thirdparty_freetype_sources = [
+        "src/autofit/autofit.c",
+        "src/base/ftbase.c",
+        "src/base/ftbbox.c",
+        "src/base/ftbdf.c",
+        "src/base/ftbitmap.c",
+        "src/base/ftcid.c",
+        "src/base/ftdebug.c",
+        "src/base/ftfstype.c",
+        "src/base/ftgasp.c",
+        "src/base/ftglyph.c",
+        "src/base/ftgxval.c",
+        "src/base/ftinit.c",
+        "src/base/ftmm.c",
+        "src/base/ftotval.c",
+        "src/base/ftpatent.c",
+        "src/base/ftpfr.c",
+        "src/base/ftstroke.c",
+        "src/base/ftsynth.c",
+        "src/base/ftsystem.c",
+        "src/base/fttype1.c",
+        "src/base/ftwinfnt.c",
+        "src/bdf/bdf.c",
+        "src/bzip2/ftbzip2.c",
+        "src/cache/ftcache.c",
+        "src/cff/cff.c",
+        "src/cid/type1cid.c",
+        "src/gxvalid/gxvalid.c",
+        "src/gzip/ftgzip.c",
+        "src/lzw/ftlzw.c",
+        "src/otvalid/otvalid.c",
+        "src/pcf/pcf.c",
+        "src/pfr/pfr.c",
+        "src/psaux/psaux.c",
+        "src/pshinter/pshinter.c",
+        "src/psnames/psnames.c",
+        "src/raster/raster.c",
+        "src/sdf/sdf.c",
+        "src/smooth/smooth.c",
+        "src/truetype/truetype.c",
+        "src/type1/type1.c",
+        "src/type42/type42.c",
+        "src/winfonts/winfnt.c",
+        "src/sfnt/sfnt.c",
+    ]
+    thirdparty_freetype_sources = [thirdparty_freetype_dir + file for file in thirdparty_freetype_sources]
+
+    thirdparty_png_dir = "../../../thirdparty/libpng/"
+    thirdparty_png_sources = [
+        "png.c",
+        "pngerror.c",
+        "pngget.c",
+        "pngmem.c",
+        "pngpread.c",
+        "pngread.c",
+        "pngrio.c",
+        "pngrtran.c",
+        "pngrutil.c",
+        "pngset.c",
+        "pngtrans.c",
+        "pngwio.c",
+        "pngwrite.c",
+        "pngwtran.c",
+        "pngwutil.c",
+    ]
+    thirdparty_freetype_sources += [thirdparty_png_dir + file for file in thirdparty_png_sources]
+
+    thirdparty_zlib_dir = "../../../thirdparty/zlib/"
+    thirdparty_zlib_sources = [
+        "adler32.c",
+        "compress.c",
+        "crc32.c",
+        "deflate.c",
+        "infback.c",
+        "inffast.c",
+        "inflate.c",
+        "inftrees.c",
+        "trees.c",
+        "uncompr.c",
+        "zutil.c",
+    ]
+    thirdparty_freetype_sources += [thirdparty_zlib_dir + file for file in thirdparty_zlib_sources]
+
+    env_freetype.Append(CPPPATH=[thirdparty_freetype_dir + "/include", thirdparty_zlib_dir, thirdparty_png_dir])
+    env.Append(CPPPATH=[thirdparty_freetype_dir + "/include"])
+
+    env_freetype.Append(CPPDEFINES=["FT2_BUILD_LIBRARY", "FT_CONFIG_OPTION_USE_PNG", ("PNG_ARM_NEON_OPT", 0)])
+    if env["target"] == "debug":
+        env_freetype.Append(CPPDEFINES=["ZLIB_DEBUG"])
+
+    env.Append(CPPDEFINES=["MODULE_FREETYPE_ENABLED"])
+
+    lib = env_freetype.Library(
+        f'freetype_builtin.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["LIBSUFFIX"]}',
+        thirdparty_freetype_sources,
+    )
+    env.Append(LIBS=[lib])
+
+# HarfBuzz
+env_harfbuzz = env.Clone()
+env_harfbuzz.disable_warnings()
+
+thirdparty_harfbuzz_dir = "../../../thirdparty/harfbuzz/"
+thirdparty_harfbuzz_sources = [
+    "src/hb-aat-layout.cc",
+    "src/hb-aat-map.cc",
+    "src/hb-blob.cc",
+    "src/hb-buffer-serialize.cc",
+    "src/hb-buffer-verify.cc",
+    "src/hb-buffer.cc",
+    "src/hb-common.cc",
+    #'src/hb-coretext.cc',
+    #'src/hb-directwrite.cc',
+    "src/hb-draw.cc",
+    "src/hb-face.cc",
+    "src/hb-fallback-shape.cc",
+    "src/hb-font.cc",
+    #'src/hb-gdi.cc',
+    #'src/hb-glib.cc',
+    #'src/hb-gobject-structs.cc',
+    "src/hb-icu.cc",
+    "src/hb-map.cc",
+    "src/hb-number.cc",
+    "src/hb-ot-cff1-table.cc",
+    "src/hb-ot-cff2-table.cc",
+    "src/hb-ot-color.cc",
+    "src/hb-ot-face.cc",
+    "src/hb-ot-font.cc",
+    "src/hb-ot-layout.cc",
+    "src/hb-ot-map.cc",
+    "src/hb-ot-math.cc",
+    "src/hb-ot-meta.cc",
+    "src/hb-ot-metrics.cc",
+    "src/hb-ot-name.cc",
+    "src/hb-ot-shape-complex-arabic.cc",
+    "src/hb-ot-shape-complex-default.cc",
+    "src/hb-ot-shape-complex-hangul.cc",
+    "src/hb-ot-shape-complex-hebrew.cc",
+    "src/hb-ot-shape-complex-indic-table.cc",
+    "src/hb-ot-shape-complex-indic.cc",
+    "src/hb-ot-shape-complex-khmer.cc",
+    "src/hb-ot-shape-complex-myanmar.cc",
+    "src/hb-ot-shape-complex-syllabic.cc",
+    "src/hb-ot-shape-complex-thai.cc",
+    "src/hb-ot-shape-complex-use.cc",
+    "src/hb-ot-shape-complex-vowel-constraints.cc",
+    "src/hb-ot-shape-fallback.cc",
+    "src/hb-ot-shape-normalize.cc",
+    "src/hb-ot-shape.cc",
+    "src/hb-ot-tag.cc",
+    "src/hb-ot-var.cc",
+    "src/hb-set.cc",
+    "src/hb-shape-plan.cc",
+    "src/hb-shape.cc",
+    "src/hb-shaper.cc",
+    "src/hb-static.cc",
+    "src/hb-style.cc",
+    "src/hb-subset-cff-common.cc",
+    "src/hb-subset-cff1.cc",
+    "src/hb-subset-cff2.cc",
+    "src/hb-subset-input.cc",
+    "src/hb-subset-plan.cc",
+    "src/hb-subset.cc",
+    "src/hb-ucd.cc",
+    "src/hb-unicode.cc",
+    #'src/hb-uniscribe.cc'
+]
+
+if env["freetype_enabled"]:
+    thirdparty_harfbuzz_sources += [
+        "src/hb-ft.cc",
+        "src/hb-graphite2.cc",
+    ]
+thirdparty_harfbuzz_sources = [thirdparty_harfbuzz_dir + file for file in thirdparty_harfbuzz_sources]
+
+env_harfbuzz.Append(
+    CPPPATH=[
+        "../../../thirdparty/harfbuzz/src",
+        "../../../thirdparty/icu4c/common/",
+    ]
+)
+
+if env["freetype_enabled"]:
+    env_harfbuzz.Append(
+        CPPPATH=[
+            "../../../thirdparty/freetype/include",
+            "../../../thirdparty/graphite/include",
+        ]
+    )
+
+if env["platform"] == "android" or env["platform"] == "linuxbsd":
+    env_harfbuzz.Append(CCFLAGS=["-DHAVE_PTHREAD"])
+
+env_harfbuzz.Append(
+    CCFLAGS=[
+        "-DHAVE_ICU_BUILTIN",
+        "-DHAVE_ICU",
+    ]
+)
+
+if env["freetype_enabled"]:
+    env_harfbuzz.Append(
+        CCFLAGS=[
+            "-DHAVE_FREETYPE",
+            "-DHAVE_GRAPHITE2",
+            "-DGRAPHITE2_STATIC",
+        ]
+    )
+
+env.Append(CPPPATH=["../../../thirdparty/harfbuzz/src"])
+
+lib = env_harfbuzz.Library(
+    f'harfbuzz_builtin.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["LIBSUFFIX"]}',
+    thirdparty_harfbuzz_sources,
+)
+env.Prepend(LIBS=[lib])
+
+# Graphite
+if env["graphite_enabled"] and env["freetype_enabled"]:
+    env_graphite = env.Clone()
+    env_graphite.disable_warnings()
+
+    thirdparty_graphite_dir = "../../../thirdparty/graphite/"
+    thirdparty_graphite_sources = [
+        "src/gr_char_info.cpp",
+        "src/gr_face.cpp",
+        "src/gr_features.cpp",
+        "src/gr_font.cpp",
+        "src/gr_logging.cpp",
+        "src/gr_segment.cpp",
+        "src/gr_slot.cpp",
+        "src/CmapCache.cpp",
+        "src/Code.cpp",
+        "src/Collider.cpp",
+        "src/Decompressor.cpp",
+        "src/Face.cpp",
+        #'src/FileFace.cpp',
+        "src/FeatureMap.cpp",
+        "src/Font.cpp",
+        "src/GlyphCache.cpp",
+        "src/GlyphFace.cpp",
+        "src/Intervals.cpp",
+        "src/Justifier.cpp",
+        "src/NameTable.cpp",
+        "src/Pass.cpp",
+        "src/Position.cpp",
+        "src/Segment.cpp",
+        "src/Silf.cpp",
+        "src/Slot.cpp",
+        "src/Sparse.cpp",
+        "src/TtfUtil.cpp",
+        "src/UtfCodec.cpp",
+        "src/FileFace.cpp",
+        "src/json.cpp",
+    ]
+    if env["platform"] != "windows" or env["use_mingw"]:
+        thirdparty_graphite_sources += ["src/direct_machine.cpp"]
+    else:
+        thirdparty_graphite_sources += ["src/call_machine.cpp"]
+
+    thirdparty_graphite_sources = [thirdparty_graphite_dir + file for file in thirdparty_graphite_sources]
+
+    env_graphite.Append(CPPPATH=["../../../thirdparty/graphite/src", "../../../thirdparty/graphite/include"])
+    env_graphite.Append(
+        CCFLAGS=[
+            "-DGRAPHITE2_STATIC",
+            "-DGRAPHITE2_NTRACING",
+            "-DGRAPHITE2_NFILEFACE",
+        ]
+    )
+
+    lib = env_graphite.Library(
+        f'graphite_builtin.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["LIBSUFFIX"]}',
+        thirdparty_graphite_sources,
+    )
+    env.Append(LIBS=[lib])
+
+# ICU
+env_icu = env.Clone()
+env_icu.disable_warnings()
+
+thirdparty_icu_dir = "../../../thirdparty/icu4c/"
+thirdparty_icu_sources = [
+    "common/appendable.cpp",
+    "common/bmpset.cpp",
+    "common/brkeng.cpp",
+    "common/brkiter.cpp",
+    "common/bytesinkutil.cpp",
+    "common/bytestream.cpp",
+    "common/bytestrie.cpp",
+    "common/bytestriebuilder.cpp",
+    "common/bytestrieiterator.cpp",
+    "common/caniter.cpp",
+    "common/characterproperties.cpp",
+    "common/chariter.cpp",
+    "common/charstr.cpp",
+    "common/cmemory.cpp",
+    "common/cstr.cpp",
+    "common/cstring.cpp",
+    "common/cwchar.cpp",
+    "common/dictbe.cpp",
+    "common/dictionarydata.cpp",
+    "common/dtintrv.cpp",
+    "common/edits.cpp",
+    "common/emojiprops.cpp",
+    "common/errorcode.cpp",
+    "common/filteredbrk.cpp",
+    "common/filterednormalizer2.cpp",
+    "common/icudataver.cpp",
+    "common/icuplug.cpp",
+    "common/loadednormalizer2impl.cpp",
+    "common/localebuilder.cpp",
+    "common/localematcher.cpp",
+    "common/localeprioritylist.cpp",
+    "common/locavailable.cpp",
+    "common/locbased.cpp",
+    "common/locdispnames.cpp",
+    "common/locdistance.cpp",
+    "common/locdspnm.cpp",
+    "common/locid.cpp",
+    "common/loclikely.cpp",
+    "common/loclikelysubtags.cpp",
+    "common/locmap.cpp",
+    "common/locresdata.cpp",
+    "common/locutil.cpp",
+    "common/lsr.cpp",
+    "common/lstmbe.cpp",
+    "common/messagepattern.cpp",
+    "common/normalizer2.cpp",
+    "common/normalizer2impl.cpp",
+    "common/normlzr.cpp",
+    "common/parsepos.cpp",
+    "common/patternprops.cpp",
+    "common/pluralmap.cpp",
+    "common/propname.cpp",
+    "common/propsvec.cpp",
+    "common/punycode.cpp",
+    "common/putil.cpp",
+    "common/rbbi.cpp",
+    "common/rbbi_cache.cpp",
+    "common/rbbidata.cpp",
+    "common/rbbinode.cpp",
+    "common/rbbirb.cpp",
+    "common/rbbiscan.cpp",
+    "common/rbbisetb.cpp",
+    "common/rbbistbl.cpp",
+    "common/rbbitblb.cpp",
+    "common/resbund.cpp",
+    "common/resbund_cnv.cpp",
+    "common/resource.cpp",
+    "common/restrace.cpp",
+    "common/ruleiter.cpp",
+    "common/schriter.cpp",
+    "common/serv.cpp",
+    "common/servlk.cpp",
+    "common/servlkf.cpp",
+    "common/servls.cpp",
+    "common/servnotf.cpp",
+    "common/servrbf.cpp",
+    "common/servslkf.cpp",
+    "common/sharedobject.cpp",
+    "common/simpleformatter.cpp",
+    "common/static_unicode_sets.cpp",
+    "common/stringpiece.cpp",
+    "common/stringtriebuilder.cpp",
+    "common/uarrsort.cpp",
+    "common/ubidi.cpp",
+    "common/ubidi_props.cpp",
+    "common/ubidiln.cpp",
+    "common/ubiditransform.cpp",
+    "common/ubidiwrt.cpp",
+    "common/ubrk.cpp",
+    "common/ucase.cpp",
+    "common/ucasemap.cpp",
+    "common/ucasemap_titlecase_brkiter.cpp",
+    "common/ucat.cpp",
+    "common/uchar.cpp",
+    "common/ucharstrie.cpp",
+    "common/ucharstriebuilder.cpp",
+    "common/ucharstrieiterator.cpp",
+    "common/uchriter.cpp",
+    "common/ucln_cmn.cpp",
+    "common/ucmndata.cpp",
+    "common/ucnv.cpp",
+    "common/ucnv2022.cpp",
+    "common/ucnv_bld.cpp",
+    "common/ucnv_cb.cpp",
+    "common/ucnv_cnv.cpp",
+    "common/ucnv_ct.cpp",
+    "common/ucnv_err.cpp",
+    "common/ucnv_ext.cpp",
+    "common/ucnv_io.cpp",
+    "common/ucnv_lmb.cpp",
+    "common/ucnv_set.cpp",
+    "common/ucnv_u16.cpp",
+    "common/ucnv_u32.cpp",
+    "common/ucnv_u7.cpp",
+    "common/ucnv_u8.cpp",
+    "common/ucnvbocu.cpp",
+    "common/ucnvdisp.cpp",
+    "common/ucnvhz.cpp",
+    "common/ucnvisci.cpp",
+    "common/ucnvlat1.cpp",
+    "common/ucnvmbcs.cpp",
+    "common/ucnvscsu.cpp",
+    "common/ucnvsel.cpp",
+    "common/ucol_swp.cpp",
+    "common/ucptrie.cpp",
+    "common/ucurr.cpp",
+    "common/udata.cpp",
+    "common/udatamem.cpp",
+    "common/udataswp.cpp",
+    "common/uenum.cpp",
+    "common/uhash.cpp",
+    "common/uhash_us.cpp",
+    "common/uidna.cpp",
+    "common/uinit.cpp",
+    "common/uinvchar.cpp",
+    "common/uiter.cpp",
+    "common/ulist.cpp",
+    "common/uloc.cpp",
+    "common/uloc_keytype.cpp",
+    "common/uloc_tag.cpp",
+    "common/umapfile.cpp",
+    "common/umath.cpp",
+    "common/umutablecptrie.cpp",
+    "common/umutex.cpp",
+    "common/unames.cpp",
+    "common/unifiedcache.cpp",
+    "common/unifilt.cpp",
+    "common/unifunct.cpp",
+    "common/uniset.cpp",
+    "common/uniset_closure.cpp",
+    "common/uniset_props.cpp",
+    "common/unisetspan.cpp",
+    "common/unistr.cpp",
+    "common/unistr_case.cpp",
+    "common/unistr_case_locale.cpp",
+    "common/unistr_cnv.cpp",
+    "common/unistr_props.cpp",
+    "common/unistr_titlecase_brkiter.cpp",
+    "common/unorm.cpp",
+    "common/unormcmp.cpp",
+    "common/uobject.cpp",
+    "common/uprops.cpp",
+    "common/ures_cnv.cpp",
+    "common/uresbund.cpp",
+    "common/uresdata.cpp",
+    "common/usc_impl.cpp",
+    "common/uscript.cpp",
+    "common/uscript_props.cpp",
+    "common/uset.cpp",
+    "common/uset_props.cpp",
+    "common/usetiter.cpp",
+    # "common/ushape.cpp",
+    "common/usprep.cpp",
+    "common/ustack.cpp",
+    "common/ustr_cnv.cpp",
+    "common/ustr_titlecase_brkiter.cpp",
+    "common/ustr_wcs.cpp",
+    "common/ustrcase.cpp",
+    "common/ustrcase_locale.cpp",
+    "common/ustrenum.cpp",
+    "common/ustrfmt.cpp",
+    "common/ustring.cpp",
+    "common/ustrtrns.cpp",
+    "common/utext.cpp",
+    "common/utf_impl.cpp",
+    "common/util.cpp",
+    "common/util_props.cpp",
+    "common/utrace.cpp",
+    "common/utrie.cpp",
+    "common/utrie2.cpp",
+    "common/utrie2_builder.cpp",
+    "common/utrie_swap.cpp",
+    "common/uts46.cpp",
+    "common/utypes.cpp",
+    "common/uvector.cpp",
+    "common/uvectr32.cpp",
+    "common/uvectr64.cpp",
+    "common/wintz.cpp",
+]
+thirdparty_icu_sources = [thirdparty_icu_dir + file for file in thirdparty_icu_sources]
+
+icu_data_name = "icudt70l.dat"
+
+if env["static_icu_data"]:
+    env_icu.Depends("../../../thirdparty/icu4c/icudata.gen.h", "../../../thirdparty/icu4c/" + icu_data_name)
+    env_icu.Command(
+        "../../../thirdparty/icu4c/icudata.gen.h", "../../../thirdparty/icu4c/" + icu_data_name, methods.make_icu_data
+    )
+    env.Append(CXXFLAGS=["-DICU_STATIC_DATA"])
+    env.Append(CPPPATH=["../../../thirdparty/icu4c/"])
+else:
+    thirdparty_sources += ["../icu_data/icudata_stub.cpp"]
+
+env_icu.Append(CPPPATH=["../../../thirdparty/icu4c/common/"])
+env_icu.Append(
+    CXXFLAGS=[
+        "-DU_STATIC_IMPLEMENTATION",
+        "-DU_COMMON_IMPLEMENTATION",
+        "-DUCONFIG_NO_COLLATION",
+        "-DUCONFIG_NO_CONVERSION",
+        "-DUCONFIG_NO_FORMATTING",
+        "-DUCONFIG_NO_SERVICE",
+        "-DUCONFIG_NO_IDNA",
+        "-DUCONFIG_NO_FILE_IO",
+        "-DUCONFIG_NO_TRANSLITERATION",
+        "-DPKGDATA_MODE=static",
+        "-DICU_DATA_NAME=" + icu_data_name,
+    ]
+)
+env.Append(
+    CXXFLAGS=[
+        "-DICU_DATA_NAME=" + icu_data_name,
+    ]
+)
+env.Append(CPPPATH=["../../../thirdparty/icu4c/common/"])
+
+if env["platform"] == "windows":
+    env.Append(LIBS=["advapi32"])
+
+lib = env_icu.Library(
+    f'icu_builtin.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["LIBSUFFIX"]}', thirdparty_icu_sources
+)
+env.Append(LIBS=[lib])
+
+env.Append(CPPDEFINES=["GDEXTENSION"])
+env.Append(CPPPATH=["../"])
+sources = Glob("../*.cpp")
+
+if env["platform"] == "osx":
+    methods.write_osx_plist(
+        f'./bin/libtextserver_advanced.osx.{env["target"]}.framework',
+        f'libtextserver_advanced.osx.{env["target"]}',
+        "org.godotengine.textserver_advanced",
+        "ICU / HarfBuzz / Graphite Text Server",
+    )
+    library = env.SharedLibrary(
+        f'./bin/libtextserver_advanced.osx.{env["target"]}.framework/libtextserver_advanced.osx.{env["target"]}',
+        source=sources,
+    )
+else:
+    library = env.SharedLibrary(
+        f'./bin/libtextserver_advanced.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["SHLIBSUFFIX"]}',
+        source=sources,
+    )
+
+Default(library)
+
+
+def print_elapsed_time():
+    elapsed_time_sec = round(time.time() - time_at_start, 3)
+    time_ms = round((elapsed_time_sec % 1) * 1000)
+    print("[Time elapsed: {}.{:03}]".format(time.strftime("%H:%M:%S", time.gmtime(elapsed_time_sec)), time_ms))
+
+
+atexit.register(print_elapsed_time)

+ 130 - 0
modules/text_server_adv/gdextension_build/methods.py

@@ -0,0 +1,130 @@
+import os
+import sys
+
+
+def no_verbose(sys, env):
+    colors = {}
+
+    # Colors are disabled in non-TTY environments such as pipes. This means
+    # that if output is redirected to a file, it will not contain color codes
+    if sys.stdout.isatty():
+        colors["blue"] = "\033[0;94m"
+        colors["bold_blue"] = "\033[1;94m"
+        colors["reset"] = "\033[0m"
+    else:
+        colors["blue"] = ""
+        colors["bold_blue"] = ""
+        colors["reset"] = ""
+
+    # There is a space before "..." to ensure that source file names can be
+    # Ctrl + clicked in the VS Code terminal.
+    compile_source_message = "{}Compiling {}$SOURCE{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+    java_compile_source_message = "{}Compiling {}$SOURCE{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+    compile_shared_source_message = "{}Compiling shared {}$SOURCE{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+    link_program_message = "{}Linking Program {}$TARGET{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+    link_library_message = "{}Linking Static Library {}$TARGET{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+    ranlib_library_message = "{}Ranlib Library {}$TARGET{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+    link_shared_library_message = "{}Linking Shared Library {}$TARGET{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+    java_library_message = "{}Creating Java Archive {}$TARGET{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+
+    env.Append(CXXCOMSTR=[compile_source_message])
+    env.Append(CCCOMSTR=[compile_source_message])
+    env.Append(SHCCCOMSTR=[compile_shared_source_message])
+    env.Append(SHCXXCOMSTR=[compile_shared_source_message])
+    env.Append(ARCOMSTR=[link_library_message])
+    env.Append(RANLIBCOMSTR=[ranlib_library_message])
+    env.Append(SHLINKCOMSTR=[link_shared_library_message])
+    env.Append(LINKCOMSTR=[link_program_message])
+    env.Append(JARCOMSTR=[java_library_message])
+    env.Append(JAVACCOMSTR=[java_compile_source_message])
+
+
+def disable_warnings(self):
+    # 'self' is the environment
+    if self["platform"] == "windows" and not self["use_mingw"]:
+        # We have to remove existing warning level defines before appending /w,
+        # otherwise we get: "warning D9025 : overriding '/W3' with '/w'"
+        warn_flags = ["/Wall", "/W4", "/W3", "/W2", "/W1", "/WX"]
+        self.Append(CCFLAGS=["/w"])
+        self.Append(CFLAGS=["/w"])
+        self.Append(CXXFLAGS=["/w"])
+        self["CCFLAGS"] = [x for x in self["CCFLAGS"] if not x in warn_flags]
+        self["CFLAGS"] = [x for x in self["CFLAGS"] if not x in warn_flags]
+        self["CXXFLAGS"] = [x for x in self["CXXFLAGS"] if not x in warn_flags]
+    else:
+        self.Append(CCFLAGS=["-w"])
+        self.Append(CFLAGS=["-w"])
+        self.Append(CXXFLAGS=["-w"])
+
+
+def make_icu_data(target, source, env):
+    dst = target[0].srcnode().abspath
+    g = open(dst, "w", encoding="utf-8")
+
+    g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+    g.write("/* (C) 2016 and later: Unicode, Inc. and others. */\n")
+    g.write("/* License & terms of use: https://www.unicode.org/copyright.html */\n")
+    g.write("#ifndef _ICU_DATA_H\n")
+    g.write("#define _ICU_DATA_H\n")
+    g.write('#include "unicode/utypes.h"\n')
+    g.write('#include "unicode/udata.h"\n')
+    g.write('#include "unicode/uversion.h"\n')
+
+    f = open(source[0].srcnode().abspath, "rb")
+    buf = f.read()
+
+    g.write('extern "C" U_EXPORT const size_t U_ICUDATA_SIZE = ' + str(len(buf)) + ";\n")
+    g.write('extern "C" U_EXPORT const unsigned char U_ICUDATA_ENTRY_POINT[] = {\n')
+    for i in range(len(buf)):
+        g.write("\t" + str(buf[i]) + ",\n")
+
+    g.write("};\n")
+    g.write("#endif")
+
+
+def write_osx_plist(target, binary_name, identifier, name):
+    os.makedirs(f"{target}/Resourece/", exist_ok=True)
+    f = open(f"{target}/Resourece/Info.plist", "w")
+
+    f.write(f'<?xml version="1.0" encoding="UTF-8"?>\n')
+    f.write(f'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n')
+    f.write(f'<plist version="1.0">\n')
+    f.write(f"<dict>\n")
+    f.write(f"\t<key>CFBundleExecutable</key>\n")
+    f.write(f"\t<string>{binary_name}</string>\n")
+    f.write(f"\t<key>CFBundleIdentifier</key>\n")
+    f.write(f"\t<string>{identifier}</string>\n")
+    f.write(f"\t<key>CFBundleInfoDictionaryVersion</key>\n")
+    f.write(f"\t<string>6.0</string>\n")
+    f.write(f"\t<key>CFBundleName</key>\n")
+    f.write(f"\t<string>{name}</string>\n")
+    f.write(f"\t<key>CFBundlePackageType</key>\n")
+    f.write(f"\t<string>FMWK</string>\n")
+    f.write(f"\t<key>CFBundleShortVersionString</key>\n")
+    f.write(f"\t<string>1.0.0</string>\n")
+    f.write(f"\t<key>CFBundleSupportedPlatforms</key>\n")
+    f.write(f"\t<array>\n")
+    f.write(f"\t\t<string>MacOSX</string>\n")
+    f.write(f"\t</array>\n")
+    f.write(f"\t<key>CFBundleVersion</key>\n")
+    f.write(f"\t<string>1.0.0</string>\n")
+    f.write(f"\t<key>LSMinimumSystemVersion</key>\n")
+    f.write(f"\t<string>10.14</string>\n")
+    f.write(f"</dict>\n")
+    f.write(f"</plist>\n")

+ 12 - 0
modules/text_server_adv/gdextension_build/text_server_adv.gdextension

@@ -0,0 +1,12 @@
+[configuration]
+
+entry_symbol = "textserver_advanced_init"
+
+[libraries]
+
+linux.64.debug = "bin/libtextserver_advanced.linux.debug.64.so"
+linux.64.release = "bin/libtextserver_advanced.linux.release.64.so"
+windows.64.debug = "bin/libtextserver_advanced.windows.debug.64.dll"
+windows.64.release = "bin/libtextserver_advanced.windows.release.64.dll"
+macos.debug = "bin/libtextserver_advanced.osx.debug.framework"
+macos.release = "bin/libtextserver_advanced.osx.release.framework"

+ 26 - 2
modules/text_server_adv/register_types.cpp

@@ -34,10 +34,11 @@
 
 void preregister_text_server_adv_types() {
 	GDREGISTER_CLASS(TextServerAdvanced);
-	if (TextServerManager::get_singleton()) {
+	TextServerManager *tsman = TextServerManager::get_singleton();
+	if (tsman) {
 		Ref<TextServerAdvanced> ts;
 		ts.instantiate();
-		TextServerManager::get_singleton()->add_interface(ts);
+		tsman->add_interface(ts);
 	}
 }
 
@@ -46,3 +47,26 @@ void register_text_server_adv_types() {
 
 void unregister_text_server_adv_types() {
 }
+
+#ifdef GDEXTENSION
+
+#include <godot_cpp/core/class_db.hpp>
+#include <godot_cpp/core/defs.hpp>
+#include <godot_cpp/core/memory.hpp>
+
+using namespace godot;
+
+extern "C" {
+
+GDNativeBool GDN_EXPORT textserver_advanced_init(const GDNativeInterface *p_interface, const GDNativeExtensionClassLibraryPtr p_library, GDNativeInitialization *r_initialization) {
+	GDExtensionBinding::InitObject init_obj(p_interface, p_library, r_initialization);
+
+	init_obj.register_server_initializer(&preregister_text_server_adv_types);
+	init_obj.register_server_terminator(&unregister_text_server_adv_types);
+
+	return init_obj.init();
+}
+
+} // ! extern "C"
+
+#endif // ! GDEXTENSION

+ 16 - 1
modules/text_server_adv/script_iterator.h

@@ -31,7 +31,22 @@
 #ifndef SCRIPT_ITERATOR_H
 #define SCRIPT_ITERATOR_H
 
-#include "servers/text_server.h"
+#ifdef GDEXTENSION
+
+// Headers for building as GDExtension plug-in.
+#include <godot_cpp/godot.hpp>
+#include <godot_cpp/templates/vector.hpp>
+#include <godot_cpp/variant/string.hpp>
+
+using namespace godot;
+
+#else
+
+// Headers for building as built-in module.
+#include "core/string/ustring.h"
+#include "core/templates/vector.h"
+
+#endif
 
 #include <unicode/uchar.h>
 #include <unicode/uloc.h>

Datei-Diff unterdrückt, da er zu groß ist
+ 381 - 316
modules/text_server_adv/text_server_adv.cpp


+ 291 - 177
modules/text_server_adv/text_server_adv.h

@@ -36,13 +36,61 @@
 /* shaping and advanced font features support.                           */
 /*************************************************************************/
 
-#include "servers/text_server.h"
+#ifdef GDEXTENSION
+// Headers for building as GDExtension plug-in.
+
+#include <godot_cpp/godot.hpp>
+
+#include <godot_cpp/core/class_db.hpp>
+#include <godot_cpp/core/mutex_lock.hpp>
+
+#include <godot_cpp/variant/array.hpp>
+#include <godot_cpp/variant/dictionary.hpp>
+#include <godot_cpp/variant/packed_int32_array.hpp>
+#include <godot_cpp/variant/packed_string_array.hpp>
+#include <godot_cpp/variant/packed_vector2_array.hpp>
+#include <godot_cpp/variant/rect2.hpp>
+#include <godot_cpp/variant/rid.hpp>
+#include <godot_cpp/variant/string.hpp>
+#include <godot_cpp/variant/vector2.hpp>
+#include <godot_cpp/variant/vector2i.hpp>
+
+#include <godot_cpp/classes/text_server.hpp>
+#include <godot_cpp/classes/text_server_extension.hpp>
+#include <godot_cpp/classes/text_server_manager.hpp>
+
+#include <godot_cpp/classes/caret_info.hpp>
+#include <godot_cpp/classes/global_constants_binds.hpp>
+#include <godot_cpp/classes/glyph.hpp>
+#include <godot_cpp/classes/image.hpp>
+#include <godot_cpp/classes/image_texture.hpp>
+#include <godot_cpp/classes/ref.hpp>
+
+#include <godot_cpp/templates/hash_map.hpp>
+#include <godot_cpp/templates/map.hpp>
+#include <godot_cpp/templates/rid_owner.hpp>
+#include <godot_cpp/templates/set.hpp>
+#include <godot_cpp/templates/thread_work_pool.hpp>
+#include <godot_cpp/templates/vector.hpp>
+
+using namespace godot;
+
+#else
+// Headers for building as built-in module.
 
 #include "core/templates/rid_owner.h"
 #include "core/templates/thread_work_pool.h"
 #include "scene/resources/texture.h"
+#include "servers/text/text_server_extension.h"
+
+#include "modules/modules_enabled.gen.h" // For freetype, msdfgen.
+
+#endif
+
 #include "script_iterator.h"
 
+// Thirdparty headers.
+
 #include <unicode/ubidi.h>
 #include <unicode/ubrk.h>
 #include <unicode/uchar.h>
@@ -55,8 +103,6 @@
 #include <unicode/ustring.h>
 #include <unicode/utypes.h>
 
-#include "modules/modules_enabled.gen.h" // For freetype, msdfgen.
-
 #ifdef MODULE_FREETYPE_ENABLED
 #include <ft2build.h>
 #include FT_FREETYPE_H
@@ -73,12 +119,11 @@
 #include <hb-icu.h>
 #include <hb.h>
 
-class TextServerAdvanced : public TextServer {
-	GDCLASS(TextServerAdvanced, TextServer);
-	_THREAD_SAFE_CLASS_
+/*************************************************************************/
 
-	static String interface_name;
-	static uint32_t interface_features;
+class TextServerAdvanced : public TextServerExtension {
+	GDCLASS(TextServerAdvanced, TextServerExtension);
+	_THREAD_SAFE_CLASS_
 
 	struct NumSystemData {
 		Set<StringName> lang;
@@ -89,21 +134,23 @@ class TextServerAdvanced : public TextServer {
 
 	Vector<NumSystemData> num_systems;
 	Map<StringName, int32_t> feature_sets;
+	Map<int32_t, StringName> feature_sets_inv;
 
 	void _insert_num_systems_lang();
 	void _insert_feature_sets();
+	_FORCE_INLINE_ void _insert_feature(const StringName &p_name, int32_t p_tag);
 
 	// ICU support data.
 
-	uint8_t *icu_data = nullptr;
+	bool icu_data_loaded = false;
 
 	// Font cache data.
 
 #ifdef MODULE_FREETYPE_ENABLED
-	mutable FT_Library library = nullptr;
+	mutable FT_Library ft_library = nullptr;
 #endif
 
-	const int rect_range = 2;
+	const int rect_range = 1;
 
 	struct FontTexture {
 		Image::Format format;
@@ -129,12 +176,12 @@ class TextServerAdvanced : public TextServer {
 	};
 
 	struct FontDataForSizeAdvanced {
-		float ascent = 0.f;
-		float descent = 0.f;
-		float underline_position = 0.f;
-		float underline_thickness = 0.f;
-		float scale = 1.f;
-		float oversampling = 1.f;
+		double ascent = 0.0;
+		double descent = 0.0;
+		double underline_position = 0.0;
+		double underline_thickness = 0.0;
+		double scale = 1.0;
+		double oversampling = 1.0;
 
 		int spacing_glyph = 0;
 		int spacing_space = 0;
@@ -176,8 +223,8 @@ class TextServerAdvanced : public TextServer {
 		TextServer::Hinting hinting = TextServer::HINTING_LIGHT;
 		TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO;
 		Dictionary variation_coordinates;
-		float oversampling = 0.f;
-		float embolden = 0.f;
+		double oversampling = 0.0;
+		double embolden = 0.0;
 		Transform2D transform;
 
 		uint32_t style_flags = 0;
@@ -203,8 +250,8 @@ class TextServerAdvanced : public TextServer {
 
 		~FontDataAdvanced() {
 			work_pool.finish();
-			for (const Map<Vector2i, FontDataForSizeAdvanced *>::Element *E = cache.front(); E; E = E->next()) {
-				memdelete(E->get());
+			for (const KeyValue<Vector2i, FontDataForSizeAdvanced *> &E : cache) {
+				memdelete(E.value);
 			}
 			cache.clear();
 		}
@@ -242,16 +289,34 @@ class TextServerAdvanced : public TextServer {
 		}
 	}
 
-	_FORCE_INLINE_ float _get_extra_advance(RID p_font_rid, int p_font_size) const;
+	_FORCE_INLINE_ double _get_extra_advance(RID p_font_rid, int p_font_size) const;
 
 	// Shaped text cache data.
+	struct TrimData {
+		int trim_pos = -1;
+		int ellipsis_pos = -1;
+		Vector<Glyph> ellipsis_glyph_buf;
+	};
+
+	struct ShapedTextDataAdvanced {
+		Mutex mutex;
+
+		/* Source data */
+		RID parent; // Substring parent ShapedTextData.
+
+		int start = 0; // Substring start offset in the parent string.
+		int end = 0; // Substring end offset in the parent string.
+
+		String text;
+		String custom_punct;
+		TextServer::Direction direction = DIRECTION_LTR; // Desired text direction.
+		TextServer::Orientation orientation = ORIENTATION_HORIZONTAL;
 
-	struct ShapedTextDataAdvanced : public ShapedTextData {
 		struct Span {
 			int start = -1;
 			int end = -1;
 
-			Vector<RID> fonts;
+			Array fonts;
 			int font_size = 0;
 
 			Variant embedded_key;
@@ -262,6 +327,38 @@ class TextServerAdvanced : public TextServer {
 		};
 		Vector<Span> spans;
 
+		struct EmbeddedObject {
+			int pos = 0;
+			InlineAlignment inline_align = INLINE_ALIGNMENT_CENTER;
+			Rect2 rect;
+		};
+		Map<Variant, EmbeddedObject> objects;
+
+		/* Shaped data */
+		TextServer::Direction para_direction = DIRECTION_LTR; // Detected text direction.
+		bool valid = false; // String is shaped.
+		bool line_breaks_valid = false; // Line and word break flags are populated (and virtual zero width spaces inserted).
+		bool justification_ops_valid = false; // Virtual elongation glyphs are added to the string.
+		bool sort_valid = false;
+		bool text_trimmed = false;
+
+		bool preserve_invalid = true; // Draw hex code box instead of missing characters.
+		bool preserve_control = false; // Draw control characters.
+
+		double ascent = 0.0; // Ascent for horizontal layout, 1/2 of width for vertical.
+		double descent = 0.0; // Descent for horizontal layout, 1/2 of width for vertical.
+		double width = 0.0; // Width for horizontal layout, height for vertical.
+		double width_trimmed = 0.0;
+
+		double upos = 0.0;
+		double uthk = 0.0;
+
+		TrimData overrun_trim_data;
+		bool fit_width_minimum_reached = false;
+
+		Vector<Glyph> glyphs;
+		Vector<Glyph> glyphs_logical;
+
 		/* Intermediate data */
 		Char16String utf16;
 		Vector<UBiDi *> bidi_iter;
@@ -289,16 +386,16 @@ class TextServerAdvanced : public TextServer {
 
 	// Common data.
 
-	float oversampling = 1.f;
+	double oversampling = 1.0;
 	mutable RID_PtrOwner<FontDataAdvanced> font_owner;
 	mutable RID_PtrOwner<ShapedTextDataAdvanced> shaped_owner;
 
 	void _realign(ShapedTextDataAdvanced *p_sd) const;
-	int _convert_pos(const ShapedTextDataAdvanced *p_sd, int p_pos) const;
-	int _convert_pos_inv(const ShapedTextDataAdvanced *p_sd, int p_pos) const;
-	bool _shape_substr(ShapedTextDataAdvanced *p_new_sd, const ShapedTextDataAdvanced *p_sd, int p_start, int p_length) const;
-	void _shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_start, int32_t p_end, hb_script_t p_script, hb_direction_t p_direction, Vector<RID> p_fonts, int p_span, int p_fb_index);
-	Glyph _shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, RID p_font, int p_font_size);
+	int64_t _convert_pos(const ShapedTextDataAdvanced *p_sd, int64_t p_pos) const;
+	int64_t _convert_pos_inv(const ShapedTextDataAdvanced *p_sd, int64_t p_pos) const;
+	bool _shape_substr(ShapedTextDataAdvanced *p_new_sd, const ShapedTextDataAdvanced *p_sd, int64_t p_start, int64_t p_length) const;
+	void _shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_start, int64_t p_end, hb_script_t p_script, hb_direction_t p_direction, Array p_fonts, int64_t p_span, int64_t p_fb_index);
+	Glyph _shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, const RID &p_font, int64_t p_font_size);
 	_FORCE_INLINE_ void _add_featuers(const Dictionary &p_source, Vector<hb_feature_t> &r_ftrs);
 
 	// HarfBuzz bitmap font interface.
@@ -324,6 +421,25 @@ class TextServerAdvanced : public TextServer {
 	static void _bmp_font_set_funcs(hb_font_t *p_font, TextServerAdvanced::FontDataForSizeAdvanced *p_face, bool p_unref);
 	static hb_font_t *_bmp_font_create(TextServerAdvanced::FontDataForSizeAdvanced *p_face, hb_destroy_func_t p_destroy);
 
+	hb_font_t *_font_get_hb_handle(const RID &p_font, int64_t p_font_size) 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 & 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;
+			}
+		}
+	};
+
 protected:
 	static void _bind_methods(){};
 
@@ -333,10 +449,10 @@ protected:
 public:
 	virtual bool has_feature(Feature p_feature) const override;
 	virtual String get_name() const override;
-	virtual uint32_t get_features() const override;
+	virtual int64_t get_features() const override;
 
-	virtual void free(RID p_rid) override;
-	virtual bool has(RID p_rid) override;
+	virtual void free_rid(const RID &p_rid) override;
+	virtual bool has(const RID &p_rid) override;
 	virtual bool load_support_data(const String &p_filename) override;
 
 	virtual String get_support_data_filename() const override;
@@ -345,220 +461,218 @@ public:
 
 	virtual bool is_locale_right_to_left(const String &p_locale) const override;
 
-	virtual int32_t name_to_tag(const String &p_name) const override;
-	virtual String tag_to_name(int32_t p_tag) const override;
+	virtual int64_t name_to_tag(const String &p_name) const override;
+	virtual String tag_to_name(int64_t p_tag) const override;
 
 	/* Font interface */
 	virtual RID create_font() override;
 
-	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;
-
-	virtual void font_set_style(RID p_font_rid, uint32_t /*FontStyle*/ p_style) override;
-	virtual uint32_t /*FontStyle*/ font_get_style(RID p_font_rid) const override;
+	virtual void font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) override;
+	virtual void font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) override;
 
-	virtual void font_set_style_name(RID p_font_rid, const String &p_name) override;
-	virtual String font_get_style_name(RID p_font_rid) const override;
+	virtual void font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) override;
+	virtual int64_t /*FontStyle*/ font_get_style(const RID &p_font_rid) const override;
 
-	virtual void font_set_name(RID p_font_rid, const String &p_name) override;
-	virtual String font_get_name(RID p_font_rid) const override;
+	virtual void font_set_style_name(const RID &p_font_rid, const String &p_name) override;
+	virtual String font_get_style_name(const RID &p_font_rid) const override;
 
-	virtual void font_set_antialiased(RID p_font_rid, bool p_antialiased) override;
-	virtual bool font_is_antialiased(RID p_font_rid) const override;
+	virtual void font_set_name(const RID &p_font_rid, const String &p_name) override;
+	virtual String font_get_name(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_set_antialiased(const RID &p_font_rid, bool p_antialiased) override;
+	virtual bool font_is_antialiased(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) override;
+	virtual bool font_is_multichannel_signed_distance_field(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) override;
+	virtual int64_t font_get_msdf_pixel_range(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) override;
+	virtual int64_t font_get_msdf_size(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) override;
+	virtual int64_t font_get_fixed_size(const RID &p_font_rid) const override;
 
-	virtual void font_set_hinting(RID p_font_rid, TextServer::Hinting p_hinting) override;
-	virtual TextServer::Hinting font_get_hinting(RID p_font_rid) const override;
+	virtual void font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) override;
+	virtual bool font_is_force_autohinter(const RID &p_font_rid) const override;
 
-	virtual void font_set_subpixel_positioning(RID p_font_rid, SubpixelPositioning p_subpixel) override;
-	virtual SubpixelPositioning font_get_subpixel_positioning(RID p_font_rid) const override;
+	virtual void font_set_subpixel_positioning(const RID &p_font_rid, SubpixelPositioning p_subpixel) override;
+	virtual SubpixelPositioning font_get_subpixel_positioning(const RID &p_font_rid) const override;
 
-	virtual void font_set_embolden(RID p_font_rid, float p_strength) override;
-	virtual float font_get_embolden(RID p_font_rid) const override;
+	virtual void font_set_embolden(const RID &p_font_rid, double p_strength) override;
+	virtual double font_get_embolden(const RID &p_font_rid) const override;
 
-	virtual void font_set_transform(RID p_font_rid, Transform2D p_transform) override;
-	virtual Transform2D font_get_transform(RID p_font_rid) const override;
+	virtual void font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) override;
+	virtual Transform2D font_get_transform(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) override;
+	virtual Dictionary font_get_variation_coordinates(const RID &p_font_rid) const override;
 
-	virtual void font_set_oversampling(RID p_font_rid, float p_oversampling) override;
-	virtual float font_get_oversampling(RID p_font_rid) const override;
+	virtual void font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) override;
+	virtual TextServer::Hinting font_get_hinting(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_set_oversampling(const RID &p_font_rid, double p_oversampling) override;
+	virtual double font_get_oversampling(const RID &p_font_rid) const override;
 
-	hb_font_t *_font_get_hb_handle(RID p_font, int p_font_size) const;
+	virtual Array font_get_size_cache_list(const RID &p_font_rid) const override;
+	virtual void font_clear_size_cache(const RID &p_font_rid) override;
+	virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) override;
 
-	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;
+	virtual void font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) override;
+	virtual double font_get_ascent(const RID &p_font_rid, int64_t p_size) const override;
 
-	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;
+	virtual void font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) override;
+	virtual double font_get_descent(const RID &p_font_rid, int64_t p_size) const override;
 
-	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;
+	virtual void font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) override;
+	virtual double font_get_underline_position(const RID &p_font_rid, int64_t p_size) const override;
 
-	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;
+	virtual void font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) override;
+	virtual double font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const override;
 
-	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;
+	virtual void font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) override;
+	virtual double font_get_scale(const RID &p_font_rid, int64_t p_size) const override;
 
-	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;
+	virtual void font_set_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing, int64_t p_value) override;
+	virtual int64_t font_get_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing) const override;
 
-	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;
+	virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const override;
+	virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) override;
+	virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) override;
 
-	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;
+	virtual void font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) override;
+	virtual Ref<Image> font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override;
 
-	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;
+	virtual void font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) override;
+	virtual PackedInt32Array font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override;
 
-	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;
+	virtual Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const override;
+	virtual void font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) override;
+	virtual void font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) override;
 
-	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;
+	virtual Vector2 font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) override;
 
-	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;
+	virtual Vector2 font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) override;
 
-	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;
+	virtual Vector2 font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) override;
 
-	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;
+	virtual Rect2 font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) override;
 
-	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;
+	virtual int64_t font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) override;
 
-	virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const override;
+	virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override;
 
-	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;
+	virtual Array font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const override;
+	virtual void font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) override;
+	virtual void font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) override;
 
-	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;
+	virtual void font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) override;
+	virtual Vector2 font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const override;
 
-	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;
+	virtual int64_t font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector = 0) const override;
 
-	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;
+	virtual bool font_has_char(const RID &p_font_rid, int64_t p_char) const override;
+	virtual String font_get_supported_chars(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_render_range(const RID &p_font, const Vector2i &p_size, int64_t p_start, int64_t p_end) override;
+	virtual void font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) override;
 
-	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;
+	virtual void font_draw_glyph(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
+	virtual void font_draw_glyph_outline(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
 
-	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;
+	virtual bool font_is_language_supported(const RID &p_font_rid, const String &p_language) const override;
+	virtual void font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) override;
+	virtual bool font_get_language_support_override(const RID &p_font_rid, const String &p_language) override;
+	virtual void font_remove_language_support_override(const RID &p_font_rid, const String &p_language) override;
+	virtual PackedStringArray font_get_language_support_overrides(const RID &p_font_rid) override;
 
-	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;
+	virtual bool font_is_script_supported(const RID &p_font_rid, const String &p_script) const override;
+	virtual void font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) override;
+	virtual bool font_get_script_support_override(const RID &p_font_rid, const String &p_script) override;
+	virtual void font_remove_script_support_override(const RID &p_font_rid, const String &p_script) override;
+	virtual PackedStringArray font_get_script_support_overrides(const RID &p_font_rid) override;
 
-	virtual void font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) override;
-	virtual Dictionary font_get_opentype_feature_overrides(RID p_font_rid) const override;
+	virtual void font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) override;
+	virtual Dictionary font_get_opentype_feature_overrides(const RID &p_font_rid) const override;
 
-	virtual Dictionary font_supported_feature_list(RID p_font_rid) const override;
-	virtual Dictionary font_supported_variation_list(RID p_font_rid) const override;
+	virtual Dictionary font_supported_feature_list(const RID &p_font_rid) const override;
+	virtual Dictionary font_supported_variation_list(const RID &p_font_rid) const override;
 
-	virtual float font_get_global_oversampling() const override;
-	virtual void font_set_global_oversampling(float p_oversampling) override;
+	virtual double font_get_global_oversampling() const override;
+	virtual void font_set_global_oversampling(double p_oversampling) override;
 
 	/* Shaped text buffer interface */
 
 	virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
 
-	virtual void shaped_text_clear(RID p_shaped) override;
+	virtual void shaped_text_clear(const RID &p_shaped) override;
 
-	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;
-	virtual Direction shaped_text_get_inferred_direction(RID p_shaped) const override;
+	virtual void shaped_text_set_direction(const RID &p_shaped, Direction p_direction = DIRECTION_AUTO) override;
+	virtual Direction shaped_text_get_direction(const RID &p_shaped) const override;
+	virtual Direction shaped_text_get_inferred_direction(const RID &p_shaped) const override;
 
-	virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override;
+	virtual void shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) override;
 
-	virtual void shaped_text_set_custom_punctuation(RID p_shaped, const String &p_punct) override;
-	virtual String shaped_text_get_custom_punctuation(RID p_shaped) const override;
+	virtual void shaped_text_set_custom_punctuation(const RID &p_shaped, const String &p_punct) override;
+	virtual String shaped_text_get_custom_punctuation(const RID &p_shaped) const override;
 
-	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;
+	virtual void shaped_text_set_orientation(const RID &p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
+	virtual Orientation shaped_text_get_orientation(const RID &p_shaped) const override;
 
-	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;
+	virtual void shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) override;
+	virtual bool shaped_text_get_preserve_invalid(const RID &p_shaped) const override;
 
-	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;
+	virtual void shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) override;
+	virtual bool shaped_text_get_preserve_control(const RID &p_shaped) const override;
 
-	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 = "", const Variant &p_meta = Variant()) override;
-	virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) override;
-	virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
+	virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override;
+	virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) override;
+	virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
 
-	virtual int shaped_get_span_count(RID p_shaped) const override;
-	virtual Variant shaped_get_span_meta(RID p_shaped, int p_index) const override;
-	virtual void shaped_set_span_update_font(RID p_shaped, int p_index, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary()) override;
+	virtual int64_t shaped_get_span_count(const RID &p_shaped) const override;
+	virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const override;
+	virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override;
 
-	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;
+	virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const override;
+	virtual RID shaped_text_get_parent(const RID &p_shaped) const override;
 
-	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;
+	virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, int64_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
+	virtual double shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) override;
 
-	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;
+	virtual bool shaped_text_shape(const RID &p_shaped) override;
+	virtual bool shaped_text_update_breaks(const RID &p_shaped) override;
+	virtual bool shaped_text_update_justification_ops(const RID &p_shaped) override;
 
-	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;
+	virtual int64_t shaped_text_get_trim_pos(const RID &p_shaped) const override;
+	virtual int64_t shaped_text_get_ellipsis_pos(const RID &p_shaped) const override;
+	virtual const Glyph *shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const override;
+	virtual int64_t shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const override;
 
-	virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) override;
+	virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, int64_t p_trim_flags) override;
 
-	virtual bool shaped_text_is_ready(RID p_shaped) const override;
+	virtual bool shaped_text_is_ready(const RID &p_shaped) const override;
 
-	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;
+	virtual const Glyph *shaped_text_get_glyphs(const RID &p_shaped) const override;
+	virtual const Glyph *shaped_text_sort_logical(const RID &p_shaped) override;
+	virtual int64_t shaped_text_get_glyph_count(const RID &p_shaped) const override;
 
-	virtual Vector2i shaped_text_get_range(RID p_shaped) const override;
+	virtual Vector2i shaped_text_get_range(const RID &p_shaped) const override;
 
-	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;
+	virtual Array shaped_text_get_objects(const RID &p_shaped) const override;
+	virtual Rect2 shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const override;
 
-	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;
+	virtual Size2 shaped_text_get_size(const RID &p_shaped) const override;
+	virtual double shaped_text_get_ascent(const RID &p_shaped) const override;
+	virtual double shaped_text_get_descent(const RID &p_shaped) const override;
+	virtual double shaped_text_get_width(const RID &p_shaped) const override;
+	virtual double shaped_text_get_underline_position(const RID &p_shaped) const override;
+	virtual double shaped_text_get_underline_thickness(const RID &p_shaped) const override;
 
 	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;

+ 2 - 0
modules/text_server_fb/.gitignore

@@ -0,0 +1,2 @@
+# Godot-cpp headers
+gdextension_build/godot-cpp

+ 1 - 1
modules/text_server_fb/doc_classes/TextServerFallback.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<class name="TextServerFallback" inherits="TextServer" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
+<class name="TextServerFallback" inherits="TextServerExtension" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
 	<brief_description>
 		Fallback implementation of the Text Server, without BiDi and complex text layout support.
 	</brief_description>

+ 205 - 0
modules/text_server_fb/gdextension_build/SConstruct

@@ -0,0 +1,205 @@
+#!/usr/bin/env python
+import atexit
+import os
+import sys
+import methods
+import time
+
+# For the reference:
+# - CCFLAGS are compilation flags shared between C and C++
+# - CFLAGS are for C-specific compilation flags
+# - CXXFLAGS are for C++-specific compilation flags
+# - CPPFLAGS are for pre-processor flags
+# - CPPDEFINES are for pre-processor defines
+# - LINKFLAGS are for linking flags
+
+time_at_start = time.time()
+
+env = SConscript("./godot-cpp/SConstruct")
+env.__class__.disable_warnings = methods.disable_warnings
+
+opts = Variables([], ARGUMENTS)
+opts.Add(BoolVariable("freetype_enabled", "Use FreeType library", True))
+opts.Add(BoolVariable("msdfgen_enabled", "Use MSDFgen library (require FreeType)", True))
+opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))
+
+opts.Update(env)
+
+if not env["verbose"]:
+    methods.no_verbose(sys, env)
+
+# MSDFGEN
+if env["msdfgen_enabled"] and env["freetype_enabled"]:
+    env_msdfgen = env.Clone()
+    env_msdfgen.disable_warnings()
+
+    thirdparty_msdfgen_dir = "../../../thirdparty/msdfgen/"
+    thirdparty_msdfgen_sources = [
+        "core/Contour.cpp",
+        "core/EdgeHolder.cpp",
+        "core/MSDFErrorCorrection.cpp",
+        "core/Projection.cpp",
+        "core/Scanline.cpp",
+        "core/Shape.cpp",
+        "core/SignedDistance.cpp",
+        "core/Vector2.cpp",
+        "core/contour-combiners.cpp",
+        "core/edge-coloring.cpp",
+        "core/edge-segments.cpp",
+        "core/edge-selectors.cpp",
+        "core/equation-solver.cpp",
+        "core/msdf-error-correction.cpp",
+        "core/msdfgen.cpp",
+        "core/rasterization.cpp",
+        "core/render-sdf.cpp",
+        "core/sdf-error-estimation.cpp",
+        "core/shape-description.cpp",
+    ]
+    thirdparty_msdfgen_sources = [thirdparty_msdfgen_dir + file for file in thirdparty_msdfgen_sources]
+
+    env_msdfgen.Append(CPPPATH=["../../../thirdparty/freetype/include", "../../../thirdparty/msdfgen"])
+    env.Append(CPPPATH=["../../../thirdparty/msdfgen"])
+    env.Append(CPPDEFINES=["MODULE_MSDFGEN_ENABLED"])
+
+    lib = env_msdfgen.Library(
+        f'msdfgen_builtin.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["LIBSUFFIX"]}',
+        thirdparty_msdfgen_sources,
+    )
+    env.Append(LIBS=[lib])
+
+# FreeType
+if env["freetype_enabled"]:
+    env_freetype = env.Clone()
+    env_freetype.disable_warnings()
+
+    thirdparty_freetype_dir = "../../../thirdparty/freetype/"
+    thirdparty_freetype_sources = [
+        "src/autofit/autofit.c",
+        "src/base/ftbase.c",
+        "src/base/ftbbox.c",
+        "src/base/ftbdf.c",
+        "src/base/ftbitmap.c",
+        "src/base/ftcid.c",
+        "src/base/ftdebug.c",
+        "src/base/ftfstype.c",
+        "src/base/ftgasp.c",
+        "src/base/ftglyph.c",
+        "src/base/ftgxval.c",
+        "src/base/ftinit.c",
+        "src/base/ftmm.c",
+        "src/base/ftotval.c",
+        "src/base/ftpatent.c",
+        "src/base/ftpfr.c",
+        "src/base/ftstroke.c",
+        "src/base/ftsynth.c",
+        "src/base/ftsystem.c",
+        "src/base/fttype1.c",
+        "src/base/ftwinfnt.c",
+        "src/bdf/bdf.c",
+        "src/bzip2/ftbzip2.c",
+        "src/cache/ftcache.c",
+        "src/cff/cff.c",
+        "src/cid/type1cid.c",
+        "src/gxvalid/gxvalid.c",
+        "src/gzip/ftgzip.c",
+        "src/lzw/ftlzw.c",
+        "src/otvalid/otvalid.c",
+        "src/pcf/pcf.c",
+        "src/pfr/pfr.c",
+        "src/psaux/psaux.c",
+        "src/pshinter/pshinter.c",
+        "src/psnames/psnames.c",
+        "src/raster/raster.c",
+        "src/sdf/sdf.c",
+        "src/smooth/smooth.c",
+        "src/truetype/truetype.c",
+        "src/type1/type1.c",
+        "src/type42/type42.c",
+        "src/winfonts/winfnt.c",
+        "src/sfnt/sfnt.c",
+    ]
+    thirdparty_freetype_sources = [thirdparty_freetype_dir + file for file in thirdparty_freetype_sources]
+
+    thirdparty_png_dir = "../../../thirdparty/libpng/"
+    thirdparty_png_sources = [
+        "png.c",
+        "pngerror.c",
+        "pngget.c",
+        "pngmem.c",
+        "pngpread.c",
+        "pngread.c",
+        "pngrio.c",
+        "pngrtran.c",
+        "pngrutil.c",
+        "pngset.c",
+        "pngtrans.c",
+        "pngwio.c",
+        "pngwrite.c",
+        "pngwtran.c",
+        "pngwutil.c",
+    ]
+    thirdparty_freetype_sources += [thirdparty_png_dir + file for file in thirdparty_png_sources]
+
+    thirdparty_zlib_dir = "../../../thirdparty/zlib/"
+    thirdparty_zlib_sources = [
+        "adler32.c",
+        "compress.c",
+        "crc32.c",
+        "deflate.c",
+        "infback.c",
+        "inffast.c",
+        "inflate.c",
+        "inftrees.c",
+        "trees.c",
+        "uncompr.c",
+        "zutil.c",
+    ]
+    thirdparty_freetype_sources += [thirdparty_zlib_dir + file for file in thirdparty_zlib_sources]
+
+    env_freetype.Append(CPPPATH=[thirdparty_freetype_dir + "/include", thirdparty_zlib_dir, thirdparty_png_dir])
+    env.Append(CPPPATH=[thirdparty_freetype_dir + "/include"])
+
+    env_freetype.Append(CPPDEFINES=["FT2_BUILD_LIBRARY", "FT_CONFIG_OPTION_USE_PNG", ("PNG_ARM_NEON_OPT", 0)])
+    if env["target"] == "debug":
+        env_freetype.Append(CPPDEFINES=["ZLIB_DEBUG"])
+
+    env.Append(CPPDEFINES=["MODULE_FREETYPE_ENABLED"])
+
+    lib = env_freetype.Library(
+        f'freetype_builtin.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["LIBSUFFIX"]}',
+        thirdparty_freetype_sources,
+    )
+    env.Append(LIBS=[lib])
+
+
+env.Append(CPPDEFINES=["GDEXTENSION"])
+env.Append(CPPPATH=["../"])
+sources = Glob("../*.cpp")
+
+if env["platform"] == "osx":
+    methods.write_osx_plist(
+        f'./bin/libtextserver_fallback.osx.{env["target"]}.framework',
+        f'libtextserver_fallback.osx.{env["target"]}',
+        "org.godotengine.textserver_fallback",
+        "Fallback Text Server",
+    )
+    library = env.SharedLibrary(
+        f'./bin/libtextserver_fallback.osx.{env["target"]}.framework/libtextserver_fallback.osx.{env["target"]}',
+        source=sources,
+    )
+else:
+    library = env.SharedLibrary(
+        f'./bin/libtextserver_fallback.{env["platform"]}.{env["target"]}.{env["arch_suffix"]}{env["SHLIBSUFFIX"]}',
+        source=sources,
+    )
+
+Default(library)
+
+
+def print_elapsed_time():
+    elapsed_time_sec = round(time.time() - time_at_start, 3)
+    time_ms = round((elapsed_time_sec % 1) * 1000)
+    print("[Time elapsed: {}.{:03}]".format(time.strftime("%H:%M:%S", time.gmtime(elapsed_time_sec)), time_ms))
+
+
+atexit.register(print_elapsed_time)

+ 130 - 0
modules/text_server_fb/gdextension_build/methods.py

@@ -0,0 +1,130 @@
+import os
+import sys
+
+
+def no_verbose(sys, env):
+    colors = {}
+
+    # Colors are disabled in non-TTY environments such as pipes. This means
+    # that if output is redirected to a file, it will not contain color codes
+    if sys.stdout.isatty():
+        colors["blue"] = "\033[0;94m"
+        colors["bold_blue"] = "\033[1;94m"
+        colors["reset"] = "\033[0m"
+    else:
+        colors["blue"] = ""
+        colors["bold_blue"] = ""
+        colors["reset"] = ""
+
+    # There is a space before "..." to ensure that source file names can be
+    # Ctrl + clicked in the VS Code terminal.
+    compile_source_message = "{}Compiling {}$SOURCE{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+    java_compile_source_message = "{}Compiling {}$SOURCE{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+    compile_shared_source_message = "{}Compiling shared {}$SOURCE{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+    link_program_message = "{}Linking Program {}$TARGET{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+    link_library_message = "{}Linking Static Library {}$TARGET{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+    ranlib_library_message = "{}Ranlib Library {}$TARGET{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+    link_shared_library_message = "{}Linking Shared Library {}$TARGET{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+    java_library_message = "{}Creating Java Archive {}$TARGET{} ...{}".format(
+        colors["blue"], colors["bold_blue"], colors["blue"], colors["reset"]
+    )
+
+    env.Append(CXXCOMSTR=[compile_source_message])
+    env.Append(CCCOMSTR=[compile_source_message])
+    env.Append(SHCCCOMSTR=[compile_shared_source_message])
+    env.Append(SHCXXCOMSTR=[compile_shared_source_message])
+    env.Append(ARCOMSTR=[link_library_message])
+    env.Append(RANLIBCOMSTR=[ranlib_library_message])
+    env.Append(SHLINKCOMSTR=[link_shared_library_message])
+    env.Append(LINKCOMSTR=[link_program_message])
+    env.Append(JARCOMSTR=[java_library_message])
+    env.Append(JAVACCOMSTR=[java_compile_source_message])
+
+
+def disable_warnings(self):
+    # 'self' is the environment
+    if self["platform"] == "windows" and not self["use_mingw"]:
+        # We have to remove existing warning level defines before appending /w,
+        # otherwise we get: "warning D9025 : overriding '/W3' with '/w'"
+        warn_flags = ["/Wall", "/W4", "/W3", "/W2", "/W1", "/WX"]
+        self.Append(CCFLAGS=["/w"])
+        self.Append(CFLAGS=["/w"])
+        self.Append(CXXFLAGS=["/w"])
+        self["CCFLAGS"] = [x for x in self["CCFLAGS"] if not x in warn_flags]
+        self["CFLAGS"] = [x for x in self["CFLAGS"] if not x in warn_flags]
+        self["CXXFLAGS"] = [x for x in self["CXXFLAGS"] if not x in warn_flags]
+    else:
+        self.Append(CCFLAGS=["-w"])
+        self.Append(CFLAGS=["-w"])
+        self.Append(CXXFLAGS=["-w"])
+
+
+def make_icu_data(target, source, env):
+    dst = target[0].srcnode().abspath
+    g = open(dst, "w", encoding="utf-8")
+
+    g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+    g.write("/* (C) 2016 and later: Unicode, Inc. and others. */\n")
+    g.write("/* License & terms of use: https://www.unicode.org/copyright.html */\n")
+    g.write("#ifndef _ICU_DATA_H\n")
+    g.write("#define _ICU_DATA_H\n")
+    g.write('#include "unicode/utypes.h"\n')
+    g.write('#include "unicode/udata.h"\n')
+    g.write('#include "unicode/uversion.h"\n')
+
+    f = open(source[0].srcnode().abspath, "rb")
+    buf = f.read()
+
+    g.write('extern "C" U_EXPORT const size_t U_ICUDATA_SIZE = ' + str(len(buf)) + ";\n")
+    g.write('extern "C" U_EXPORT const unsigned char U_ICUDATA_ENTRY_POINT[] = {\n')
+    for i in range(len(buf)):
+        g.write("\t" + str(buf[i]) + ",\n")
+
+    g.write("};\n")
+    g.write("#endif")
+
+
+def write_osx_plist(target, binary_name, identifier, name):
+    os.makedirs(f"{target}/Resourece/", exist_ok=True)
+    f = open(f"{target}/Resourece/Info.plist", "w")
+
+    f.write(f'<?xml version="1.0" encoding="UTF-8"?>\n')
+    f.write(f'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n')
+    f.write(f'<plist version="1.0">\n')
+    f.write(f"<dict>\n")
+    f.write(f"\t<key>CFBundleExecutable</key>\n")
+    f.write(f"\t<string>{binary_name}</string>\n")
+    f.write(f"\t<key>CFBundleIdentifier</key>\n")
+    f.write(f"\t<string>{identifier}</string>\n")
+    f.write(f"\t<key>CFBundleInfoDictionaryVersion</key>\n")
+    f.write(f"\t<string>6.0</string>\n")
+    f.write(f"\t<key>CFBundleName</key>\n")
+    f.write(f"\t<string>{name}</string>\n")
+    f.write(f"\t<key>CFBundlePackageType</key>\n")
+    f.write(f"\t<string>FMWK</string>\n")
+    f.write(f"\t<key>CFBundleShortVersionString</key>\n")
+    f.write(f"\t<string>1.0.0</string>\n")
+    f.write(f"\t<key>CFBundleSupportedPlatforms</key>\n")
+    f.write(f"\t<array>\n")
+    f.write(f"\t\t<string>MacOSX</string>\n")
+    f.write(f"\t</array>\n")
+    f.write(f"\t<key>CFBundleVersion</key>\n")
+    f.write(f"\t<string>1.0.0</string>\n")
+    f.write(f"\t<key>LSMinimumSystemVersion</key>\n")
+    f.write(f"\t<string>10.14</string>\n")
+    f.write(f"</dict>\n")
+    f.write(f"</plist>\n")

+ 12 - 0
modules/text_server_fb/gdextension_build/text_server_fb.gdextension

@@ -0,0 +1,12 @@
+[configuration]
+
+entry_symbol = "textserver_fallback_init"
+
+[libraries]
+
+linux.64.debug = "bin/libtextserver_fallback.linux.debug.64.so"
+linux.64.release = "bin/libtextserver_fallback.linux.release.64.so"
+windows.64.debug = "bin/libtextserver_fallback.windows.debug.64.dll"
+windows.64.release = "bin/libtextserver_fallback.windows.release.64.dll"
+macos.debug = "bin/libtextserver_fallback.osx.debug.framework"
+macos.release = "bin/libtextserver_fallback.osx.release.framework"

+ 26 - 2
modules/text_server_fb/register_types.cpp

@@ -34,10 +34,11 @@
 
 void preregister_text_server_fb_types() {
 	GDREGISTER_CLASS(TextServerFallback);
-	if (TextServerManager::get_singleton()) {
+	TextServerManager *tsman = TextServerManager::get_singleton();
+	if (tsman) {
 		Ref<TextServerFallback> ts;
 		ts.instantiate();
-		TextServerManager::get_singleton()->add_interface(ts);
+		tsman->add_interface(ts);
 	}
 }
 
@@ -46,3 +47,26 @@ void register_text_server_fb_types() {
 
 void unregister_text_server_fb_types() {
 }
+
+#ifdef GDEXTENSION
+
+#include <godot_cpp/core/class_db.hpp>
+#include <godot_cpp/core/defs.hpp>
+#include <godot_cpp/core/memory.hpp>
+
+using namespace godot;
+
+extern "C" {
+
+GDNativeBool GDN_EXPORT textserver_fallback_init(const GDNativeInterface *p_interface, const GDNativeExtensionClassLibraryPtr p_library, GDNativeInitialization *r_initialization) {
+	GDExtensionBinding::InitObject init_obj(p_interface, p_library, r_initialization);
+
+	init_obj.register_server_initializer(&preregister_text_server_fb_types);
+	init_obj.register_server_terminator(&unregister_text_server_fb_types);
+
+	return init_obj.init();
+}
+
+} // ! extern "C"
+
+#endif // ! GDEXTENSION

Datei-Diff unterdrückt, da er zu groß ist
+ 188 - 128
modules/text_server_fb/text_server_fb.cpp


+ 262 - 167
modules/text_server_fb/text_server_fb.h

@@ -36,7 +36,49 @@
 /* BiDi, shaping and advanced font features support.                     */
 /*************************************************************************/
 
-#include "servers/text_server.h"
+#ifdef GDEXTENSION
+// Headers for building as GDExtension plug-in.
+
+#include <godot_cpp/godot.hpp>
+
+#include <godot_cpp/core/class_db.hpp>
+#include <godot_cpp/core/mutex_lock.hpp>
+
+#include <godot_cpp/variant/array.hpp>
+#include <godot_cpp/variant/dictionary.hpp>
+#include <godot_cpp/variant/packed_int32_array.hpp>
+#include <godot_cpp/variant/packed_string_array.hpp>
+#include <godot_cpp/variant/packed_vector2_array.hpp>
+#include <godot_cpp/variant/rect2.hpp>
+#include <godot_cpp/variant/rid.hpp>
+#include <godot_cpp/variant/string.hpp>
+#include <godot_cpp/variant/vector2.hpp>
+#include <godot_cpp/variant/vector2i.hpp>
+
+#include <godot_cpp/classes/text_server.hpp>
+#include <godot_cpp/classes/text_server_extension.hpp>
+#include <godot_cpp/classes/text_server_manager.hpp>
+
+#include <godot_cpp/classes/caret_info.hpp>
+#include <godot_cpp/classes/global_constants_binds.hpp>
+#include <godot_cpp/classes/glyph.hpp>
+#include <godot_cpp/classes/image.hpp>
+#include <godot_cpp/classes/image_texture.hpp>
+#include <godot_cpp/classes/ref.hpp>
+
+#include <godot_cpp/templates/hash_map.hpp>
+#include <godot_cpp/templates/map.hpp>
+#include <godot_cpp/templates/rid_owner.hpp>
+#include <godot_cpp/templates/set.hpp>
+#include <godot_cpp/templates/thread_work_pool.hpp>
+#include <godot_cpp/templates/vector.hpp>
+
+using namespace godot;
+
+#else
+// Headers for building as built-in module.
+
+#include "servers/text/text_server_extension.h"
 
 #include "core/templates/rid_owner.h"
 #include "core/templates/thread_work_pool.h"
@@ -44,6 +86,10 @@
 
 #include "modules/modules_enabled.gen.h" // For freetype, msdfgen.
 
+#endif
+
+// Thirdparty headers.
+
 #ifdef MODULE_FREETYPE_ENABLED
 #include <ft2build.h>
 #include FT_FREETYPE_H
@@ -54,26 +100,25 @@
 #include FT_BBOX_H
 #endif
 
-#define OT_TAG(c1, c2, c3, c4) ((int32_t)((((uint32_t)(c1)&0xFF) << 24) | (((uint32_t)(c2)&0xFF) << 16) | (((uint32_t)(c3)&0xFF) << 8) | ((uint32_t)(c4)&0xFF)))
+/*************************************************************************/
 
-class TextServerFallback : public TextServer {
-	GDCLASS(TextServerFallback, TextServer);
+class TextServerFallback : public TextServerExtension {
+	GDCLASS(TextServerFallback, TextServerExtension);
 	_THREAD_SAFE_CLASS_
 
-	static String interface_name;
-	static uint32_t interface_features;
-
 	Map<StringName, int32_t> feature_sets;
+	Map<int32_t, StringName> feature_sets_inv;
 
 	void _insert_feature_sets();
+	_FORCE_INLINE_ void _insert_feature(const StringName &p_name, int32_t p_tag);
 
 	// Font cache data.
 
 #ifdef MODULE_FREETYPE_ENABLED
-	mutable FT_Library library = nullptr;
+	mutable FT_Library ft_library = nullptr;
 #endif
 
-	const int rect_range = 2;
+	const int rect_range = 1;
 
 	struct FontTexture {
 		Image::Format format;
@@ -99,12 +144,12 @@ class TextServerFallback : public TextServer {
 	};
 
 	struct FontDataForSizeFallback {
-		float ascent = 0.f;
-		float descent = 0.f;
-		float underline_position = 0.f;
-		float underline_thickness = 0.f;
-		float scale = 1.f;
-		float oversampling = 1.f;
+		double ascent = 0.0;
+		double descent = 0.0;
+		double underline_position = 0.0;
+		double underline_thickness = 0.0;
+		double scale = 1.0;
+		double oversampling = 1.0;
 
 		int spacing_glyph = 0;
 		int spacing_space = 0;
@@ -141,8 +186,8 @@ class TextServerFallback : public TextServer {
 		TextServer::Hinting hinting = TextServer::HINTING_LIGHT;
 		TextServer::SubpixelPositioning subpixel_positioning = TextServer::SUBPIXEL_POSITIONING_AUTO;
 		Dictionary variation_coordinates;
-		float oversampling = 0.f;
-		float embolden = 0.f;
+		double oversampling = 0.0;
+		double embolden = 0.0;
 		Transform2D transform;
 
 		uint32_t style_flags = 0;
@@ -167,8 +212,8 @@ class TextServerFallback : public TextServer {
 
 		~FontDataFallback() {
 			work_pool.finish();
-			for (const Map<Vector2i, FontDataForSizeFallback *>::Element *E = cache.front(); E; E = E->next()) {
-				memdelete(E->get());
+			for (const KeyValue<Vector2i, FontDataForSizeFallback *> &E : cache) {
+				memdelete(E.value);
 			}
 			cache.clear();
 		}
@@ -207,13 +252,31 @@ class TextServerFallback : public TextServer {
 	}
 
 	// Shaped text cache data.
+	struct TrimData {
+		int trim_pos = -1;
+		int ellipsis_pos = -1;
+		Vector<Glyph> ellipsis_glyph_buf;
+	};
+
+	struct ShapedTextDataFallback {
+		Mutex mutex;
+
+		/* Source data */
+		RID parent; // Substring parent ShapedTextData.
+
+		int start = 0; // Substring start offset in the parent string.
+		int end = 0; // Substring end offset in the parent string.
+
+		String text;
+		String custom_punct;
+		TextServer::Direction direction = DIRECTION_LTR; // Desired text direction.
+		TextServer::Orientation orientation = ORIENTATION_HORIZONTAL;
 
-	struct ShapedTextDataFallback : public ShapedTextData {
 		struct Span {
 			int start = -1;
 			int end = -1;
 
-			Vector<RID> fonts;
+			Array fonts;
 			int font_size = 0;
 
 			Variant embedded_key;
@@ -223,11 +286,43 @@ class TextServerFallback : public TextServer {
 			Variant meta;
 		};
 		Vector<Span> spans;
+
+		struct EmbeddedObject {
+			int pos = 0;
+			InlineAlignment inline_align = INLINE_ALIGNMENT_CENTER;
+			Rect2 rect;
+		};
+		Map<Variant, EmbeddedObject> objects;
+
+		/* Shaped data */
+		TextServer::Direction para_direction = DIRECTION_LTR; // Detected text direction.
+		bool valid = false; // String is shaped.
+		bool line_breaks_valid = false; // Line and word break flags are populated (and virtual zero width spaces inserted).
+		bool justification_ops_valid = false; // Virtual elongation glyphs are added to the string.
+		bool sort_valid = false;
+		bool text_trimmed = false;
+
+		bool preserve_invalid = true; // Draw hex code box instead of missing characters.
+		bool preserve_control = false; // Draw control characters.
+
+		double ascent = 0.0; // Ascent for horizontal layout, 1/2 of width for vertical.
+		double descent = 0.0; // Descent for horizontal layout, 1/2 of width for vertical.
+		double width = 0.0; // Width for horizontal layout, height for vertical.
+		double width_trimmed = 0.0;
+
+		double upos = 0.0;
+		double uthk = 0.0;
+
+		TrimData overrun_trim_data;
+		bool fit_width_minimum_reached = false;
+
+		Vector<Glyph> glyphs;
+		Vector<Glyph> glyphs_logical;
 	};
 
 	// Common data.
 
-	float oversampling = 1.f;
+	double oversampling = 1.0;
 	mutable RID_PtrOwner<FontDataFallback> font_owner;
 	mutable RID_PtrOwner<ShapedTextDataFallback> shaped_owner;
 
@@ -242,10 +337,10 @@ protected:
 public:
 	virtual bool has_feature(Feature p_feature) const override;
 	virtual String get_name() const override;
-	virtual uint32_t get_features() const override;
+	virtual int64_t get_features() const override;
 
-	virtual void free(RID p_rid) override;
-	virtual bool has(RID p_rid) override;
+	virtual void free_rid(const RID &p_rid) override;
+	virtual bool has(const RID &p_rid) override;
 	virtual bool load_support_data(const String &p_filename) override;
 
 	virtual String get_support_data_filename() const override { return ""; };
@@ -254,218 +349,218 @@ public:
 
 	virtual bool is_locale_right_to_left(const String &p_locale) const override;
 
-	virtual int32_t name_to_tag(const String &p_name) const override;
-	virtual String tag_to_name(int32_t p_tag) const override;
+	virtual int64_t name_to_tag(const String &p_name) const override;
+	virtual String tag_to_name(int64_t p_tag) const override;
 
 	/* Font interface */
 	virtual RID create_font() override;
 
-	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;
+	virtual void font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) override;
+	virtual void font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) override;
 
-	virtual void font_set_style(RID p_font_rid, uint32_t /*FontStyle*/ p_style) override;
-	virtual uint32_t /*FontStyle*/ font_get_style(RID p_font_rid) const override;
+	virtual void font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) override;
+	virtual int64_t /*FontStyle*/ font_get_style(const RID &p_font_rid) const override;
 
-	virtual void font_set_style_name(RID p_font_rid, const String &p_name) override;
-	virtual String font_get_style_name(RID p_font_rid) const override;
+	virtual void font_set_style_name(const RID &p_font_rid, const String &p_name) override;
+	virtual String font_get_style_name(const RID &p_font_rid) const override;
 
-	virtual void font_set_name(RID p_font_rid, const String &p_name) override;
-	virtual String font_get_name(RID p_font_rid) const override;
+	virtual void font_set_name(const RID &p_font_rid, const String &p_name) override;
+	virtual String font_get_name(const RID &p_font_rid) const override;
 
-	virtual void font_set_antialiased(RID p_font_rid, bool p_antialiased) override;
-	virtual bool font_is_antialiased(RID p_font_rid) const override;
+	virtual void font_set_antialiased(const RID &p_font_rid, bool p_antialiased) override;
+	virtual bool font_is_antialiased(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) override;
+	virtual bool font_is_multichannel_signed_distance_field(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) override;
+	virtual int64_t font_get_msdf_pixel_range(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) override;
+	virtual int64_t font_get_msdf_size(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) override;
+	virtual int64_t font_get_fixed_size(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) override;
+	virtual bool font_is_force_autohinter(const RID &p_font_rid) const override;
 
-	virtual void font_set_hinting(RID p_font_rid, TextServer::Hinting p_hinting) override;
-	virtual TextServer::Hinting font_get_hinting(RID p_font_rid) const override;
+	virtual void font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) override;
+	virtual TextServer::Hinting font_get_hinting(const RID &p_font_rid) const override;
 
-	virtual void font_set_subpixel_positioning(RID p_font_rid, SubpixelPositioning p_subpixel) override;
-	virtual SubpixelPositioning font_get_subpixel_positioning(RID p_font_rid) const override;
+	virtual void font_set_subpixel_positioning(const RID &p_font_rid, SubpixelPositioning p_subpixel) override;
+	virtual SubpixelPositioning font_get_subpixel_positioning(const RID &p_font_rid) const override;
 
-	virtual void font_set_embolden(RID p_font_rid, float p_strength) override;
-	virtual float font_get_embolden(RID p_font_rid) const override;
+	virtual void font_set_embolden(const RID &p_font_rid, double p_strength) override;
+	virtual double font_get_embolden(const RID &p_font_rid) const override;
 
-	virtual void font_set_transform(RID p_font_rid, Transform2D p_transform) override;
-	virtual Transform2D font_get_transform(RID p_font_rid) const override;
+	virtual void font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) override;
+	virtual Transform2D font_get_transform(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) override;
+	virtual Dictionary font_get_variation_coordinates(const RID &p_font_rid) const override;
 
-	virtual void font_set_oversampling(RID p_font_rid, float p_oversampling) override;
-	virtual float font_get_oversampling(RID p_font_rid) const override;
+	virtual void font_set_oversampling(const RID &p_font_rid, double p_oversampling) override;
+	virtual double font_get_oversampling(const RID &p_font_rid) const override;
 
-	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;
+	virtual Array font_get_size_cache_list(const RID &p_font_rid) const override;
+	virtual void font_clear_size_cache(const RID &p_font_rid) override;
+	virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) override;
 
-	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;
+	virtual void font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) override;
+	virtual double font_get_ascent(const RID &p_font_rid, int64_t p_size) const override;
 
-	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;
+	virtual void font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) override;
+	virtual double font_get_descent(const RID &p_font_rid, int64_t p_size) const override;
 
-	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;
+	virtual void font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) override;
+	virtual double font_get_underline_position(const RID &p_font_rid, int64_t p_size) const override;
 
-	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;
+	virtual void font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) override;
+	virtual double font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const override;
 
-	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;
+	virtual void font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) override;
+	virtual double font_get_scale(const RID &p_font_rid, int64_t p_size) const override;
 
-	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;
+	virtual void font_set_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing, int64_t p_value) override;
+	virtual int64_t font_get_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing) const override;
 
-	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;
+	virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const override;
+	virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) override;
+	virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) override;
 
-	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;
+	virtual void font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) override;
+	virtual Ref<Image> font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override;
 
-	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;
+	virtual void font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) override;
+	virtual PackedInt32Array font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override;
 
-	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;
+	virtual Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const override;
+	virtual void font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) override;
+	virtual void font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) override;
 
-	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;
+	virtual Vector2 font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) override;
 
-	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;
+	virtual Vector2 font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) override;
 
-	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;
+	virtual Vector2 font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) override;
 
-	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;
+	virtual Rect2 font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) override;
 
-	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;
+	virtual int64_t font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) override;
 
-	virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const override;
+	virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override;
 
-	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;
+	virtual Array font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const override;
+	virtual void font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) override;
+	virtual void font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) override;
 
-	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;
+	virtual void font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) override;
+	virtual Vector2 font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const override;
 
-	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;
+	virtual int64_t font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector = 0) const override;
 
-	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;
+	virtual bool font_has_char(const RID &p_font_rid, int64_t p_char) const override;
+	virtual String font_get_supported_chars(const RID &p_font_rid) const override;
 
-	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;
+	virtual void font_render_range(const RID &p_font, const Vector2i &p_size, int64_t p_start, int64_t p_end) override;
+	virtual void font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) override;
 
-	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;
+	virtual void font_draw_glyph(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
+	virtual void font_draw_glyph_outline(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
 
-	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;
+	virtual bool font_is_language_supported(const RID &p_font_rid, const String &p_language) const override;
+	virtual void font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) override;
+	virtual bool font_get_language_support_override(const RID &p_font_rid, const String &p_language) override;
+	virtual void font_remove_language_support_override(const RID &p_font_rid, const String &p_language) override;
+	virtual PackedStringArray font_get_language_support_overrides(const RID &p_font_rid) override;
 
-	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;
+	virtual bool font_is_script_supported(const RID &p_font_rid, const String &p_script) const override;
+	virtual void font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) override;
+	virtual bool font_get_script_support_override(const RID &p_font_rid, const String &p_script) override;
+	virtual void font_remove_script_support_override(const RID &p_font_rid, const String &p_script) override;
+	virtual PackedStringArray font_get_script_support_overrides(const RID &p_font_rid) override;
 
-	virtual void font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) override;
-	virtual Dictionary font_get_opentype_feature_overrides(RID p_font_rid) const override;
+	virtual void font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) override;
+	virtual Dictionary font_get_opentype_feature_overrides(const RID &p_font_rid) const override;
 
-	virtual Dictionary font_supported_feature_list(RID p_font_rid) const override;
-	virtual Dictionary font_supported_variation_list(RID p_font_rid) const override;
+	virtual Dictionary font_supported_feature_list(const RID &p_font_rid) const override;
+	virtual Dictionary font_supported_variation_list(const RID &p_font_rid) const override;
 
-	virtual float font_get_global_oversampling() const override;
-	virtual void font_set_global_oversampling(float p_oversampling) override;
+	virtual double font_get_global_oversampling() const override;
+	virtual void font_set_global_oversampling(double p_oversampling) override;
 
 	/* Shaped text buffer interface */
 
 	virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
 
-	virtual void shaped_text_clear(RID p_shaped) override;
+	virtual void shaped_text_clear(const RID &p_shaped) override;
 
-	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;
-	virtual Direction shaped_text_get_inferred_direction(RID p_shaped) const override;
+	virtual void shaped_text_set_direction(const RID &p_shaped, Direction p_direction = DIRECTION_AUTO) override;
+	virtual Direction shaped_text_get_direction(const RID &p_shaped) const override;
+	virtual Direction shaped_text_get_inferred_direction(const RID &p_shaped) const override;
 
-	virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override;
+	virtual void shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) override;
 
-	virtual void shaped_text_set_custom_punctuation(RID p_shaped, const String &p_punct) override;
-	virtual String shaped_text_get_custom_punctuation(RID p_shaped) const override;
+	virtual void shaped_text_set_custom_punctuation(const RID &p_shaped, const String &p_punct) override;
+	virtual String shaped_text_get_custom_punctuation(const RID &p_shaped) const override;
 
-	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;
+	virtual void shaped_text_set_orientation(const RID &p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
+	virtual Orientation shaped_text_get_orientation(const RID &p_shaped) const override;
 
-	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;
+	virtual void shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) override;
+	virtual bool shaped_text_get_preserve_invalid(const RID &p_shaped) const override;
 
-	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;
+	virtual void shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) override;
+	virtual bool shaped_text_get_preserve_control(const RID &p_shaped) const override;
 
-	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 = "", const Variant &p_meta = Variant()) override;
-	virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) override;
-	virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
+	virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override;
+	virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) override;
+	virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
 
-	virtual int shaped_get_span_count(RID p_shaped) const override;
-	virtual Variant shaped_get_span_meta(RID p_shaped, int p_index) const override;
-	virtual void shaped_set_span_update_font(RID p_shaped, int p_index, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary()) override;
+	virtual int64_t shaped_get_span_count(const RID &p_shaped) const override;
+	virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const override;
+	virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override;
 
-	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;
+	virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const override;
+	virtual RID shaped_text_get_parent(const RID &p_shaped) const override;
 
-	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;
+	virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, int64_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
+	virtual double shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) override;
 
-	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;
+	virtual bool shaped_text_shape(const RID &p_shaped) override;
+	virtual bool shaped_text_update_breaks(const RID &p_shaped) override;
+	virtual bool shaped_text_update_justification_ops(const RID &p_shaped) override;
 
-	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;
+	virtual int64_t shaped_text_get_trim_pos(const RID &p_shaped) const override;
+	virtual int64_t shaped_text_get_ellipsis_pos(const RID &p_shaped) const override;
+	virtual const Glyph *shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const override;
+	virtual int64_t shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const override;
 
-	virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) override;
+	virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, int64_t p_trim_flags) override;
 
-	virtual bool shaped_text_is_ready(RID p_shaped) const override;
+	virtual bool shaped_text_is_ready(const RID &p_shaped) const override;
 
-	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;
+	virtual const Glyph *shaped_text_get_glyphs(const RID &p_shaped) const override;
+	virtual const Glyph *shaped_text_sort_logical(const RID &p_shaped) override;
+	virtual int64_t shaped_text_get_glyph_count(const RID &p_shaped) const override;
 
-	virtual Vector2i shaped_text_get_range(RID p_shaped) const override;
+	virtual Vector2i shaped_text_get_range(const RID &p_shaped) const override;
 
-	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;
+	virtual Array shaped_text_get_objects(const RID &p_shaped) const override;
+	virtual Rect2 shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const override;
 
-	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;
+	virtual Size2 shaped_text_get_size(const RID &p_shaped) const override;
+	virtual double shaped_text_get_ascent(const RID &p_shaped) const override;
+	virtual double shaped_text_get_descent(const RID &p_shaped) const override;
+	virtual double shaped_text_get_width(const RID &p_shaped) const override;
+	virtual double shaped_text_get_underline_position(const RID &p_shaped) const override;
+	virtual double shaped_text_get_underline_thickness(const RID &p_shaped) const override;
 
 	virtual String string_to_upper(const String &p_string, const String &p_language = "") const override;
 	virtual String string_to_lower(const String &p_string, const String &p_language = "") const override;

+ 3 - 3
scene/gui/label.cpp

@@ -115,7 +115,7 @@ void Label::_shape() {
 
 	if (lines_dirty) {
 		for (int i = 0; i < lines_rid.size(); i++) {
-			TS->free(lines_rid[i]);
+			TS->free_rid(lines_rid[i]);
 		}
 		lines_rid.clear();
 
@@ -960,8 +960,8 @@ Label::Label(const String &p_text) {
 
 Label::~Label() {
 	for (int i = 0; i < lines_rid.size(); i++) {
-		TS->free(lines_rid[i]);
+		TS->free_rid(lines_rid[i]);
 	}
 	lines_rid.clear();
-	TS->free(text_rid);
+	TS->free_rid(text_rid);
 }

+ 1 - 1
scene/gui/line_edit.cpp

@@ -2458,5 +2458,5 @@ LineEdit::LineEdit(const String &p_placeholder) {
 }
 
 LineEdit::~LineEdit() {
-	TS->free(text_rid);
+	TS->free_rid(text_rid);
 }

+ 10 - 4
scene/resources/font.cpp

@@ -40,7 +40,7 @@
 _FORCE_INLINE_ void FontData::_clear_cache() {
 	for (int i = 0; i < cache.size(); i++) {
 		if (cache[i].is_valid()) {
-			TS->free(cache[i]);
+			TS->free_rid(cache[i]);
 			cache.write[i] = RID();
 		}
 	}
@@ -1499,7 +1499,7 @@ void FontData::clear_cache() {
 void FontData::remove_cache(int p_cache_index) {
 	ERR_FAIL_INDEX(p_cache_index, cache.size());
 	if (cache[p_cache_index].is_valid()) {
-		TS->free(cache.write[p_cache_index]);
+		TS->free_rid(cache.write[p_cache_index]);
 	}
 	cache.remove_at(p_cache_index);
 	emit_changed();
@@ -1924,6 +1924,8 @@ void Font::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_supported_chars"), &Font::get_supported_chars);
 
 	ClassDB::bind_method(D_METHOD("update_changes"), &Font::update_changes);
+
+	ClassDB::bind_method(D_METHOD("get_rids"), &Font::get_rids);
 }
 
 bool Font::_set(const StringName &p_name, const Variant &p_value) {
@@ -2427,11 +2429,15 @@ String Font::get_supported_chars() const {
 	return chars;
 }
 
-Vector<RID> Font::get_rids() const {
+Array Font::get_rids() const {
+	Array _rids;
 	for (int i = 0; i < data.size(); i++) {
 		_ensure_rid(i);
+		if (rids[i].is_valid()) {
+			_rids.push_back(rids[i]);
+		}
 	}
-	return rids;
+	return _rids;
 }
 
 void Font::update_changes() {

+ 1 - 1
scene/resources/font.h

@@ -311,7 +311,7 @@ public:
 	virtual Size2 get_char_size(char32_t p_char, char32_t p_next = 0, int p_size = DEFAULT_FONT_SIZE) const;
 	virtual real_t draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, int p_size = DEFAULT_FONT_SIZE, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, const Color &p_outline_modulate = Color(1, 1, 1, 0)) const;
 
-	Vector<RID> get_rids() const;
+	Array get_rids() const;
 
 	void update_changes();
 

+ 1 - 1
scene/resources/text_line.cpp

@@ -411,5 +411,5 @@ TextLine::TextLine() {
 }
 
 TextLine::~TextLine() {
-	TS->free(rid);
+	TS->free_rid(rid);
 }

+ 6 - 6
scene/resources/text_paragraph.cpp

@@ -140,7 +140,7 @@ void TextParagraph::_bind_methods() {
 void TextParagraph::_shape_lines() {
 	if (lines_dirty) {
 		for (int i = 0; i < lines_rid.size(); i++) {
-			TS->free(lines_rid[i]);
+			TS->free_rid(lines_rid[i]);
 		}
 		lines_rid.clear();
 
@@ -168,7 +168,7 @@ void TextParagraph::_shape_lines() {
 				RID line = TS->shaped_text_substr(rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]);
 				float h = (TS->shaped_text_get_orientation(line) == TextServer::ORIENTATION_HORIZONTAL) ? TS->shaped_text_get_size(line).y : TS->shaped_text_get_size(line).x;
 				if (v_offset < h) {
-					TS->free(line);
+					TS->free_rid(line);
 					break;
 				}
 				if (!tab_stops.is_empty()) {
@@ -271,7 +271,7 @@ void TextParagraph::clear() {
 	spacing_top = 0;
 	spacing_bottom = 0;
 	for (int i = 0; i < lines_rid.size(); i++) {
-		TS->free(lines_rid[i]);
+		TS->free_rid(lines_rid[i]);
 	}
 	lines_rid.clear();
 	TS->shaped_text_clear(rid);
@@ -847,9 +847,9 @@ TextParagraph::TextParagraph() {
 
 TextParagraph::~TextParagraph() {
 	for (int i = 0; i < lines_rid.size(); i++) {
-		TS->free(lines_rid[i]);
+		TS->free_rid(lines_rid[i]);
 	}
 	lines_rid.clear();
-	TS->free(rid);
-	TS->free(dropcap_rid);
+	TS->free_rid(rid);
+	TS->free_rid(dropcap_rid);
 }

+ 2 - 0
servers/register_server_types.cpp

@@ -72,6 +72,7 @@
 #include "rendering_server.h"
 #include "servers/extensions/physics_server_3d_extension.h"
 #include "servers/rendering/shader_types.h"
+#include "text/text_server_dummy.h"
 #include "text/text_server_extension.h"
 #include "text_server.h"
 #include "xr/xr_interface.h"
@@ -113,6 +114,7 @@ void preregister_server_types() {
 	GDREGISTER_CLASS(TextServerManager);
 	GDREGISTER_ABSTRACT_CLASS(TextServer);
 	GDREGISTER_CLASS(TextServerExtension);
+	GDREGISTER_CLASS(TextServerDummy);
 
 	GDREGISTER_NATIVE_STRUCT(Glyph, "int start = -1;int end = -1;uint8_t count = 0;uint8_t repeat = 1;uint16_t flags = 0;float x_off = 0.f;float y_off = 0.f;float advance = 0.f;RID font_rid;int font_size = 0;int32_t index = 0");
 	GDREGISTER_NATIVE_STRUCT(CaretInfo, "Rect2 leading_caret;Rect2 trailing_caret;TextServer::Direction leading_direction;TextServer::Direction trailing_direction");

+ 48 - 0
servers/text/text_server_dummy.h

@@ -0,0 +1,48 @@
+/*************************************************************************/
+/*  text_server_dummy.h                                                  */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "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_DUMMY_H
+#define TEXT_SERVER_DUMMY_H
+
+#include "servers/text/text_server_extension.h"
+
+/*************************************************************************/
+
+class TextServerDummy : public TextServerExtension {
+	GDCLASS(TextServerDummy, TextServerExtension);
+	_THREAD_SAFE_CLASS_
+
+public:
+	virtual String get_name() const override {
+		return "Dummy";
+	}
+};
+
+#endif // TEXT_SERVER_DUMMY_H

Datei-Diff unterdrückt, da er zu groß ist
+ 420 - 418
servers/text/text_server_extension.cpp


+ 407 - 404
servers/text/text_server_extension.h

@@ -48,433 +48,436 @@ protected:
 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 int64_t get_features() const override;
+	GDVIRTUAL1RC(bool, has_feature, Feature);
+	GDVIRTUAL0RC(String, get_name);
+	GDVIRTUAL0RC(int64_t, get_features);
 
-	virtual void free(RID p_rid) override;
-	virtual bool has(RID p_rid) override;
+	virtual void free_rid(const RID &p_rid) override;
+	virtual bool has(const 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 &);
+	GDVIRTUAL1(free_rid, 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 &);
+	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 &);
+	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);
+	virtual int64_t name_to_tag(const String &p_name) const override;
+	virtual String tag_to_name(int64_t p_tag) const override;
+	GDVIRTUAL1RC(int64_t, name_to_tag, const String &);
+	GDVIRTUAL1RC(String, tag_to_name, int64_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_style(RID p_font_rid, uint32_t /*FontStyle*/ p_style) override;
-	virtual uint32_t /*FontStyle*/ font_get_style(RID p_font_rid) const override;
-	GDVIRTUAL2(_font_set_style, RID, uint32_t);
-	GDVIRTUAL1RC(uint32_t, _font_get_style, RID);
-
-	virtual void font_set_name(RID p_font_rid, const String &p_name) override;
-	virtual String font_get_name(RID p_font_rid) const override;
-	GDVIRTUAL2(_font_set_name, RID, const String &);
-	GDVIRTUAL1RC(String, _font_get_name, RID);
-
-	virtual void font_set_style_name(RID p_font_rid, const String &p_name) override;
-	virtual String font_get_style_name(RID p_font_rid) const override;
-	GDVIRTUAL2(_font_set_style_name, RID, const String &);
-	GDVIRTUAL1RC(String, _font_get_style_name, RID);
-
-	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, _font_get_hinting, RID);
-
-	virtual void font_set_subpixel_positioning(RID p_font_rid, SubpixelPositioning p_subpixel) override;
-	virtual SubpixelPositioning font_get_subpixel_positioning(RID p_font_rid) const override;
-	GDVIRTUAL2(_font_set_subpixel_positioning, RID, SubpixelPositioning);
-	GDVIRTUAL1RC(SubpixelPositioning, _font_get_subpixel_positioning, RID);
-
-	virtual void font_set_embolden(RID p_font_rid, float p_strength) override;
-	virtual float font_get_embolden(RID p_font_rid) const override;
-	GDVIRTUAL2(_font_set_embolden, RID, float);
-	GDVIRTUAL1RC(float, _font_get_embolden, RID);
-
-	virtual void font_set_transform(RID p_font_rid, Transform2D p_transform) override;
-	virtual Transform2D font_get_transform(RID p_font_rid) const override;
-	GDVIRTUAL2(_font_set_transform, RID, Transform2D);
-	GDVIRTUAL1RC(Transform2D, _font_get_transform, 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 void font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) override;
-	virtual Dictionary font_get_opentype_feature_overrides(RID p_font_rid) const override;
-	GDVIRTUAL2(_font_set_opentype_feature_overrides, RID, const Dictionary &);
-	GDVIRTUAL1RC(Dictionary, _font_get_opentype_feature_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 &);
+	GDVIRTUAL0R(RID, create_font);
+
+	virtual void font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) override;
+	virtual void font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) override;
+	GDVIRTUAL2(font_set_data, RID, const PackedByteArray &);
+	GDVIRTUAL3(font_set_data_ptr, RID, GDNativeConstPtr<const uint8_t>, int64_t);
+
+	virtual void font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) override;
+	virtual int64_t /*FontStyle*/ font_get_style(const RID &p_font_rid) const override;
+	GDVIRTUAL2(font_set_style, RID, int64_t);
+	GDVIRTUAL1RC(int64_t, font_get_style, RID);
+
+	virtual void font_set_name(const RID &p_font_rid, const String &p_name) override;
+	virtual String font_get_name(const RID &p_font_rid) const override;
+	GDVIRTUAL2(font_set_name, RID, const String &);
+	GDVIRTUAL1RC(String, font_get_name, RID);
+
+	virtual void font_set_style_name(const RID &p_font_rid, const String &p_name) override;
+	virtual String font_get_style_name(const RID &p_font_rid) const override;
+	GDVIRTUAL2(font_set_style_name, RID, const String &);
+	GDVIRTUAL1RC(String, font_get_style_name, RID);
+
+	virtual void font_set_antialiased(const RID &p_font_rid, bool p_antialiased) override;
+	virtual bool font_is_antialiased(const 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(const RID &p_font_rid, bool p_msdf) override;
+	virtual bool font_is_multichannel_signed_distance_field(const 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(const RID &p_font_rid, int64_t p_msdf_pixel_range) override;
+	virtual int64_t font_get_msdf_pixel_range(const RID &p_font_rid) const override;
+	GDVIRTUAL2(font_set_msdf_pixel_range, RID, int64_t);
+	GDVIRTUAL1RC(int64_t, font_get_msdf_pixel_range, RID);
+
+	virtual void font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) override;
+	virtual int64_t font_get_msdf_size(const RID &p_font_rid) const override;
+	GDVIRTUAL2(font_set_msdf_size, RID, int64_t);
+	GDVIRTUAL1RC(int64_t, font_get_msdf_size, RID);
+
+	virtual void font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) override;
+	virtual int64_t font_get_fixed_size(const RID &p_font_rid) const override;
+	GDVIRTUAL2(font_set_fixed_size, RID, int64_t);
+	GDVIRTUAL1RC(int64_t, font_get_fixed_size, RID);
+
+	virtual void font_set_subpixel_positioning(const RID &p_font_rid, SubpixelPositioning p_subpixel) override;
+	virtual SubpixelPositioning font_get_subpixel_positioning(const RID &p_font_rid) const override;
+	GDVIRTUAL2(font_set_subpixel_positioning, RID, SubpixelPositioning);
+	GDVIRTUAL1RC(SubpixelPositioning, font_get_subpixel_positioning, RID);
+
+	virtual void font_set_embolden(const RID &p_font_rid, double p_strength) override;
+	virtual double font_get_embolden(const RID &p_font_rid) const override;
+	GDVIRTUAL2(font_set_embolden, RID, double);
+	GDVIRTUAL1RC(double, font_get_embolden, RID);
+
+	virtual void font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) override;
+	virtual Transform2D font_get_transform(const RID &p_font_rid) const override;
+	GDVIRTUAL2(font_set_transform, RID, Transform2D);
+	GDVIRTUAL1RC(Transform2D, font_get_transform, RID);
+
+	virtual void font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) override;
+	virtual bool font_is_force_autohinter(const 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(const RID &p_font_rid, Hinting p_hinting) override;
+	virtual Hinting font_get_hinting(const RID &p_font_rid) const override;
+	GDVIRTUAL2(font_set_hinting, RID, Hinting);
+	GDVIRTUAL1RC(Hinting, font_get_hinting, RID);
+
+	virtual void font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) override;
+	virtual Dictionary font_get_variation_coordinates(const 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(const RID &p_font_rid, double p_oversampling) override;
+	virtual double font_get_oversampling(const RID &p_font_rid) const override;
+	GDVIRTUAL2(font_set_oversampling, RID, double);
+	GDVIRTUAL1RC(double, font_get_oversampling, RID);
+
+	virtual Array font_get_size_cache_list(const RID &p_font_rid) const override;
+	virtual void font_clear_size_cache(const RID &p_font_rid) override;
+	virtual void font_remove_size_cache(const 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(const RID &p_font_rid, int64_t p_size, double p_ascent) override;
+	virtual double font_get_ascent(const RID &p_font_rid, int64_t p_size) const override;
+	GDVIRTUAL3(font_set_ascent, RID, int64_t, double);
+	GDVIRTUAL2RC(double, font_get_ascent, RID, int64_t);
+
+	virtual void font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) override;
+	virtual double font_get_descent(const RID &p_font_rid, int64_t p_size) const override;
+	GDVIRTUAL3(font_set_descent, RID, int64_t, double);
+	GDVIRTUAL2RC(double, font_get_descent, RID, int64_t);
+
+	virtual void font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) override;
+	virtual double font_get_underline_position(const RID &p_font_rid, int64_t p_size) const override;
+	GDVIRTUAL3(font_set_underline_position, RID, int64_t, double);
+	GDVIRTUAL2RC(double, font_get_underline_position, RID, int64_t);
+
+	virtual void font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) override;
+	virtual double font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const override;
+	GDVIRTUAL3(font_set_underline_thickness, RID, int64_t, double);
+	GDVIRTUAL2RC(double, font_get_underline_thickness, RID, int64_t);
+
+	virtual void font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) override;
+	virtual double font_get_scale(const RID &p_font_rid, int64_t p_size) const override;
+	GDVIRTUAL3(font_set_scale, RID, int64_t, double);
+	GDVIRTUAL2RC(double, font_get_scale, RID, int64_t);
+
+	virtual void font_set_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing, int64_t p_value) override;
+	virtual int64_t font_get_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing) const override;
+	GDVIRTUAL4(font_set_spacing, RID, int64_t, SpacingType, int64_t);
+	GDVIRTUAL3RC(int64_t, font_get_spacing, RID, int64_t, SpacingType);
+
+	virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const override;
+	virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) override;
+	virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) override;
+	GDVIRTUAL2RC(int64_t, font_get_texture_count, RID, const Vector2i &);
+	GDVIRTUAL2(font_clear_textures, RID, const Vector2i &);
+	GDVIRTUAL3(font_remove_texture, RID, const Vector2i &, int64_t);
+
+	virtual void font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) override;
+	virtual Ref<Image> font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override;
+	GDVIRTUAL4(font_set_texture_image, RID, const Vector2i &, int64_t, const Ref<Image> &);
+	GDVIRTUAL3RC(Ref<Image>, font_get_texture_image, RID, const Vector2i &, int64_t);
+
+	virtual void font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) override;
+	virtual PackedInt32Array font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const override;
+	GDVIRTUAL4(font_set_texture_offsets, RID, const Vector2i &, int64_t, const PackedInt32Array &);
+	GDVIRTUAL3RC(PackedInt32Array, font_get_texture_offsets, RID, const Vector2i &, int64_t);
+
+	virtual Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const override;
+	virtual void font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) override;
+	virtual void font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_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 &, int64_t);
+
+	virtual Vector2 font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) override;
+	GDVIRTUAL3RC(Vector2, font_get_glyph_advance, RID, int64_t, int64_t);
+	GDVIRTUAL4(font_set_glyph_advance, RID, int64_t, int64_t, const Vector2 &);
+
+	virtual Vector2 font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) override;
+	GDVIRTUAL3RC(Vector2, font_get_glyph_offset, RID, const Vector2i &, int64_t);
+	GDVIRTUAL4(font_set_glyph_offset, RID, const Vector2i &, int64_t, const Vector2 &);
+
+	virtual Vector2 font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) override;
+	GDVIRTUAL3RC(Vector2, font_get_glyph_size, RID, const Vector2i &, int64_t);
+	GDVIRTUAL4(font_set_glyph_size, RID, const Vector2i &, int64_t, const Vector2 &);
+
+	virtual Rect2 font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) override;
+	GDVIRTUAL3RC(Rect2, font_get_glyph_uv_rect, RID, const Vector2i &, int64_t);
+	GDVIRTUAL4(font_set_glyph_uv_rect, RID, const Vector2i &, int64_t, const Rect2 &);
+
+	virtual int64_t font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+	virtual void font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) override;
+	GDVIRTUAL3RC(int64_t, font_get_glyph_texture_idx, RID, const Vector2i &, int64_t);
+	GDVIRTUAL4(font_set_glyph_texture_idx, RID, const Vector2i &, int64_t, int64_t);
+
+	virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override;
+	GDVIRTUAL3RC(Dictionary, font_get_glyph_contours, RID, int64_t, int64_t);
+
+	virtual Array font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const override;
+	virtual void font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) override;
+	virtual void font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) override;
+	GDVIRTUAL2RC(Array, font_get_kerning_list, RID, int64_t);
+	GDVIRTUAL2(font_clear_kerning_map, RID, int64_t);
+	GDVIRTUAL3(font_remove_kerning, RID, int64_t, const Vector2i &);
+
+	virtual void font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) override;
+	virtual Vector2 font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const override;
+	GDVIRTUAL4(font_set_kerning, RID, int64_t, const Vector2i &, const Vector2 &);
+	GDVIRTUAL3RC(Vector2, font_get_kerning, RID, int64_t, const Vector2i &);
+
+	virtual int64_t font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector = 0) const override;
+	GDVIRTUAL4RC(int64_t, font_get_glyph_index, RID, int64_t, int64_t, int64_t);
+
+	virtual bool font_has_char(const RID &p_font_rid, int64_t p_char) const override;
+	virtual String font_get_supported_chars(const RID &p_font_rid) const override;
+	GDVIRTUAL2RC(bool, font_has_char, RID, int64_t);
+	GDVIRTUAL1RC(String, font_get_supported_chars, RID);
+
+	virtual void font_render_range(const RID &p_font, const Vector2i &p_size, int64_t p_start, int64_t p_end) override;
+	virtual void font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) override;
+	GDVIRTUAL4(font_render_range, RID, const Vector2i &, int64_t, int64_t);
+	GDVIRTUAL3(font_render_glyph, RID, const Vector2i &, int64_t);
+
+	virtual void font_draw_glyph(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
+	virtual void font_draw_glyph_outline(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
+	GDVIRTUAL6C(font_draw_glyph, RID, RID, int64_t, const Vector2 &, int64_t, const Color &);
+	GDVIRTUAL7C(font_draw_glyph_outline, RID, RID, int64_t, int64_t, const Vector2 &, int64_t, const Color &);
+
+	virtual bool font_is_language_supported(const RID &p_font_rid, const String &p_language) const override;
+	virtual void font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) override;
+	virtual bool font_get_language_support_override(const RID &p_font_rid, const String &p_language) override;
+	virtual void font_remove_language_support_override(const RID &p_font_rid, const String &p_language) override;
+	virtual PackedStringArray font_get_language_support_overrides(const 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(PackedStringArray, font_get_language_support_overrides, RID);
+
+	virtual bool font_is_script_supported(const RID &p_font_rid, const String &p_script) const override;
+	virtual void font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) override;
+	virtual bool font_get_script_support_override(const RID &p_font_rid, const String &p_script) override;
+	virtual void font_remove_script_support_override(const RID &p_font_rid, const String &p_script) override;
+	virtual PackedStringArray font_get_script_support_overrides(const 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(PackedStringArray, font_get_script_support_overrides, RID);
+
+	virtual void font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) override;
+	virtual Dictionary font_get_opentype_feature_overrides(const RID &p_font_rid) const override;
+	GDVIRTUAL2(font_set_opentype_feature_overrides, RID, const Dictionary &);
+	GDVIRTUAL1RC(Dictionary, font_get_opentype_feature_overrides, RID);
+
+	virtual Dictionary font_supported_feature_list(const RID &p_font_rid) const override;
+	virtual Dictionary font_supported_variation_list(const RID &p_font_rid) const override;
+	GDVIRTUAL1RC(Dictionary, font_supported_feature_list, RID);
+	GDVIRTUAL1RC(Dictionary, font_supported_variation_list, RID);
+
+	virtual double font_get_global_oversampling() const override;
+	virtual void font_set_global_oversampling(double p_oversampling) override;
+	GDVIRTUAL0RC(double, font_get_global_oversampling);
+	GDVIRTUAL1(font_set_global_oversampling, double);
+
+	virtual Vector2 get_hex_code_box_size(int64_t p_size, int64_t p_index) const override;
+	virtual void draw_hex_code_box(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const override;
+	GDVIRTUAL2RC(Vector2, get_hex_code_box_size, int64_t, int64_t);
+	GDVIRTUAL5C(draw_hex_code_box, RID, int64_t, const Vector2 &, int64_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;
-	virtual Direction shaped_text_get_inferred_direction(RID p_shaped) const override;
-	GDVIRTUAL2(_shaped_text_set_direction, RID, Direction);
-	GDVIRTUAL1RC(Direction, _shaped_text_get_direction, RID);
-	GDVIRTUAL1RC(Direction, _shaped_text_get_inferred_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_custom_punctuation(RID p_shaped, const String &p_punct) override;
-	virtual String shaped_text_get_custom_punctuation(RID p_shaped) const override;
-	GDVIRTUAL2(_shaped_text_set_custom_punctuation, RID, String);
-	GDVIRTUAL1RC(String, _shaped_text_get_custom_punctuation, RID);
-
-	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, _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 = "", const Variant &p_meta = Variant()) override;
-	virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) override;
-	virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
-	GDVIRTUAL7R(bool, _shaped_text_add_string, RID, const String &, const Array &, int, const Dictionary &, const String &, const Variant &);
-	GDVIRTUAL5R(bool, _shaped_text_add_object, RID, Variant, const Size2 &, InlineAlignment, int);
-	GDVIRTUAL4R(bool, _shaped_text_resize_object, RID, Variant, const Size2 &, InlineAlignment);
-
-	virtual int shaped_get_span_count(RID p_shaped) const override;
-	virtual Variant shaped_get_span_meta(RID p_shaped, int p_index) const override;
-	virtual void shaped_set_span_update_font(RID p_shaped, int p_index, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary()) override;
-	GDVIRTUAL1RC(int, _shaped_get_span_count, RID);
-	GDVIRTUAL2RC(Variant, _shaped_get_span_meta, RID, int);
-	GDVIRTUAL5(_shaped_set_span_update_font, RID, int, const Array &, int, const Dictionary &);
-
-	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;
-	GDVIRTUAL1RC(GDNativePtr<Glyph>, _shaped_text_get_glyphs, RID);
-	GDVIRTUAL1R(GDNativePtr<Glyph>, _shaped_text_sort_logical, RID);
-	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);
-	GDVIRTUAL1RC(GDNativePtr<Glyph>, _shaped_text_get_ellipsis_glyphs, RID);
-	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 Vector2 shaped_text_get_grapheme_bounds(RID p_shaped, int p_pos) const override;
-	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(Vector2, _shaped_text_get_grapheme_bounds, RID, int);
-	GDVIRTUAL2RC(int, _shaped_text_next_grapheme_pos, RID, int);
-	GDVIRTUAL2RC(int, _shaped_text_prev_grapheme_pos, RID, int);
+	GDVIRTUAL2R(RID, create_shaped_text, Direction, Orientation);
+
+	virtual void shaped_text_clear(const RID &p_shaped) override;
+	GDVIRTUAL1(shaped_text_clear, RID);
+
+	virtual void shaped_text_set_direction(const RID &p_shaped, Direction p_direction = DIRECTION_AUTO) override;
+	virtual Direction shaped_text_get_direction(const RID &p_shaped) const override;
+	virtual Direction shaped_text_get_inferred_direction(const RID &p_shaped) const override;
+	GDVIRTUAL2(shaped_text_set_direction, RID, Direction);
+	GDVIRTUAL1RC(Direction, shaped_text_get_direction, RID);
+	GDVIRTUAL1RC(Direction, shaped_text_get_inferred_direction, RID);
+
+	virtual void shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) override;
+	GDVIRTUAL2(shaped_text_set_bidi_override, RID, const Array &);
+
+	virtual void shaped_text_set_custom_punctuation(const RID &p_shaped, const String &p_punct) override;
+	virtual String shaped_text_get_custom_punctuation(const RID &p_shaped) const override;
+	GDVIRTUAL2(shaped_text_set_custom_punctuation, RID, String);
+	GDVIRTUAL1RC(String, shaped_text_get_custom_punctuation, RID);
+
+	virtual void shaped_text_set_orientation(const RID &p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
+	virtual Orientation shaped_text_get_orientation(const RID &p_shaped) const override;
+	GDVIRTUAL2(shaped_text_set_orientation, RID, Orientation);
+	GDVIRTUAL1RC(Orientation, shaped_text_get_orientation, RID);
+
+	virtual void shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) override;
+	virtual bool shaped_text_get_preserve_invalid(const 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(const RID &p_shaped, bool p_enabled) override;
+	virtual bool shaped_text_get_preserve_control(const 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(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override;
+	virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) override;
+	virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
+	GDVIRTUAL7R(bool, shaped_text_add_string, RID, const String &, const Array &, int64_t, const Dictionary &, const String &, const Variant &);
+	GDVIRTUAL5R(bool, shaped_text_add_object, RID, const Variant &, const Size2 &, InlineAlignment, int64_t);
+	GDVIRTUAL4R(bool, shaped_text_resize_object, RID, const Variant &, const Size2 &, InlineAlignment);
+
+	virtual int64_t shaped_get_span_count(const RID &p_shaped) const override;
+	virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const override;
+	virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override;
+	GDVIRTUAL1RC(int64_t, shaped_get_span_count, RID);
+	GDVIRTUAL2RC(Variant, shaped_get_span_meta, RID, int64_t);
+	GDVIRTUAL5(shaped_set_span_update_font, RID, int64_t, const Array &, int64_t, const Dictionary &);
+
+	virtual RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const override;
+	virtual RID shaped_text_get_parent(const RID &p_shaped) const override;
+	GDVIRTUAL3RC(RID, shaped_text_substr, RID, int64_t, int64_t);
+	GDVIRTUAL1RC(RID, shaped_text_get_parent, RID);
+
+	virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, int64_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) override;
+	virtual double shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) override;
+	GDVIRTUAL3R(double, shaped_text_fit_to_width, RID, double, int64_t);
+	GDVIRTUAL2R(double, shaped_text_tab_align, RID, const PackedFloat32Array &);
+
+	virtual bool shaped_text_shape(const RID &p_shaped) override;
+	virtual bool shaped_text_update_breaks(const RID &p_shaped) override;
+	virtual bool shaped_text_update_justification_ops(const 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(const RID &p_shaped) const override;
+	GDVIRTUAL1RC(bool, shaped_text_is_ready, RID);
+
+	virtual const Glyph *shaped_text_get_glyphs(const RID &p_shaped) const override;
+	virtual const Glyph *shaped_text_sort_logical(const RID &p_shaped) override;
+	virtual int64_t shaped_text_get_glyph_count(const RID &p_shaped) const override;
+	GDVIRTUAL1RC(GDNativeConstPtr<const Glyph>, shaped_text_get_glyphs, RID);
+	GDVIRTUAL1R(GDNativeConstPtr<const Glyph>, shaped_text_sort_logical, RID);
+	GDVIRTUAL1RC(int64_t, shaped_text_get_glyph_count, RID);
+
+	virtual Vector2i shaped_text_get_range(const RID &p_shaped) const override;
+	GDVIRTUAL1RC(Vector2i, shaped_text_get_range, RID);
+
+	virtual PackedInt32Array shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start = 0, bool p_once = true, int64_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
+	virtual PackedInt32Array shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start = 0, int64_t p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const override;
+	virtual PackedInt32Array shaped_text_get_word_breaks(const RID &p_shaped, int64_t p_grapheme_flags = GRAPHEME_IS_SPACE | GRAPHEME_IS_PUNCTUATION) const override;
+	GDVIRTUAL5RC(PackedInt32Array, shaped_text_get_line_breaks_adv, RID, const PackedFloat32Array &, int64_t, bool, int64_t);
+	GDVIRTUAL4RC(PackedInt32Array, shaped_text_get_line_breaks, RID, double, int64_t, int64_t);
+	GDVIRTUAL2RC(PackedInt32Array, shaped_text_get_word_breaks, RID, int64_t);
+
+	virtual int64_t shaped_text_get_trim_pos(const RID &p_shaped) const override;
+	virtual int64_t shaped_text_get_ellipsis_pos(const RID &p_shaped) const override;
+	virtual const Glyph *shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const override;
+	virtual int64_t shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const override;
+	GDVIRTUAL1RC(int64_t, shaped_text_get_trim_pos, RID);
+	GDVIRTUAL1RC(int64_t, shaped_text_get_ellipsis_pos, RID);
+	GDVIRTUAL1RC(GDNativeConstPtr<const Glyph>, shaped_text_get_ellipsis_glyphs, RID);
+	GDVIRTUAL1RC(int64_t, shaped_text_get_ellipsis_glyph_count, RID);
+
+	virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, int64_t p_trim_flags) override;
+	GDVIRTUAL3(shaped_text_overrun_trim_to_width, RID, double, int64_t);
+
+	virtual Array shaped_text_get_objects(const RID &p_shaped) const override;
+	virtual Rect2 shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const override;
+	GDVIRTUAL1RC(Array, shaped_text_get_objects, RID);
+	GDVIRTUAL2RC(Rect2, shaped_text_get_object_rect, RID, const Variant &);
+
+	virtual Size2 shaped_text_get_size(const RID &p_shaped) const override;
+	virtual double shaped_text_get_ascent(const RID &p_shaped) const override;
+	virtual double shaped_text_get_descent(const RID &p_shaped) const override;
+	virtual double shaped_text_get_width(const RID &p_shaped) const override;
+	virtual double shaped_text_get_underline_position(const RID &p_shaped) const override;
+	virtual double shaped_text_get_underline_thickness(const RID &p_shaped) const override;
+	GDVIRTUAL1RC(Size2, shaped_text_get_size, RID);
+	GDVIRTUAL1RC(double, shaped_text_get_ascent, RID);
+	GDVIRTUAL1RC(double, shaped_text_get_descent, RID);
+	GDVIRTUAL1RC(double, shaped_text_get_width, RID);
+	GDVIRTUAL1RC(double, shaped_text_get_underline_position, RID);
+	GDVIRTUAL1RC(double, shaped_text_get_underline_thickness, RID);
+
+	virtual Direction shaped_text_get_dominant_direction_in_range(const RID &p_shaped, int64_t p_start, int64_t p_end) const override;
+	GDVIRTUAL3RC(int64_t, shaped_text_get_dominant_direction_in_range, RID, int64_t, int64_t);
+
+	virtual CaretInfo shaped_text_get_carets(const RID &p_shaped, int64_t p_position) const override;
+	virtual Vector<Vector2> shaped_text_get_selection(const RID &p_shaped, int64_t p_start, int64_t p_end) const override;
+	GDVIRTUAL3C(shaped_text_get_carets, RID, int64_t, GDNativePtr<CaretInfo>);
+	GDVIRTUAL3RC(Vector<Vector2>, shaped_text_get_selection, RID, int64_t, int64_t);
+
+	virtual int64_t shaped_text_hit_test_grapheme(const RID &p_shaped, double p_coords) const override;
+	virtual int64_t shaped_text_hit_test_position(const RID &p_shaped, double p_coords) const override;
+	GDVIRTUAL2RC(int64_t, shaped_text_hit_test_grapheme, RID, double);
+	GDVIRTUAL2RC(int64_t, shaped_text_hit_test_position, RID, double);
+
+	virtual void shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, const Color &p_color = Color(1, 1, 1)) const override;
+	virtual void shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, int64_t p_outline_size = 1, const Color &p_color = Color(1, 1, 1)) const override;
+	GDVIRTUAL6C(shaped_text_draw, RID, RID, const Vector2 &, double, double, const Color &);
+	GDVIRTUAL7C(shaped_text_draw_outline, RID, RID, const Vector2 &, double, double, int64_t, const Color &);
+
+	virtual Vector2 shaped_text_get_grapheme_bounds(const RID &p_shaped, int64_t p_pos) const override;
+	virtual int64_t shaped_text_next_grapheme_pos(const RID &p_shaped, int64_t p_pos) const override;
+	virtual int64_t shaped_text_prev_grapheme_pos(const RID &p_shaped, int64_t p_pos) const override;
+	GDVIRTUAL2RC(Vector2, shaped_text_get_grapheme_bounds, RID, int64_t);
+	GDVIRTUAL2RC(int64_t, shaped_text_next_grapheme_pos, RID, int64_t);
+	GDVIRTUAL2RC(int64_t, shaped_text_prev_grapheme_pos, RID, int64_t);
 
 	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 &);
+	GDVIRTUAL2RC(String, format_number, const String &, const String &);
+	GDVIRTUAL2RC(String, parse_number, const String &, const String &);
+	GDVIRTUAL1RC(String, percent_sign, const String &);
+
+	virtual String strip_diacritics(const String &p_string) const override;
+	GDVIRTUAL1RC(String, strip_diacritics, const String &);
 
 	virtual String string_to_upper(const String &p_string, const String &p_language = "") const override;
 	virtual String string_to_lower(const String &p_string, const String &p_language = "") const override;
-	GDVIRTUAL2RC(String, _string_to_upper, const String &, const String &);
-	GDVIRTUAL2RC(String, _string_to_lower, const String &, const String &);
+	GDVIRTUAL2RC(String, string_to_upper, const String &, const String &);
+	GDVIRTUAL2RC(String, string_to_lower, const String &, const String &);
 
 	TextServerExtension();
 	~TextServerExtension();

+ 29 - 23
servers/text_server.cpp

@@ -200,7 +200,7 @@ void TextServer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("tag_to_name", "tag"), &TextServer::tag_to_name);
 
 	ClassDB::bind_method(D_METHOD("has", "rid"), &TextServer::has);
-	ClassDB::bind_method(D_METHOD("free_rid", "rid"), &TextServer::free); // shouldn't conflict with Object::free()
+	ClassDB::bind_method(D_METHOD("free_rid", "rid"), &TextServer::free_rid);
 
 	/* Font Interface */
 
@@ -493,13 +493,19 @@ void TextServer::_bind_methods() {
 	BIND_ENUM_CONSTANT(SUBPIXEL_POSITIONING_AUTO);
 	BIND_ENUM_CONSTANT(SUBPIXEL_POSITIONING_ONE_HALF);
 	BIND_ENUM_CONSTANT(SUBPIXEL_POSITIONING_ONE_QUARTER);
+	BIND_ENUM_CONSTANT(SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE);
+	BIND_ENUM_CONSTANT(SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE);
 
 	/* Feature */
+	BIND_ENUM_CONSTANT(FEATURE_SIMPLE_LAYOUT);
 	BIND_ENUM_CONSTANT(FEATURE_BIDI_LAYOUT);
 	BIND_ENUM_CONSTANT(FEATURE_VERTICAL_LAYOUT);
 	BIND_ENUM_CONSTANT(FEATURE_SHAPING);
 	BIND_ENUM_CONSTANT(FEATURE_KASHIDA_JUSTIFICATION);
 	BIND_ENUM_CONSTANT(FEATURE_BREAK_ITERATORS);
+	BIND_ENUM_CONSTANT(FEATURE_FONT_BITMAP);
+	BIND_ENUM_CONSTANT(FEATURE_FONT_DYNAMIC);
+	BIND_ENUM_CONSTANT(FEATURE_FONT_MSDF);
 	BIND_ENUM_CONSTANT(FEATURE_FONT_SYSTEM);
 	BIND_ENUM_CONSTANT(FEATURE_FONT_VARIABLE);
 	BIND_ENUM_CONSTANT(FEATURE_CONTEXT_SENSITIVE_CASE_CONVERSION);
@@ -522,7 +528,7 @@ void TextServer::_bind_methods() {
 	BIND_ENUM_CONSTANT(FONT_FIXED_WIDTH);
 }
 
-Vector2 TextServer::get_hex_code_box_size(int p_size, char32_t p_index) const {
+Vector2 TextServer::get_hex_code_box_size(int64_t p_size, int64_t p_index) const {
 	int w = ((p_index <= 0xFF) ? 1 : ((p_index <= 0xFFFF) ? 2 : 3));
 	int sp = MAX(0, w - 1);
 	int sz = MAX(1, Math::round(p_size / 15.f));
@@ -530,7 +536,7 @@ Vector2 TextServer::get_hex_code_box_size(int p_size, char32_t p_index) const {
 	return Vector2(4 + 3 * w + sp + 1, 15) * sz;
 }
 
-void TextServer::_draw_hex_code_box_number(RID p_canvas, int p_size, const Vector2 &p_pos, uint8_t p_index, const Color &p_color) const {
+void TextServer::_draw_hex_code_box_number(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, uint8_t p_index, const Color &p_color) const {
 	static uint8_t chars[] = { 0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, 0x7F, 0x7B, 0x77, 0x1F, 0x4E, 0x3D, 0x4F, 0x47, 0x00 };
 	uint8_t x = chars[p_index];
 	if (x & (1 << 6)) {
@@ -556,7 +562,7 @@ void TextServer::_draw_hex_code_box_number(RID p_canvas, int p_size, const Vecto
 	}
 }
 
-void TextServer::draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_pos, char32_t p_index, const Color &p_color) const {
+void TextServer::draw_hex_code_box(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
 	if (p_index == 0) {
 		return;
 	}
@@ -600,7 +606,7 @@ void TextServer::draw_hex_code_box(RID p_canvas, int p_size, const Vector2 &p_po
 	}
 }
 
-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 TextServer::shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start, bool p_once, int64_t /*TextBreakFlag*/ p_break_flags) const {
 	PackedInt32Array lines;
 
 	ERR_FAIL_COND_V(p_width.is_empty(), lines);
@@ -676,13 +682,13 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const
 	return lines;
 }
 
-PackedInt32Array TextServer::shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start, uint16_t /*TextBreakFlag*/ p_break_flags) const {
+PackedInt32Array TextServer::shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start, int64_t /*TextBreakFlag*/ p_break_flags) const {
 	PackedInt32Array lines;
 
 	const_cast<TextServer *>(this)->shaped_text_update_breaks(p_shaped);
 	const Vector2i &range = shaped_text_get_range(p_shaped);
 
-	float width = 0.f;
+	double width = 0.f;
 	int line_start = MAX(p_start, range.x);
 	int last_safe_break = -1;
 	int word_count = 0;
@@ -744,7 +750,7 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks(RID p_shaped, float p_w
 	return lines;
 }
 
-PackedInt32Array TextServer::shaped_text_get_word_breaks(RID p_shaped, int p_grapheme_flags) const {
+PackedInt32Array TextServer::shaped_text_get_word_breaks(const RID &p_shaped, int64_t p_grapheme_flags) const {
 	PackedInt32Array words;
 
 	const_cast<TextServer *>(this)->shaped_text_update_justification_ops(p_shaped);
@@ -776,7 +782,7 @@ PackedInt32Array TextServer::shaped_text_get_word_breaks(RID p_shaped, int p_gra
 	return words;
 }
 
-CaretInfo TextServer::shaped_text_get_carets(RID p_shaped, int p_position) const {
+CaretInfo TextServer::shaped_text_get_carets(const RID &p_shaped, int64_t p_position) const {
 	Vector<Rect2> carets;
 
 	TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped);
@@ -926,7 +932,7 @@ CaretInfo TextServer::shaped_text_get_carets(RID p_shaped, int p_position) const
 	return caret;
 }
 
-Dictionary TextServer::_shaped_text_get_carets_wrapper(RID p_shaped, int p_position) const {
+Dictionary TextServer::_shaped_text_get_carets_wrapper(const RID &p_shaped, int64_t p_position) const {
 	Dictionary ret;
 
 	CaretInfo caret = shaped_text_get_carets(p_shaped, p_position);
@@ -939,7 +945,7 @@ Dictionary TextServer::_shaped_text_get_carets_wrapper(RID p_shaped, int p_posit
 	return ret;
 }
 
-TextServer::Direction TextServer::shaped_text_get_dominant_direction_in_range(RID p_shaped, int p_start, int p_end) const {
+TextServer::Direction TextServer::shaped_text_get_dominant_direction_in_range(const RID &p_shaped, int64_t p_start, int64_t p_end) const {
 	if (p_start == p_end) {
 		return DIRECTION_AUTO;
 	}
@@ -973,7 +979,7 @@ TextServer::Direction TextServer::shaped_text_get_dominant_direction_in_range(RI
 	}
 }
 
-Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const {
+Vector<Vector2> TextServer::shaped_text_get_selection(const RID &p_shaped, int64_t p_start, int64_t p_end) const {
 	Vector<Vector2> ranges;
 
 	if (p_start == p_end) {
@@ -1066,9 +1072,9 @@ Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start,
 	return ranges;
 }
 
-int TextServer::shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const {
+int64_t TextServer::shaped_text_hit_test_grapheme(const RID &p_shaped, double p_coords) const {
 	// Exact grapheme hit test, return -1 if missed.
-	float off = 0.0f;
+	double off = 0.0f;
 
 	int v_size = shaped_text_get_glyph_count(p_shaped);
 	const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
@@ -1084,7 +1090,7 @@ int TextServer::shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) cons
 	return -1;
 }
 
-int TextServer::shaped_text_hit_test_position(RID p_shaped, float p_coords) const {
+int64_t TextServer::shaped_text_hit_test_position(const RID &p_shaped, double p_coords) const {
 	int v_size = shaped_text_get_glyph_count(p_shaped);
 	const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
 
@@ -1177,7 +1183,7 @@ int TextServer::shaped_text_hit_test_position(RID p_shaped, float p_coords) cons
 	return 0;
 }
 
-Vector2 TextServer::shaped_text_get_grapheme_bounds(RID p_shaped, int p_pos) const {
+Vector2 TextServer::shaped_text_get_grapheme_bounds(const RID &p_shaped, int64_t p_pos) const {
 	int v_size = shaped_text_get_glyph_count(p_shaped);
 	const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
 
@@ -1198,7 +1204,7 @@ Vector2 TextServer::shaped_text_get_grapheme_bounds(RID p_shaped, int p_pos) con
 	return Vector2();
 }
 
-int TextServer::shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const {
+int64_t TextServer::shaped_text_next_grapheme_pos(const RID &p_shaped, int64_t 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++) {
@@ -1209,7 +1215,7 @@ int TextServer::shaped_text_next_grapheme_pos(RID p_shaped, int p_pos) const {
 	return p_pos;
 }
 
-int TextServer::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const {
+int64_t TextServer::shaped_text_prev_grapheme_pos(const RID &p_shaped, int64_t 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++) {
@@ -1221,7 +1227,7 @@ int TextServer::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const {
 	return p_pos;
 }
 
-void TextServer::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 {
+void TextServer::shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, const Color &p_color) const {
 	TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped);
 	bool hex_codes = shaped_text_get_preserve_control(p_shaped) || shaped_text_get_preserve_invalid(p_shaped);
 
@@ -1318,7 +1324,7 @@ 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, float p_clip_l, float p_clip_r, int p_outline_size, const Color &p_color) const {
+void TextServer::shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l, double p_clip_r, int64_t p_outline_size, const Color &p_color) const {
 	TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped);
 
 	bool rtl = (shaped_text_get_inferred_direction(p_shaped) == DIRECTION_RTL);
@@ -1538,7 +1544,7 @@ String TextServer::strip_diacritics(const String &p_string) const {
 	return result;
 }
 
-Array TextServer::_shaped_text_get_glyphs_wrapper(RID p_shaped) const {
+Array TextServer::_shaped_text_get_glyphs_wrapper(const RID &p_shaped) const {
 	Array ret;
 
 	const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
@@ -1563,7 +1569,7 @@ Array TextServer::_shaped_text_get_glyphs_wrapper(RID p_shaped) const {
 	return ret;
 }
 
-Array TextServer::_shaped_text_sort_logical_wrapper(RID p_shaped) {
+Array TextServer::_shaped_text_sort_logical_wrapper(const RID &p_shaped) {
 	Array ret;
 
 	const Glyph *glyphs = shaped_text_sort_logical(p_shaped);
@@ -1588,7 +1594,7 @@ Array TextServer::_shaped_text_sort_logical_wrapper(RID p_shaped) {
 	return ret;
 }
 
-Array TextServer::_shaped_text_get_ellipsis_glyphs_wrapper(RID p_shaped) const {
+Array TextServer::_shaped_text_get_ellipsis_glyphs_wrapper(const RID &p_shaped) const {
 	Array ret;
 
 	const Glyph *glyphs = shaped_text_get_ellipsis_glyphs(p_shaped);

+ 188 - 254
servers/text_server.h

@@ -102,25 +102,29 @@ public:
 	};
 
 	enum SubpixelPositioning {
-		SUBPIXEL_POSITIONING_DISABLED,
-		SUBPIXEL_POSITIONING_AUTO,
-		SUBPIXEL_POSITIONING_ONE_HALF,
-		SUBPIXEL_POSITIONING_ONE_QUARTER,
-	};
+		SUBPIXEL_POSITIONING_DISABLED = 0,
+		SUBPIXEL_POSITIONING_AUTO = 1,
+		SUBPIXEL_POSITIONING_ONE_HALF = 2,
+		SUBPIXEL_POSITIONING_ONE_QUARTER = 3,
 
-	const int SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE = 20;
-	const int SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE = 16;
+		SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE = 20,
+		SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE = 16,
+	};
 
 	enum Feature {
-		FEATURE_BIDI_LAYOUT = 1 << 0,
-		FEATURE_VERTICAL_LAYOUT = 1 << 1,
-		FEATURE_SHAPING = 1 << 2,
-		FEATURE_KASHIDA_JUSTIFICATION = 1 << 3,
-		FEATURE_BREAK_ITERATORS = 1 << 4,
-		FEATURE_FONT_SYSTEM = 1 << 5,
-		FEATURE_FONT_VARIABLE = 1 << 6,
-		FEATURE_CONTEXT_SENSITIVE_CASE_CONVERSION = 1 << 7,
-		FEATURE_USE_SUPPORT_DATA = 1 << 8,
+		FEATURE_SIMPLE_LAYOUT = 1 << 0,
+		FEATURE_BIDI_LAYOUT = 1 << 1,
+		FEATURE_VERTICAL_LAYOUT = 1 << 2,
+		FEATURE_SHAPING = 1 << 3,
+		FEATURE_KASHIDA_JUSTIFICATION = 1 << 4,
+		FEATURE_BREAK_ITERATORS = 1 << 5,
+		FEATURE_FONT_BITMAP = 1 << 6,
+		FEATURE_FONT_DYNAMIC = 1 << 7,
+		FEATURE_FONT_MSDF = 1 << 8,
+		FEATURE_FONT_SYSTEM = 1 << 9,
+		FEATURE_FONT_VARIABLE = 1 << 10,
+		FEATURE_CONTEXT_SENSITIVE_CASE_CONVERSION = 1 << 11,
+		FEATURE_USE_SUPPORT_DATA = 1 << 12,
 	};
 
 	enum ContourPointTag {
@@ -142,62 +146,9 @@ public:
 		FONT_FIXED_WIDTH = 1 << 2,
 	};
 
-	void _draw_hex_code_box_number(RID p_canvas, int p_size, const Vector2 &p_pos, uint8_t p_index, const Color &p_color) const;
+	void _draw_hex_code_box_number(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, uint8_t p_index, const Color &p_color) const;
 
 protected:
-	struct TrimData {
-		int trim_pos = -1;
-		int ellipsis_pos = -1;
-		Vector<Glyph> ellipsis_glyph_buf;
-	};
-
-	struct ShapedTextData {
-		Mutex mutex;
-
-		/* Source data */
-		RID parent; // Substring parent ShapedTextData.
-
-		int start = 0; // Substring start offset in the parent string.
-		int end = 0; // Substring end offset in the parent string.
-
-		String text;
-		String custom_punct;
-		TextServer::Direction direction = DIRECTION_LTR; // Desired text direction.
-		TextServer::Orientation orientation = ORIENTATION_HORIZONTAL;
-
-		struct EmbeddedObject {
-			int pos = 0;
-			InlineAlignment inline_align = INLINE_ALIGNMENT_CENTER;
-			Rect2 rect;
-		};
-		Map<Variant, EmbeddedObject> objects;
-
-		/* Shaped data */
-		TextServer::Direction para_direction = DIRECTION_LTR; // Detected text direction.
-		bool valid = false; // String is shaped.
-		bool line_breaks_valid = false; // Line and word break flags are populated (and virtual zero width spaces inserted).
-		bool justification_ops_valid = false; // Virtual elongation glyphs are added to the string.
-		bool sort_valid = false;
-		bool text_trimmed = false;
-
-		bool preserve_invalid = true; // Draw hex code box instead of missing characters.
-		bool preserve_control = false; // Draw control characters.
-
-		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;
-
-		float upos = 0.f;
-		float uthk = 0.f;
-
-		TrimData overrun_trim_data;
-		bool fit_width_minimum_reached = false;
-
-		Vector<Glyph> glyphs;
-		Vector<Glyph> glyphs_logical;
-	};
-
 	Map<char32_t, char32_t> diacritics_map;
 	void _diacritics_map_add(const String &p_from, char32_t p_to);
 	void _init_diacritics_map();
@@ -207,10 +158,10 @@ protected:
 public:
 	virtual bool has_feature(Feature p_feature) const = 0;
 	virtual String get_name() const = 0;
-	virtual uint32_t get_features() const = 0;
+	virtual int64_t get_features() const = 0;
 
-	virtual void free(RID p_rid) = 0;
-	virtual bool has(RID p_rid) = 0;
+	virtual void free_rid(const RID &p_rid) = 0;
+	virtual bool has(const RID &p_rid) = 0;
 	virtual bool load_support_data(const String &p_filename) = 0;
 
 	virtual String get_support_data_filename() const = 0;
@@ -219,251 +170,251 @@ public:
 
 	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 ""; };
+	virtual int64_t name_to_tag(const String &p_name) const { return 0; };
+	virtual String tag_to_name(int64_t p_tag) const { return ""; };
 
 	/* Font interface */
 	virtual RID create_font() = 0;
 
-	virtual void font_set_data(RID p_font_rid, const PackedByteArray &p_data) = 0;
-	virtual void font_set_data_ptr(RID p_font_rid, const uint8_t *p_data_ptr, size_t p_data_size) = 0;
+	virtual void font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) = 0;
+	virtual void font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) = 0;
 
-	virtual void font_set_style(RID p_font_rid, uint32_t /*FontStyle*/ p_style) = 0;
-	virtual uint32_t /*FontStyle*/ font_get_style(RID p_font_rid) const = 0;
+	virtual void font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) = 0;
+	virtual int64_t /*FontStyle*/ font_get_style(const RID &p_font_rid) const = 0;
 
-	virtual void font_set_name(RID p_font_rid, const String &p_name) = 0;
-	virtual String font_get_name(RID p_font_rid) const = 0;
+	virtual void font_set_name(const RID &p_font_rid, const String &p_name) = 0;
+	virtual String font_get_name(const RID &p_font_rid) const = 0;
 
-	virtual void font_set_style_name(RID p_font_rid, const String &p_name) = 0;
-	virtual String font_get_style_name(RID p_font_rid) const = 0;
+	virtual void font_set_style_name(const RID &p_font_rid, const String &p_name) = 0;
+	virtual String font_get_style_name(const RID &p_font_rid) const = 0;
 
-	virtual void font_set_antialiased(RID p_font_rid, bool p_antialiased) = 0;
-	virtual bool font_is_antialiased(RID p_font_rid) const = 0;
+	virtual void font_set_antialiased(const RID &p_font_rid, bool p_antialiased) = 0;
+	virtual bool font_is_antialiased(const RID &p_font_rid) const = 0;
 
-	virtual void font_set_multichannel_signed_distance_field(RID p_font_rid, bool p_msdf) = 0;
-	virtual bool font_is_multichannel_signed_distance_field(RID p_font_rid) const = 0;
+	virtual void font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) = 0;
+	virtual bool font_is_multichannel_signed_distance_field(const RID &p_font_rid) const = 0;
 
-	virtual void font_set_msdf_pixel_range(RID p_font_rid, int p_msdf_pixel_range) = 0;
-	virtual int font_get_msdf_pixel_range(RID p_font_rid) const = 0;
+	virtual void font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) = 0;
+	virtual int64_t font_get_msdf_pixel_range(const RID &p_font_rid) const = 0;
 
-	virtual void font_set_msdf_size(RID p_font_rid, int p_msdf_size) = 0;
-	virtual int font_get_msdf_size(RID p_font_rid) const = 0;
+	virtual void font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) = 0;
+	virtual int64_t font_get_msdf_size(const RID &p_font_rid) const = 0;
 
-	virtual void font_set_fixed_size(RID p_font_rid, int p_fixed_size) = 0;
-	virtual int font_get_fixed_size(RID p_font_rid) const = 0;
+	virtual void font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) = 0;
+	virtual int64_t font_get_fixed_size(const RID &p_font_rid) const = 0;
 
-	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_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) = 0;
+	virtual bool font_is_force_autohinter(const 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_hinting(const RID &p_font_rid, Hinting p_hinting) = 0;
+	virtual Hinting font_get_hinting(const RID &p_font_rid) const = 0;
 
-	virtual void font_set_subpixel_positioning(RID p_font_rid, SubpixelPositioning p_subpixel) = 0;
-	virtual SubpixelPositioning font_get_subpixel_positioning(RID p_font_rid) const = 0;
+	virtual void font_set_subpixel_positioning(const RID &p_font_rid, SubpixelPositioning p_subpixel) = 0;
+	virtual SubpixelPositioning font_get_subpixel_positioning(const RID &p_font_rid) const = 0;
 
-	virtual void font_set_embolden(RID p_font_rid, float p_strength) = 0;
-	virtual float font_get_embolden(RID p_font_rid) const = 0;
+	virtual void font_set_embolden(const RID &p_font_rid, double p_strength) = 0;
+	virtual double font_get_embolden(const RID &p_font_rid) const = 0;
 
-	virtual void font_set_transform(RID p_font_rid, Transform2D p_transform) = 0;
-	virtual Transform2D font_get_transform(RID p_font_rid) const = 0;
+	virtual void font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) = 0;
+	virtual Transform2D font_get_transform(const 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_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) = 0;
+	virtual Dictionary font_get_variation_coordinates(const 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 void font_set_oversampling(const RID &p_font_rid, double p_oversampling) = 0;
+	virtual double font_get_oversampling(const 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 Array font_get_size_cache_list(const RID &p_font_rid) const = 0;
+	virtual void font_clear_size_cache(const RID &p_font_rid) = 0;
+	virtual void font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) = 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_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) = 0;
+	virtual double font_get_ascent(const RID &p_font_rid, int64_t 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_descent(const RID &p_font_rid, int64_t p_size, double p_descent) = 0;
+	virtual double font_get_descent(const RID &p_font_rid, int64_t 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_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) = 0;
+	virtual double font_get_underline_position(const RID &p_font_rid, int64_t 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_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) = 0;
+	virtual double font_get_underline_thickness(const RID &p_font_rid, int64_t 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_scale(const RID &p_font_rid, int64_t p_size, double p_scale) = 0;
+	virtual double font_get_scale(const RID &p_font_rid, int64_t 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;
+	virtual void font_set_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing, int64_t p_value) = 0;
+	virtual int64_t font_get_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing) const = 0;
 
-	virtual int font_get_texture_count(RID p_font_rid, const Vector2i &p_size) const = 0;
-	virtual void font_clear_textures(RID p_font_rid, const Vector2i &p_size) = 0;
-	virtual void font_remove_texture(RID p_font_rid, const Vector2i &p_size, int p_texture_index) = 0;
+	virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const = 0;
+	virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) = 0;
+	virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) = 0;
 
-	virtual void font_set_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const Ref<Image> &p_image) = 0;
-	virtual Ref<Image> font_get_texture_image(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const = 0;
+	virtual void font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) = 0;
+	virtual Ref<Image> font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const = 0;
 
-	virtual void font_set_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index, const PackedInt32Array &p_offset) = 0;
-	virtual PackedInt32Array font_get_texture_offsets(RID p_font_rid, const Vector2i &p_size, int p_texture_index) const = 0;
+	virtual void font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) = 0;
+	virtual PackedInt32Array font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const = 0;
 
-	virtual Array font_get_glyph_list(RID p_font_rid, const Vector2i &p_size) const = 0;
-	virtual void font_clear_glyphs(RID p_font_rid, const Vector2i &p_size) = 0;
-	virtual void font_remove_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) = 0;
+	virtual Array font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const = 0;
+	virtual void font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) = 0;
+	virtual void font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) = 0;
 
-	virtual Vector2 font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const = 0;
-	virtual void font_set_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph, const Vector2 &p_advance) = 0;
+	virtual Vector2 font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const = 0;
+	virtual void font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) = 0;
 
-	virtual Vector2 font_get_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const = 0;
-	virtual void font_set_glyph_offset(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_offset) = 0;
+	virtual Vector2 font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const = 0;
+	virtual void font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) = 0;
 
-	virtual Vector2 font_get_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const = 0;
-	virtual void font_set_glyph_size(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Vector2 &p_gl_size) = 0;
+	virtual Vector2 font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const = 0;
+	virtual void font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) = 0;
 
-	virtual Rect2 font_get_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph) const = 0;
-	virtual void font_set_glyph_uv_rect(RID p_font_rid, const Vector2i &p_size, int32_t p_glyph, const Rect2 &p_uv_rect) = 0;
+	virtual Rect2 font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const = 0;
+	virtual void font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) = 0;
 
-	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 int64_t font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const = 0;
+	virtual void font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) = 0;
 
-	virtual Dictionary font_get_glyph_contours(RID p_font, int p_size, int32_t p_index) const = 0;
+	virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_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;
-	virtual void font_remove_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) = 0;
+	virtual Array font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const = 0;
+	virtual void font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) = 0;
+	virtual void font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) = 0;
 
-	virtual void font_set_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) = 0;
-	virtual Vector2 font_get_kerning(RID p_font_rid, int p_size, const Vector2i &p_glyph_pair) const = 0;
+	virtual void font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) = 0;
+	virtual Vector2 font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const = 0;
 
-	virtual int32_t font_get_glyph_index(RID p_font_rid, int p_size, char32_t p_char, char32_t p_variation_selector) const = 0;
+	virtual int64_t font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector) const = 0;
 
-	virtual bool font_has_char(RID p_font_rid, char32_t p_char) const = 0;
-	virtual String font_get_supported_chars(RID p_font_rid) const = 0;
+	virtual bool font_has_char(const RID &p_font_rid, int64_t p_char) const = 0;
+	virtual String font_get_supported_chars(const RID &p_font_rid) const = 0;
 
-	virtual void font_render_range(RID p_font, const Vector2i &p_size, char32_t p_start, char32_t p_end) = 0;
-	virtual void font_render_glyph(RID p_font_rid, const Vector2i &p_size, int32_t p_index) = 0;
+	virtual void font_render_range(const RID &p_font, const Vector2i &p_size, int64_t p_start, int64_t p_end) = 0;
+	virtual void font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) = 0;
 
-	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 = 0;
-	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 = 0;
+	virtual void font_draw_glyph(const RID &p_font, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const = 0;
+	virtual void font_draw_glyph_outline(const RID &p_font, const RID &p_canvas, int64_t p_size, int64_t p_outline_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color = Color(1, 1, 1)) const = 0;
 
-	virtual bool font_is_language_supported(RID p_font_rid, const String &p_language) const = 0;
-	virtual void font_set_language_support_override(RID p_font_rid, const String &p_language, bool p_supported) = 0;
-	virtual bool font_get_language_support_override(RID p_font_rid, const String &p_language) = 0;
-	virtual void font_remove_language_support_override(RID p_font_rid, const String &p_language) = 0;
-	virtual Vector<String> font_get_language_support_overrides(RID p_font_rid) = 0;
+	virtual bool font_is_language_supported(const RID &p_font_rid, const String &p_language) const = 0;
+	virtual void font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) = 0;
+	virtual bool font_get_language_support_override(const RID &p_font_rid, const String &p_language) = 0;
+	virtual void font_remove_language_support_override(const RID &p_font_rid, const String &p_language) = 0;
+	virtual PackedStringArray font_get_language_support_overrides(const RID &p_font_rid) = 0;
 
-	virtual bool font_is_script_supported(RID p_font_rid, const String &p_script) const = 0;
-	virtual void font_set_script_support_override(RID p_font_rid, const String &p_script, bool p_supported) = 0;
-	virtual bool font_get_script_support_override(RID p_font_rid, const String &p_script) = 0;
-	virtual void font_remove_script_support_override(RID p_font_rid, const String &p_script) = 0;
-	virtual Vector<String> font_get_script_support_overrides(RID p_font_rid) = 0;
+	virtual bool font_is_script_supported(const RID &p_font_rid, const String &p_script) const = 0;
+	virtual void font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) = 0;
+	virtual bool font_get_script_support_override(const RID &p_font_rid, const String &p_script) = 0;
+	virtual void font_remove_script_support_override(const RID &p_font_rid, const String &p_script) = 0;
+	virtual PackedStringArray font_get_script_support_overrides(const RID &p_font_rid) = 0;
 
-	virtual void font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) = 0;
-	virtual Dictionary font_get_opentype_feature_overrides(RID p_font_rid) const = 0;
+	virtual void font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) = 0;
+	virtual Dictionary font_get_opentype_feature_overrides(const RID &p_font_rid) const = 0;
 
-	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 Dictionary font_supported_feature_list(const RID &p_font_rid) const = 0;
+	virtual Dictionary font_supported_variation_list(const RID &p_font_rid) const = 0;
 
-	virtual float font_get_global_oversampling() const = 0;
-	virtual void font_set_global_oversampling(float p_oversampling) = 0;
+	virtual double font_get_global_oversampling() const = 0;
+	virtual void font_set_global_oversampling(double p_oversampling) = 0;
 
-	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;
+	virtual Vector2 get_hex_code_box_size(int64_t p_size, int64_t p_index) const;
+	virtual void draw_hex_code_box(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const;
 
 	/* Shaped text buffer interface */
 
 	virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) = 0;
 
-	virtual void shaped_text_clear(RID p_shaped) = 0;
+	virtual void shaped_text_clear(const RID &p_shaped) = 0;
 
-	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 Direction shaped_text_get_inferred_direction(RID p_shaped) const = 0;
+	virtual void shaped_text_set_direction(const RID &p_shaped, Direction p_direction = DIRECTION_AUTO) = 0;
+	virtual Direction shaped_text_get_direction(const RID &p_shaped) const = 0;
+	virtual Direction shaped_text_get_inferred_direction(const RID &p_shaped) const = 0;
 
-	virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) = 0;
+	virtual void shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) = 0;
 
-	virtual void shaped_text_set_custom_punctuation(RID p_shaped, const String &p_punct) = 0;
-	virtual String shaped_text_get_custom_punctuation(RID p_shaped) const = 0;
+	virtual void shaped_text_set_custom_punctuation(const RID &p_shaped, const String &p_punct) = 0;
+	virtual String shaped_text_get_custom_punctuation(const RID &p_shaped) const = 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;
+	virtual void shaped_text_set_orientation(const RID &p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) = 0;
+	virtual Orientation shaped_text_get_orientation(const RID &p_shaped) const = 0;
 
-	virtual void shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) = 0;
-	virtual bool shaped_text_get_preserve_invalid(RID p_shaped) const = 0;
+	virtual void shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) = 0;
+	virtual bool shaped_text_get_preserve_invalid(const RID &p_shaped) const = 0;
 
-	virtual void shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) = 0;
-	virtual bool shaped_text_get_preserve_control(RID p_shaped) const = 0;
+	virtual void shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) = 0;
+	virtual bool shaped_text_get_preserve_control(const RID &p_shaped) const = 0;
 
-	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 = "", const Variant &p_meta = Variant()) = 0;
-	virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) = 0;
-	virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) = 0;
+	virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) = 0;
+	virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) = 0;
+	virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) = 0;
 
-	virtual int shaped_get_span_count(RID p_shaped) const = 0;
-	virtual Variant shaped_get_span_meta(RID p_shaped, int p_index) const = 0;
-	virtual void shaped_set_span_update_font(RID p_shaped, int p_index, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary()) = 0;
+	virtual int64_t shaped_get_span_count(const RID &p_shaped) const = 0;
+	virtual Variant shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const = 0;
+	virtual void shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) = 0;
 
-	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 RID shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const = 0; // Copy shaped substring (e.g. line break) without reshaping, but correctly reordered, preservers range.
+	virtual RID shaped_text_get_parent(const RID &p_shaped) const = 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 double shaped_text_fit_to_width(const RID &p_shaped, double p_width, int64_t /*JustificationFlag*/ p_jst_flags = JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA) = 0;
+	virtual double shaped_text_tab_align(const 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;
-	virtual bool shaped_text_update_justification_ops(RID p_shaped) = 0;
+	virtual bool shaped_text_shape(const RID &p_shaped) = 0;
+	virtual bool shaped_text_update_breaks(const RID &p_shaped) = 0;
+	virtual bool shaped_text_update_justification_ops(const RID &p_shaped) = 0;
 
-	virtual bool shaped_text_is_ready(RID p_shaped) const = 0;
+	virtual bool shaped_text_is_ready(const 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 const Glyph *shaped_text_get_glyphs(const RID &p_shaped) const = 0;
+	Array _shaped_text_get_glyphs_wrapper(const RID &p_shaped) const;
+	virtual const Glyph *shaped_text_sort_logical(const RID &p_shaped) = 0;
+	Array _shaped_text_sort_logical_wrapper(const RID &p_shaped);
+	virtual int64_t shaped_text_get_glyph_count(const RID &p_shaped) const = 0;
 
-	virtual Vector2i shaped_text_get_range(RID p_shaped) const = 0;
+	virtual Vector2i shaped_text_get_range(const RID &p_shaped) const = 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 PackedInt32Array shaped_text_get_line_breaks_adv(const RID &p_shaped, const PackedFloat32Array &p_width, int64_t p_start = 0, bool p_once = true, int64_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
+	virtual PackedInt32Array shaped_text_get_line_breaks(const RID &p_shaped, double p_width, int64_t p_start = 0, int64_t /*TextBreakFlag*/ p_break_flags = BREAK_MANDATORY | BREAK_WORD_BOUND) const;
+	virtual PackedInt32Array shaped_text_get_word_breaks(const RID &p_shaped, int64_t 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 int64_t shaped_text_get_trim_pos(const RID &p_shaped) const = 0;
+	virtual int64_t shaped_text_get_ellipsis_pos(const RID &p_shaped) const = 0;
+	virtual const Glyph *shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const = 0;
+	Array _shaped_text_get_ellipsis_glyphs_wrapper(const RID &p_shaped) const;
+	virtual int64_t shaped_text_get_ellipsis_glyph_count(const 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 void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, int64_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 Array shaped_text_get_objects(const RID &p_shaped) const = 0;
+	virtual Rect2 shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const = 0;
 
-	virtual Size2 shaped_text_get_size(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 Size2 shaped_text_get_size(const RID &p_shaped) const = 0;
+	virtual double shaped_text_get_ascent(const RID &p_shaped) const = 0;
+	virtual double shaped_text_get_descent(const RID &p_shaped) const = 0;
+	virtual double shaped_text_get_width(const RID &p_shaped) const = 0;
+	virtual double shaped_text_get_underline_position(const RID &p_shaped) const = 0;
+	virtual double shaped_text_get_underline_thickness(const 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_direction_in_range(const RID &p_shaped, int64_t p_start, int64_t 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 CaretInfo shaped_text_get_carets(const RID &p_shaped, int64_t p_position) const;
+	Dictionary _shaped_text_get_carets_wrapper(const RID &p_shaped, int64_t p_position) const;
 
-	virtual Vector<Vector2> shaped_text_get_selection(RID p_shaped, int p_start, int p_end) const;
+	virtual Vector<Vector2> shaped_text_get_selection(const RID &p_shaped, int64_t p_start, int64_t p_end) const;
 
-	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 int64_t shaped_text_hit_test_grapheme(const RID &p_shaped, double p_coords) const; // Return grapheme index.
+	virtual int64_t shaped_text_hit_test_position(const RID &p_shaped, double p_coords) const; // Return caret/selection position.
 
-	virtual Vector2 shaped_text_get_grapheme_bounds(RID p_shaped, int p_pos) const;
-	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;
+	virtual Vector2 shaped_text_get_grapheme_bounds(const RID &p_shaped, int64_t p_pos) const;
+	virtual int64_t shaped_text_next_grapheme_pos(const RID &p_shaped, int64_t p_pos) const;
+	virtual int64_t shaped_text_prev_grapheme_pos(const RID &p_shaped, int64_t 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, 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;
+	virtual void shaped_text_draw(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, const Color &p_color = Color(1, 1, 1)) const;
+	virtual void shaped_text_draw_outline(const RID &p_shaped, const RID &p_canvas, const Vector2 &p_pos, double p_clip_l = -1.0, double p_clip_r = -1.0, int64_t 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 "%"; };
+	virtual String format_number(const String &p_string, const String &p_language = "") const = 0;
+	virtual String parse_number(const String &p_string, const String &p_language = "") const = 0;
+	virtual String percent_sign(const String &p_language = "") const = 0;
 
 	virtual String strip_diacritics(const String &p_string) const;
 
@@ -507,23 +458,6 @@ struct CaretInfo {
 	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;
-		}
-	}
-};
-
 /*************************************************************************/
 
 class TextServerManager : public Object {

+ 0 - 4
tests/core/object/test_class_db.h

@@ -671,10 +671,6 @@ void add_exposed_classes(Context &r_context) {
 			} else {
 				exposed_class.methods.push_back(method);
 			}
-
-			if (method.is_virtual) {
-				TEST_COND(String(method.name)[0] != '_', "Virtual method ", String(method.name), " does not start with underscore.");
-			}
 		}
 
 		// Add signals

+ 285 - 281
tests/scene/test_code_edit.h

@@ -2901,291 +2901,293 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
 	}
 
 	SUBCASE("[CodeEdit] autocomplete completion") {
-		CHECK(code_edit->get_code_completion_selected_index() == -1);
-		code_edit->set_code_completion_enabled(true);
-		CHECK(code_edit->get_code_completion_selected_index() == -1);
-
-		code_edit->update_code_completion_options();
-		code_edit->set_code_completion_selected_index(1);
-		CHECK(code_edit->get_code_completion_selected_index() == -1);
-		CHECK(code_edit->get_code_completion_option(0).size() == 0);
-		CHECK(code_edit->get_code_completion_options().size() == 0);
-
-		/* Adding does not update the list. */
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_0.", "item_0");
-
-		code_edit->set_code_completion_selected_index(1);
-		CHECK(code_edit->get_code_completion_selected_index() == -1);
-		CHECK(code_edit->get_code_completion_option(0).size() == 0);
-		CHECK(code_edit->get_code_completion_options().size() == 0);
-
-		/* After update, pending add should not be counted, */
-		/* also does not work on col 0                      */
-		code_edit->insert_text_at_caret("i");
-		code_edit->update_code_completion_options();
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0", Color(1, 0, 0), RES(), Color(1, 0, 0));
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_1.", "item_1");
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_2.", "item_2");
-
-		ERR_PRINT_OFF;
-		code_edit->set_code_completion_selected_index(1);
-		ERR_PRINT_ON;
-		CHECK(code_edit->get_code_completion_selected_index() == 0);
-		CHECK(code_edit->get_code_completion_option(0).size() == 6);
-		CHECK(code_edit->get_code_completion_options().size() == 1);
-
-		/* Check cancel closes completion. */
-		SEND_GUI_ACTION(code_edit, "ui_cancel");
-		CHECK(code_edit->get_code_completion_selected_index() == -1);
-
-		code_edit->update_code_completion_options();
-		CHECK(code_edit->get_code_completion_selected_index() == 0);
-		code_edit->set_code_completion_selected_index(1);
-		CHECK(code_edit->get_code_completion_selected_index() == 1);
-		CHECK(code_edit->get_code_completion_option(0).size() == 6);
-		CHECK(code_edit->get_code_completion_options().size() == 3);
-
-		/* Check data. */
-		Dictionary option = code_edit->get_code_completion_option(0);
-		CHECK((int)option["kind"] == (int)CodeEdit::CodeCompletionKind::KIND_CLASS);
-		CHECK(option["display_text"] == "item_0.");
-		CHECK(option["insert_text"] == "item_0");
-		CHECK(option["font_color"] == Color(1, 0, 0));
-		CHECK(option["icon"] == RES());
-		CHECK(option["default_value"] == Color(1, 0, 0));
-
-		/* Set size for mouse input. */
-		code_edit->set_size(Size2(100, 100));
-
-		/* Check input. */
-		SEND_GUI_ACTION(code_edit, "ui_end");
-		CHECK(code_edit->get_code_completion_selected_index() == 2);
-
-		SEND_GUI_ACTION(code_edit, "ui_home");
-		CHECK(code_edit->get_code_completion_selected_index() == 0);
-
-		SEND_GUI_ACTION(code_edit, "ui_page_down");
-		CHECK(code_edit->get_code_completion_selected_index() == 2);
-
-		SEND_GUI_ACTION(code_edit, "ui_page_up");
-		CHECK(code_edit->get_code_completion_selected_index() == 0);
-
-		SEND_GUI_ACTION(code_edit, "ui_up");
-		CHECK(code_edit->get_code_completion_selected_index() == 2);
-
-		SEND_GUI_ACTION(code_edit, "ui_down");
-		CHECK(code_edit->get_code_completion_selected_index() == 0);
-
-		SEND_GUI_KEY_EVENT(code_edit, Key::T);
-		CHECK(code_edit->get_code_completion_selected_index() == 0);
-
-		SEND_GUI_ACTION(code_edit, "ui_left");
-		CHECK(code_edit->get_code_completion_selected_index() == 0);
-
-		SEND_GUI_ACTION(code_edit, "ui_right");
-		CHECK(code_edit->get_code_completion_selected_index() == 0);
-
-		SEND_GUI_ACTION(code_edit, "ui_text_backspace");
-		CHECK(code_edit->get_code_completion_selected_index() == 0);
+		if (TS->has_feature(TextServer::FEATURE_FONT_DYNAMIC) && TS->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) {
+			CHECK(code_edit->get_code_completion_selected_index() == -1);
+			code_edit->set_code_completion_enabled(true);
+			CHECK(code_edit->get_code_completion_selected_index() == -1);
+
+			code_edit->update_code_completion_options();
+			code_edit->set_code_completion_selected_index(1);
+			CHECK(code_edit->get_code_completion_selected_index() == -1);
+			CHECK(code_edit->get_code_completion_option(0).size() == 0);
+			CHECK(code_edit->get_code_completion_options().size() == 0);
+
+			/* Adding does not update the list. */
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_0.", "item_0");
+
+			code_edit->set_code_completion_selected_index(1);
+			CHECK(code_edit->get_code_completion_selected_index() == -1);
+			CHECK(code_edit->get_code_completion_option(0).size() == 0);
+			CHECK(code_edit->get_code_completion_options().size() == 0);
+
+			/* After update, pending add should not be counted, */
+			/* also does not work on col 0                      */
+			code_edit->insert_text_at_caret("i");
+			code_edit->update_code_completion_options();
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0", Color(1, 0, 0), RES(), Color(1, 0, 0));
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_1.", "item_1");
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_VARIABLE, "item_2.", "item_2");
 
-		Point2 caret_pos = code_edit->get_caret_draw_pos();
-		caret_pos.y -= code_edit->get_line_height();
-		SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::WHEEL_DOWN, MouseButton::NONE);
-		CHECK(code_edit->get_code_completion_selected_index() == 1);
-
-		SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::WHEEL_UP, MouseButton::NONE);
-		CHECK(code_edit->get_code_completion_selected_index() == 0);
-
-		/* Single click selects. */
-		SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::LEFT, MouseButton::MASK_LEFT);
-		CHECK(code_edit->get_code_completion_selected_index() == 2);
-
-		/* Double click inserts. */
-		SEND_GUI_DOUBLE_CLICK(code_edit, caret_pos);
-		CHECK(code_edit->get_code_completion_selected_index() == -1);
-		CHECK(code_edit->get_line(0) == "item_2");
+			ERR_PRINT_OFF;
+			code_edit->set_code_completion_selected_index(1);
+			ERR_PRINT_ON;
+			CHECK(code_edit->get_code_completion_selected_index() == 0);
+			CHECK(code_edit->get_code_completion_option(0).size() == 6);
+			CHECK(code_edit->get_code_completion_options().size() == 1);
 
-		code_edit->set_auto_brace_completion_enabled(false);
+			/* Check cancel closes completion. */
+			SEND_GUI_ACTION(code_edit, "ui_cancel");
+			CHECK(code_edit->get_code_completion_selected_index() == -1);
 
-		/* Does nothing in readonly. */
-		code_edit->undo();
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
-		code_edit->update_code_completion_options();
-		code_edit->set_editable(false);
-		code_edit->confirm_code_completion();
-		code_edit->set_editable(true);
-		CHECK(code_edit->get_line(0) == "i");
+			code_edit->update_code_completion_options();
+			CHECK(code_edit->get_code_completion_selected_index() == 0);
+			code_edit->set_code_completion_selected_index(1);
+			CHECK(code_edit->get_code_completion_selected_index() == 1);
+			CHECK(code_edit->get_code_completion_option(0).size() == 6);
+			CHECK(code_edit->get_code_completion_options().size() == 3);
 
-		/* Replace */
-		code_edit->clear();
-		code_edit->insert_text_at_caret("item_1 test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "item_0 test");
+			/* Check data. */
+			Dictionary option = code_edit->get_code_completion_option(0);
+			CHECK((int)option["kind"] == (int)CodeEdit::CodeCompletionKind::KIND_CLASS);
+			CHECK(option["display_text"] == "item_0.");
+			CHECK(option["insert_text"] == "item_0");
+			CHECK(option["font_color"] == Color(1, 0, 0));
+			CHECK(option["icon"] == RES());
+			CHECK(option["default_value"] == Color(1, 0, 0));
 
-		/* Replace string. */
-		code_edit->clear();
-		code_edit->insert_text_at_caret("\"item_1 test\"");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "\"item_0\"");
+			/* Set size for mouse input. */
+			code_edit->set_size(Size2(100, 100));
 
-		/* Normal replace if no end is given. */
-		code_edit->clear();
-		code_edit->insert_text_at_caret("\"item_1 test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "\"item_0\" test");
+			/* Check input. */
+			SEND_GUI_ACTION(code_edit, "ui_end");
+			CHECK(code_edit->get_code_completion_selected_index() == 2);
 
-		/* Insert at completion. */
-		code_edit->clear();
-		code_edit->insert_text_at_caret("item_1 test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_accept");
-		CHECK(code_edit->get_line(0) == "item_01 test");
+			SEND_GUI_ACTION(code_edit, "ui_home");
+			CHECK(code_edit->get_code_completion_selected_index() == 0);
 
-		/* Insert at completion with string should have same output. */
-		code_edit->clear();
-		code_edit->insert_text_at_caret("\"item_1 test\"");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_accept");
-		CHECK(code_edit->get_line(0) == "\"item_0\"1 test\"");
+			SEND_GUI_ACTION(code_edit, "ui_page_down");
+			CHECK(code_edit->get_code_completion_selected_index() == 2);
 
-		/* Merge symbol at end on insert text. */
-		/* End on completion entry. */
-		code_edit->clear();
-		code_edit->insert_text_at_caret("item_1 test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0(", "item_0(");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "item_0( test");
-		CHECK(code_edit->get_caret_column() == 7);
+			SEND_GUI_ACTION(code_edit, "ui_page_up");
+			CHECK(code_edit->get_code_completion_selected_index() == 0);
 
-		/* End of text*/
-		code_edit->clear();
-		code_edit->insert_text_at_caret("item_1( test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0", "item_0");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "item_0( test");
-		CHECK(code_edit->get_caret_column() == 6);
+			SEND_GUI_ACTION(code_edit, "ui_up");
+			CHECK(code_edit->get_code_completion_selected_index() == 2);
 
-		/* End of both. */
-		code_edit->clear();
-		code_edit->insert_text_at_caret("item_1( test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0(", "item_0(");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "item_0( test");
-		CHECK(code_edit->get_caret_column() == 7);
+			SEND_GUI_ACTION(code_edit, "ui_down");
+			CHECK(code_edit->get_code_completion_selected_index() == 0);
 
-		/* Full set. */
-		/* End on completion entry. */
-		code_edit->clear();
-		code_edit->insert_text_at_caret("item_1 test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0()", "item_0()");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "item_0() test");
-		CHECK(code_edit->get_caret_column() == 8);
+			SEND_GUI_KEY_EVENT(code_edit, Key::T);
+			CHECK(code_edit->get_code_completion_selected_index() == 0);
 
-		/* End of text*/
-		code_edit->clear();
-		code_edit->insert_text_at_caret("item_1() test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0", "item_0");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "item_0() test");
-		CHECK(code_edit->get_caret_column() == 6);
+			SEND_GUI_ACTION(code_edit, "ui_left");
+			CHECK(code_edit->get_code_completion_selected_index() == 0);
 
-		/* End of both. */
-		code_edit->clear();
-		code_edit->insert_text_at_caret("item_1() test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0()", "item_0()");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "item_0() test");
-		CHECK(code_edit->get_caret_column() == 8);
+			SEND_GUI_ACTION(code_edit, "ui_right");
+			CHECK(code_edit->get_code_completion_selected_index() == 0);
 
-		/* Autobrace completion. */
-		code_edit->set_auto_brace_completion_enabled(true);
+			SEND_GUI_ACTION(code_edit, "ui_text_backspace");
+			CHECK(code_edit->get_code_completion_selected_index() == 0);
 
-		/* End on completion entry. */
-		code_edit->clear();
-		code_edit->insert_text_at_caret("item_1 test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0(", "item_0(");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "item_0() test");
-		CHECK(code_edit->get_caret_column() == 7);
+			Point2 caret_pos = code_edit->get_caret_draw_pos();
+			caret_pos.y -= code_edit->get_line_height();
+			SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::WHEEL_DOWN, MouseButton::NONE);
+			CHECK(code_edit->get_code_completion_selected_index() == 1);
 
-		/* End of text*/
-		code_edit->clear();
-		code_edit->insert_text_at_caret("item_1( test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0", "item_0");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "item_0( test");
-		CHECK(code_edit->get_caret_column() == 6);
+			SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::WHEEL_UP, MouseButton::NONE);
+			CHECK(code_edit->get_code_completion_selected_index() == 0);
 
-		/* End of both. */
-		code_edit->clear();
-		code_edit->insert_text_at_caret("item_1( test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0(", "item_0(");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "item_0( test");
-		CHECK(code_edit->get_caret_column() == 7);
+			/* Single click selects. */
+			SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::LEFT, MouseButton::MASK_LEFT);
+			CHECK(code_edit->get_code_completion_selected_index() == 2);
 
-		/* Full set. */
-		/* End on completion entry. */
-		code_edit->clear();
-		code_edit->insert_text_at_caret("item_1 test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0()", "item_0()");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "item_0() test");
-		CHECK(code_edit->get_caret_column() == 8);
+			/* Double click inserts. */
+			SEND_GUI_DOUBLE_CLICK(code_edit, caret_pos);
+			CHECK(code_edit->get_code_completion_selected_index() == -1);
+			CHECK(code_edit->get_line(0) == "item_2");
 
-		/* End of text*/
-		code_edit->clear();
-		code_edit->insert_text_at_caret("item_1() test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0", "item_0");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "item_0() test");
-		CHECK(code_edit->get_caret_column() == 6);
+			code_edit->set_auto_brace_completion_enabled(false);
 
-		/* End of both. */
-		code_edit->clear();
-		code_edit->insert_text_at_caret("item_1() test");
-		code_edit->set_caret_column(2);
-		code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0()", "item_0()");
-		code_edit->update_code_completion_options();
-		SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
-		CHECK(code_edit->get_line(0) == "item_0() test");
-		CHECK(code_edit->get_caret_column() == 8);
+			/* Does nothing in readonly. */
+			code_edit->undo();
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
+			code_edit->update_code_completion_options();
+			code_edit->set_editable(false);
+			code_edit->confirm_code_completion();
+			code_edit->set_editable(true);
+			CHECK(code_edit->get_line(0) == "i");
+
+			/* Replace */
+			code_edit->clear();
+			code_edit->insert_text_at_caret("item_1 test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "item_0 test");
+
+			/* Replace string. */
+			code_edit->clear();
+			code_edit->insert_text_at_caret("\"item_1 test\"");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "\"item_0\"");
+
+			/* Normal replace if no end is given. */
+			code_edit->clear();
+			code_edit->insert_text_at_caret("\"item_1 test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "\"item_0\" test");
+
+			/* Insert at completion. */
+			code_edit->clear();
+			code_edit->insert_text_at_caret("item_1 test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_accept");
+			CHECK(code_edit->get_line(0) == "item_01 test");
+
+			/* Insert at completion with string should have same output. */
+			code_edit->clear();
+			code_edit->insert_text_at_caret("\"item_1 test\"");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0.", "item_0");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_accept");
+			CHECK(code_edit->get_line(0) == "\"item_0\"1 test\"");
+
+			/* Merge symbol at end on insert text. */
+			/* End on completion entry. */
+			code_edit->clear();
+			code_edit->insert_text_at_caret("item_1 test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0(", "item_0(");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "item_0( test");
+			CHECK(code_edit->get_caret_column() == 7);
+
+			/* End of text*/
+			code_edit->clear();
+			code_edit->insert_text_at_caret("item_1( test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0", "item_0");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "item_0( test");
+			CHECK(code_edit->get_caret_column() == 6);
+
+			/* End of both. */
+			code_edit->clear();
+			code_edit->insert_text_at_caret("item_1( test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0(", "item_0(");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "item_0( test");
+			CHECK(code_edit->get_caret_column() == 7);
+
+			/* Full set. */
+			/* End on completion entry. */
+			code_edit->clear();
+			code_edit->insert_text_at_caret("item_1 test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0()", "item_0()");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "item_0() test");
+			CHECK(code_edit->get_caret_column() == 8);
+
+			/* End of text*/
+			code_edit->clear();
+			code_edit->insert_text_at_caret("item_1() test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0", "item_0");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "item_0() test");
+			CHECK(code_edit->get_caret_column() == 6);
+
+			/* End of both. */
+			code_edit->clear();
+			code_edit->insert_text_at_caret("item_1() test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0()", "item_0()");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "item_0() test");
+			CHECK(code_edit->get_caret_column() == 8);
+
+			/* Autobrace completion. */
+			code_edit->set_auto_brace_completion_enabled(true);
+
+			/* End on completion entry. */
+			code_edit->clear();
+			code_edit->insert_text_at_caret("item_1 test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0(", "item_0(");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "item_0() test");
+			CHECK(code_edit->get_caret_column() == 7);
+
+			/* End of text*/
+			code_edit->clear();
+			code_edit->insert_text_at_caret("item_1( test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0", "item_0");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "item_0( test");
+			CHECK(code_edit->get_caret_column() == 6);
+
+			/* End of both. */
+			code_edit->clear();
+			code_edit->insert_text_at_caret("item_1( test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0(", "item_0(");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "item_0( test");
+			CHECK(code_edit->get_caret_column() == 7);
+
+			/* Full set. */
+			/* End on completion entry. */
+			code_edit->clear();
+			code_edit->insert_text_at_caret("item_1 test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0()", "item_0()");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "item_0() test");
+			CHECK(code_edit->get_caret_column() == 8);
+
+			/* End of text*/
+			code_edit->clear();
+			code_edit->insert_text_at_caret("item_1() test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0", "item_0");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "item_0() test");
+			CHECK(code_edit->get_caret_column() == 6);
+
+			/* End of both. */
+			code_edit->clear();
+			code_edit->insert_text_at_caret("item_1() test");
+			code_edit->set_caret_column(2);
+			code_edit->add_code_completion_option(CodeEdit::CodeCompletionKind::KIND_CLASS, "item_0()", "item_0()");
+			code_edit->update_code_completion_options();
+			SEND_GUI_ACTION(code_edit, "ui_text_completion_replace");
+			CHECK(code_edit->get_line(0) == "item_0() test");
+			CHECK(code_edit->get_caret_column() == 8);
+		}
 	}
 
 	memdelete(code_edit);
@@ -3198,33 +3200,35 @@ TEST_CASE("[SceneTree][CodeEdit] symbol lookup") {
 	code_edit->set_symbol_lookup_on_click_enabled(true);
 	CHECK(code_edit->is_symbol_lookup_on_click_enabled());
 
-	/* Set size for mouse input. */
-	code_edit->set_size(Size2(100, 100));
+	if (TS->has_feature(TextServer::FEATURE_FONT_DYNAMIC) && TS->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) {
+		/* Set size for mouse input. */
+		code_edit->set_size(Size2(100, 100));
 
-	code_edit->set_text("this is some text");
+		code_edit->set_text("this is some text");
 
-	Point2 caret_pos = code_edit->get_caret_draw_pos();
-	caret_pos.x += 58;
-	SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::NONE, MouseButton::NONE);
-	CHECK(code_edit->get_text_for_symbol_lookup() == "this is s" + String::chr(0xFFFF) + "ome text");
+		Point2 caret_pos = code_edit->get_caret_draw_pos();
+		caret_pos.x += 58;
+		SEND_GUI_MOUSE_EVENT(code_edit, caret_pos, MouseButton::NONE, MouseButton::NONE);
+		CHECK(code_edit->get_text_for_symbol_lookup() == "this is s" + String::chr(0xFFFF) + "ome text");
 
-	SIGNAL_WATCH(code_edit, "symbol_validate");
+		SIGNAL_WATCH(code_edit, "symbol_validate");
 
 #ifdef OSX_ENABLED
-	SEND_GUI_KEY_EVENT(code_edit, Key::META);
+		SEND_GUI_KEY_EVENT(code_edit, Key::META);
 #else
-	SEND_GUI_KEY_EVENT(code_edit, Key::CTRL);
+		SEND_GUI_KEY_EVENT(code_edit, Key::CTRL);
 #endif
 
-	Array signal_args;
-	Array arg;
-	arg.push_back("some");
-	signal_args.push_back(arg);
-	SIGNAL_CHECK("symbol_validate", signal_args);
+		Array signal_args;
+		Array arg;
+		arg.push_back("some");
+		signal_args.push_back(arg);
+		SIGNAL_CHECK("symbol_validate", signal_args);
 
-	SIGNAL_UNWATCH(code_edit, "symbol_validate");
+		SIGNAL_UNWATCH(code_edit, "symbol_validate");
 
-	memdelete(code_edit);
+		memdelete(code_edit);
+	}
 }
 
 TEST_CASE("[SceneTree][CodeEdit] line length guidelines") {

+ 43 - 23
tests/servers/test_text_server.h

@@ -46,10 +46,14 @@ TEST_SUITE("[[TextServer]") {
 				Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
 				TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
 
+				if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC)) {
+					continue;
+				}
+
 				RID font = ts->create_font();
 				ts->font_set_data_ptr(font, _font_NotoSans_Regular, _font_NotoSans_Regular_size);
 				TEST_FAIL_COND(font == RID(), "Loading font failed.");
-				ts->free(font);
+				ts->free_rid(font);
 			}
 		}
 
@@ -58,12 +62,16 @@ TEST_SUITE("[[TextServer]") {
 				Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
 				TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
 
+				if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) {
+					continue;
+				}
+
 				RID font1 = ts->create_font();
 				ts->font_set_data_ptr(font1, _font_NotoSans_Regular, _font_NotoSans_Regular_size);
 				RID font2 = ts->create_font();
 				ts->font_set_data_ptr(font2, _font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size);
 
-				Vector<RID> font;
+				Array font;
 				font.push_back(font1);
 				font.push_back(font2);
 
@@ -93,10 +101,10 @@ TEST_SUITE("[[TextServer]") {
 					TEST_FAIL_COND(glyphs[j].font_size != 16, "Incorrect glyph font size.");
 				}
 
-				ts->free(ctx);
+				ts->free_rid(ctx);
 
 				for (int j = 0; j < font.size(); j++) {
-					ts->free(font[j]);
+					ts->free_rid(font[j]);
 				}
 				font.clear();
 			}
@@ -107,7 +115,7 @@ TEST_SUITE("[[TextServer]") {
 				Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
 				TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
 
-				if (!ts->has_feature(TextServer::FEATURE_BIDI_LAYOUT)) {
+				if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_BIDI_LAYOUT)) {
 					continue;
 				}
 
@@ -116,7 +124,7 @@ TEST_SUITE("[[TextServer]") {
 				RID font2 = ts->create_font();
 				ts->font_set_data_ptr(font2, _font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size);
 
-				Vector<RID> font;
+				Array font;
 				font.push_back(font1);
 				font.push_back(font2);
 
@@ -145,10 +153,10 @@ TEST_SUITE("[[TextServer]") {
 					}
 				}
 
-				ts->free(ctx);
+				ts->free_rid(ctx);
 
 				for (int j = 0; j < font.size(); j++) {
-					ts->free(font[j]);
+					ts->free_rid(font[j]);
 				}
 				font.clear();
 			}
@@ -159,6 +167,10 @@ TEST_SUITE("[[TextServer]") {
 				Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
 				TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
 
+				if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) {
+					continue;
+				}
+
 				RID font1 = ts->create_font();
 				ts->font_set_data_ptr(font1, _font_NotoSans_Regular, _font_NotoSans_Regular_size);
 				RID font2 = ts->create_font();
@@ -166,7 +178,7 @@ TEST_SUITE("[[TextServer]") {
 				RID font3 = ts->create_font();
 				ts->font_set_data_ptr(font3, _font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size);
 
-				Vector<RID> font;
+				Array font;
 				font.push_back(font1);
 				font.push_back(font2);
 				font.push_back(font3);
@@ -198,7 +210,7 @@ TEST_SUITE("[[TextServer]") {
 							TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags.");
 						}
 					}
-					ts->free(ctx);
+					ts->free_rid(ctx);
 				}
 
 				{
@@ -241,7 +253,7 @@ TEST_SUITE("[[TextServer]") {
 							}
 						}
 					}
-					ts->free(ctx);
+					ts->free_rid(ctx);
 				}
 
 				{
@@ -294,7 +306,7 @@ TEST_SUITE("[[TextServer]") {
 						}
 					}
 
-					ts->free(ctx);
+					ts->free_rid(ctx);
 				}
 
 				{
@@ -322,7 +334,7 @@ TEST_SUITE("[[TextServer]") {
 							TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags.");
 						}
 					}
-					ts->free(ctx);
+					ts->free_rid(ctx);
 				}
 
 				if (ts->has_feature(TextServer::FEATURE_BREAK_ITERATORS)) {
@@ -350,11 +362,11 @@ TEST_SUITE("[[TextServer]") {
 							TEST_FAIL_COND((soft || space || hard || virt || elo), "Invalid glyph flags.");
 						}
 					}
-					ts->free(ctx);
+					ts->free_rid(ctx);
 				}
 
 				for (int j = 0; j < font.size(); j++) {
-					ts->free(font[j]);
+					ts->free_rid(font[j]);
 				}
 				font.clear();
 			}
@@ -365,6 +377,10 @@ TEST_SUITE("[[TextServer]") {
 				Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
 				TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
 
+				if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) {
+					continue;
+				}
+
 				String test_1 = U"test test test";
 				//                   5^  10^
 
@@ -373,7 +389,7 @@ TEST_SUITE("[[TextServer]") {
 				RID font2 = ts->create_font();
 				ts->font_set_data_ptr(font2, _font_NotoSansThaiUI_Regular, _font_NotoSansThaiUI_Regular_size);
 
-				Vector<RID> font;
+				Array font;
 				font.push_back(font1);
 				font.push_back(font2);
 
@@ -395,10 +411,10 @@ TEST_SUITE("[[TextServer]") {
 					TEST_FAIL_COND(brks[5] != 14, "Invalid line break position.");
 				}
 
-				ts->free(ctx);
+				ts->free_rid(ctx);
 
 				for (int j = 0; j < font.size(); j++) {
-					ts->free(font[j]);
+					ts->free_rid(font[j]);
 				}
 				font.clear();
 			}
@@ -409,12 +425,16 @@ TEST_SUITE("[[TextServer]") {
 				Ref<TextServer> ts = TextServerManager::get_singleton()->get_interface(i);
 				TEST_FAIL_COND(ts.is_null(), "Invalid TS interface.");
 
+				if (!ts->has_feature(TextServer::FEATURE_FONT_DYNAMIC) || !ts->has_feature(TextServer::FEATURE_SIMPLE_LAYOUT)) {
+					continue;
+				}
+
 				RID font1 = ts->create_font();
 				ts->font_set_data_ptr(font1, _font_NotoSans_Regular, _font_NotoSans_Regular_size);
 				RID font2 = ts->create_font();
 				ts->font_set_data_ptr(font2, _font_NotoNaskhArabicUI_Regular, _font_NotoNaskhArabicUI_Regular_size);
 
-				Vector<RID> font;
+				Array font;
 				font.push_back(font1);
 				font.push_back(font2);
 
@@ -438,7 +458,7 @@ TEST_SUITE("[[TextServer]") {
 					width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA);
 					TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width.");
 
-					ts->free(ctx);
+					ts->free_rid(ctx);
 
 					ctx = ts->create_shaped_text();
 					TEST_FAIL_COND(ctx == RID(), "Creating text buffer failed.");
@@ -451,7 +471,7 @@ TEST_SUITE("[[TextServer]") {
 					width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA);
 					TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width.");
 
-					ts->free(ctx);
+					ts->free_rid(ctx);
 				}
 
 				ctx = ts->create_shaped_text();
@@ -463,10 +483,10 @@ TEST_SUITE("[[TextServer]") {
 				width = ts->shaped_text_fit_to_width(ctx, 100, TextServer::JUSTIFICATION_WORD_BOUND);
 				TEST_FAIL_COND((width <= width_old || width > 100), "Invalid fill width.");
 
-				ts->free(ctx);
+				ts->free_rid(ctx);
 
 				for (int j = 0; j < font.size(); j++) {
-					ts->free(font[j]);
+					ts->free_rid(font[j]);
 				}
 				font.clear();
 			}

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.