summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/basis_universal/SCsub4
-rw-r--r--modules/bmp/image_loader_bmp.cpp2
-rw-r--r--modules/bmp/image_loader_bmp.h2
-rw-r--r--modules/bmp/register_types.cpp7
-rw-r--r--modules/csg/SCsub2
-rw-r--r--modules/csg/csg.h1
-rw-r--r--modules/cvtt/config.py2
-rw-r--r--modules/denoise/SCsub2
-rw-r--r--modules/denoise/config.py2
-rw-r--r--modules/etcpak/config.py2
-rw-r--r--modules/freetype/SCsub2
-rw-r--r--modules/gdscript/SCsub2
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml10
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp52
-rw-r--r--modules/gdscript/gdscript.cpp2
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp84
-rw-r--r--modules/gdscript/gdscript_cache.cpp14
-rw-r--r--modules/gdscript/gdscript_cache.h2
-rw-r--r--modules/gdscript/gdscript_compiler.cpp2
-rw-r--r--modules/gdscript/gdscript_parser.cpp33
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.cpp1
-rw-r--r--modules/gltf/SCsub4
-rw-r--r--modules/gltf/doc_classes/GLTFDocumentExtension.xml8
-rw-r--r--modules/gltf/doc_classes/GLTFNode.xml3
-rw-r--r--modules/gltf/doc_classes/GLTFState.xml8
-rw-r--r--modules/gltf/extensions/SCsub9
-rw-r--r--modules/gltf/gltf_defines.h2
-rw-r--r--modules/gltf/gltf_document.cpp95
-rw-r--r--modules/gltf/gltf_document.h4
-rw-r--r--modules/gltf/gltf_document_extension.cpp7
-rw-r--r--modules/gltf/gltf_document_extension.h2
-rw-r--r--modules/gltf/gltf_state.cpp12
-rw-r--r--modules/gltf/gltf_state.h4
-rw-r--r--modules/gltf/register_types.h5
-rw-r--r--modules/gridmap/SCsub2
-rw-r--r--modules/gridmap/doc_classes/GridMap.xml2
-rw-r--r--modules/gridmap/grid_map.cpp2
-rw-r--r--modules/hdr/image_loader_hdr.cpp2
-rw-r--r--modules/hdr/image_loader_hdr.h2
-rw-r--r--modules/hdr/register_types.cpp7
-rw-r--r--modules/jpg/image_loader_jpegd.cpp2
-rw-r--r--modules/jpg/image_loader_jpegd.h2
-rw-r--r--modules/jpg/register_types.cpp7
-rw-r--r--modules/minimp3/audio_stream_mp3.cpp14
-rw-r--r--modules/minimp3/audio_stream_mp3.h12
-rw-r--r--modules/mono/SCsub2
-rwxr-xr-xmodules/mono/build_scripts/build_assemblies.py12
-rw-r--r--modules/mono/build_scripts/mono_configure.py9
-rw-r--r--modules/mono/config.py2
-rw-r--r--modules/mono/csharp_script.cpp8
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/EventHandlerSuffixSuppressor.cs53
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs4
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs18
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs70
-rw-r--r--modules/mono/editor/bindings_generator.cpp9
-rw-r--r--modules/mono/editor/editor_internal_calls.cpp2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs4
-rw-r--r--modules/mono/utils/macos_utils.h4
-rw-r--r--modules/multiplayer/SCsub2
-rw-r--r--modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml4
-rw-r--r--modules/multiplayer/multiplayer_spawner.cpp20
-rw-r--r--modules/multiplayer/multiplayer_spawner.h2
-rw-r--r--modules/multiplayer/multiplayer_synchronizer.cpp10
-rw-r--r--modules/multiplayer/multiplayer_synchronizer.h2
-rw-r--r--modules/multiplayer/scene_replication_interface.cpp5
-rw-r--r--modules/navigation/SCsub2
-rw-r--r--modules/navigation/godot_navigation_server.cpp26
-rw-r--r--modules/navigation/godot_navigation_server.h2
-rw-r--r--modules/navigation/nav_map.cpp20
-rw-r--r--modules/openxr/SCsub67
-rw-r--r--modules/openxr/action_map/openxr_action_map.cpp22
-rw-r--r--modules/openxr/action_map/openxr_defs.cpp20
-rw-r--r--modules/openxr/config.py5
-rw-r--r--modules/openxr/doc_classes/OpenXRHand.xml42
-rw-r--r--modules/openxr/extensions/openxr_android_extension.cpp20
-rw-r--r--modules/openxr/extensions/openxr_android_extension.h7
-rw-r--r--modules/openxr/extensions/openxr_composition_layer_provider.h7
-rw-r--r--modules/openxr/extensions/openxr_extension_wrapper.h6
-rw-r--r--modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.cpp234
-rw-r--r--modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.h254
-rw-r--r--modules/openxr/extensions/openxr_hand_tracking_extension.cpp268
-rw-r--r--modules/openxr/extensions/openxr_hand_tracking_extension.h96
-rw-r--r--modules/openxr/extensions/openxr_htc_vive_tracker_extension.cpp9
-rw-r--r--modules/openxr/extensions/openxr_htc_vive_tracker_extension.h2
-rw-r--r--modules/openxr/extensions/openxr_palm_pose_extension.cpp66
-rw-r--r--modules/openxr/extensions/openxr_palm_pose_extension.h53
-rw-r--r--modules/openxr/extensions/openxr_vulkan_extension.cpp67
-rw-r--r--modules/openxr/extensions/openxr_vulkan_extension.h36
-rw-r--r--modules/openxr/openxr_api.cpp161
-rw-r--r--modules/openxr/openxr_api.h81
-rw-r--r--modules/openxr/openxr_interface.cpp68
-rw-r--r--modules/openxr/openxr_interface.h8
-rw-r--r--modules/openxr/register_types.cpp4
-rw-r--r--modules/openxr/scene/openxr_hand.cpp307
-rw-r--r--modules/openxr/scene/openxr_hand.h93
-rw-r--r--modules/openxr/util.h110
-rw-r--r--modules/raycast/SCsub6
-rw-r--r--modules/raycast/lightmap_raycaster_embree.cpp (renamed from modules/raycast/lightmap_raycaster.cpp)6
-rw-r--r--modules/raycast/lightmap_raycaster_embree.h (renamed from modules/raycast/lightmap_raycaster.h)9
-rw-r--r--modules/raycast/register_types.cpp4
-rw-r--r--modules/raycast/register_types.h5
-rw-r--r--modules/raycast/static_raycaster_embree.cpp (renamed from modules/raycast/static_raycaster.cpp)6
-rw-r--r--modules/raycast/static_raycaster_embree.h (renamed from modules/raycast/static_raycaster.h)9
-rw-r--r--modules/regex/SCsub2
-rw-r--r--modules/svg/image_loader_svg.cpp2
-rw-r--r--modules/svg/image_loader_svg.h2
-rw-r--r--modules/svg/register_types.cpp12
-rw-r--r--modules/text_server_adv/SCsub7
-rw-r--r--modules/text_server_adv/gdextension_build/SConstruct31
-rw-r--r--modules/text_server_adv/text_server_adv.cpp586
-rw-r--r--modules/text_server_adv/text_server_adv.h349
-rw-r--r--modules/text_server_fb/gdextension_build/SConstruct22
-rw-r--r--modules/text_server_fb/text_server_fb.cpp527
-rw-r--r--modules/text_server_fb/text_server_fb.h337
-rw-r--r--modules/tga/image_loader_tga.cpp27
-rw-r--r--modules/tga/image_loader_tga.h4
-rw-r--r--modules/tga/register_types.cpp7
-rw-r--r--modules/theora/video_stream_theora.cpp68
-rw-r--r--modules/theora/video_stream_theora.h10
-rw-r--r--modules/tinyexr/config.py2
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp2
-rw-r--r--modules/tinyexr/image_loader_tinyexr.h2
-rw-r--r--modules/tinyexr/register_types.cpp7
-rw-r--r--modules/vorbis/audio_stream_ogg_vorbis.cpp43
-rw-r--r--modules/vorbis/audio_stream_ogg_vorbis.h12
-rw-r--r--modules/vorbis/resource_importer_ogg_vorbis.cpp18
-rw-r--r--modules/webp/image_loader_webp.cpp2
-rw-r--r--modules/webp/image_loader_webp.h2
-rw-r--r--modules/webp/register_types.cpp11
-rw-r--r--modules/websocket/SCsub2
-rw-r--r--modules/websocket/websocket_macros.h50
-rw-r--r--modules/webxr/config.py2
-rw-r--r--modules/webxr/godot_webxr.h3
-rw-r--r--modules/webxr/native/library_godot_webxr.js191
-rw-r--r--modules/webxr/webxr_interface_js.cpp56
-rw-r--r--modules/webxr/webxr_interface_js.h1
-rw-r--r--modules/xatlas_unwrap/config.py2
138 files changed, 3697 insertions, 1605 deletions
diff --git a/modules/basis_universal/SCsub b/modules/basis_universal/SCsub
index a44a7f0db3..161b0f3814 100644
--- a/modules/basis_universal/SCsub
+++ b/modules/basis_universal/SCsub
@@ -40,12 +40,12 @@ if not env.msvc:
else:
env_basisu.Prepend(CPPPATH=[thirdparty_dir])
-if env["target"] == "debug":
+if env.dev_build:
env_basisu.Append(CPPDEFINES=[("BASISU_DEVEL_MESSAGES", 1), ("BASISD_ENABLE_DEBUG_FLAGS", 1)])
env_thirdparty = env_basisu.Clone()
env_thirdparty.disable_warnings()
-if env["tools"]:
+if env.editor_build:
env_thirdparty.Append(CPPDEFINES=["BASISU_NO_IMG_LOADERS"])
env_thirdparty.add_source_files(thirdparty_obj, encoder_sources)
env_thirdparty.add_source_files(thirdparty_obj, transcoder_sources)
diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp
index ae03abca50..cc21ed28e8 100644
--- a/modules/bmp/image_loader_bmp.cpp
+++ b/modules/bmp/image_loader_bmp.cpp
@@ -200,7 +200,7 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
return err;
}
-Error ImageLoaderBMP::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) {
+Error ImageLoaderBMP::load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale) {
bmp_header_s bmp_header;
Error err = ERR_INVALID_DATA;
diff --git a/modules/bmp/image_loader_bmp.h b/modules/bmp/image_loader_bmp.h
index cf8346ecad..0ca54de1dc 100644
--- a/modules/bmp/image_loader_bmp.h
+++ b/modules/bmp/image_loader_bmp.h
@@ -83,7 +83,7 @@ protected:
const bmp_header_s &p_header);
public:
- virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale);
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderBMP();
};
diff --git a/modules/bmp/register_types.cpp b/modules/bmp/register_types.cpp
index 7c4a2085b2..67858e9d46 100644
--- a/modules/bmp/register_types.cpp
+++ b/modules/bmp/register_types.cpp
@@ -32,14 +32,14 @@
#include "image_loader_bmp.h"
-static ImageLoaderBMP *image_loader_bmp = nullptr;
+static Ref<ImageLoaderBMP> image_loader_bmp;
void initialize_bmp_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}
- image_loader_bmp = memnew(ImageLoaderBMP);
+ image_loader_bmp.instantiate();
ImageLoader::add_image_format_loader(image_loader_bmp);
}
@@ -48,5 +48,6 @@ void uninitialize_bmp_module(ModuleInitializationLevel p_level) {
return;
}
- memdelete(image_loader_bmp);
+ ImageLoader::remove_image_format_loader(image_loader_bmp);
+ image_loader_bmp.unref();
}
diff --git a/modules/csg/SCsub b/modules/csg/SCsub
index 55f859db11..1cf9974fc1 100644
--- a/modules/csg/SCsub
+++ b/modules/csg/SCsub
@@ -7,5 +7,5 @@ env_csg = env_modules.Clone()
# Godot source files
env_csg.add_source_files(env.modules_sources, "*.cpp")
-if env["tools"]:
+if env.editor_build:
env_csg.add_source_files(env.modules_sources, "editor/*.cpp")
diff --git a/modules/csg/csg.h b/modules/csg/csg.h
index 738e3d68ea..aae99c52a3 100644
--- a/modules/csg/csg.h
+++ b/modules/csg/csg.h
@@ -39,7 +39,6 @@
#include "core/object/ref_counted.h"
#include "core/templates/list.h"
#include "core/templates/oa_hash_map.h"
-#include "core/templates/rb_map.h"
#include "core/templates/vector.h"
#include "scene/resources/material.h"
diff --git a/modules/cvtt/config.py b/modules/cvtt/config.py
index 53b8f2f2e3..eb565b85b9 100644
--- a/modules/cvtt/config.py
+++ b/modules/cvtt/config.py
@@ -1,5 +1,5 @@
def can_build(env, platform):
- return env["tools"]
+ return env.editor_build
def configure(env):
diff --git a/modules/denoise/SCsub b/modules/denoise/SCsub
index 97feea2b44..779ce165d2 100644
--- a/modules/denoise/SCsub
+++ b/modules/denoise/SCsub
@@ -103,9 +103,9 @@ env_oidn.Append(
"__STDC_LIMIT_MACROS",
"DISABLE_VERBOSE",
"MKLDNN_ENABLE_CONCURRENT_EXEC",
- "NDEBUG",
]
)
+env_oidn.AppendUnique(CPPDEFINES=["NDEBUG"]) # No assert() even in debug builds.
env_thirdparty = env_oidn.Clone()
env_thirdparty.disable_warnings()
diff --git a/modules/denoise/config.py b/modules/denoise/config.py
index 20a5e1da2f..27d2ffbf86 100644
--- a/modules/denoise/config.py
+++ b/modules/denoise/config.py
@@ -5,7 +5,7 @@ def can_build(env, platform):
# as doing lightmap generation and denoising on Android or Web
# would be a bit far-fetched.
desktop_platforms = ["linuxbsd", "macos", "windows"]
- return env["tools"] and platform in desktop_platforms and env["arch"] == "x86_64"
+ return env.editor_build and platform in desktop_platforms and env["arch"] == "x86_64"
def configure(env):
diff --git a/modules/etcpak/config.py b/modules/etcpak/config.py
index 53b8f2f2e3..eb565b85b9 100644
--- a/modules/etcpak/config.py
+++ b/modules/etcpak/config.py
@@ -1,5 +1,5 @@
def can_build(env, platform):
- return env["tools"]
+ return env.editor_build
def configure(env):
diff --git a/modules/freetype/SCsub b/modules/freetype/SCsub
index 2680479acc..0b86bc569f 100644
--- a/modules/freetype/SCsub
+++ b/modules/freetype/SCsub
@@ -90,7 +90,7 @@ if env["builtin_freetype"]:
env.Prepend(CPPPATH=[thirdparty_dir + "/include"])
env_freetype.Append(CPPDEFINES=["FT2_BUILD_LIBRARY", "FT_CONFIG_OPTION_USE_PNG", "FT_CONFIG_OPTION_SYSTEM_ZLIB"])
- if env["target"] == "debug":
+ if env.dev_build:
env_freetype.Append(CPPDEFINES=["ZLIB_DEBUG"])
# Also requires libpng headers
diff --git a/modules/gdscript/SCsub b/modules/gdscript/SCsub
index 2f507db548..1dc4768186 100644
--- a/modules/gdscript/SCsub
+++ b/modules/gdscript/SCsub
@@ -7,7 +7,7 @@ env_gdscript = env_modules.Clone()
env_gdscript.add_source_files(env.modules_sources, "*.cpp")
-if env["tools"]:
+if env.editor_build:
env_gdscript.add_source_files(env.modules_sources, "./editor/*.cpp")
SConscript("editor/script_templates/SCsub")
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 4f325fcf52..d0b4632ebe 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -84,7 +84,7 @@
<method name="get_stack">
<return type="Array" />
<description>
- Returns an array of dictionaries representing the current call stack.
+ Returns an array of dictionaries representing the current call stack. See also [method print_stack].
[codeblock]
func _ready():
foo()
@@ -99,6 +99,7 @@
[codeblock]
[{function:bar, line:12, source:res://script.gd}, {function:foo, line:9, source:res://script.gd}, {function:_ready, line:6, source:res://script.gd}]
[/codeblock]
+ [b]Note:[/b] [method get_stack] only works if the running instance is connected to a debugging server (i.e. an editor instance). [method get_stack] will not work in projects exported in release mode, or in projects exported in debug mode if not connected to a debugging server.
[b]Note:[/b] Not supported for calling from threads. Instead, this will return an empty array.
</description>
</method>
@@ -175,11 +176,12 @@
<method name="print_stack">
<return type="void" />
<description>
- Prints a stack trace at the current code location. Only works when running with debugger turned on.
+ Prints a stack trace at the current code location. See also [method get_stack].
Output in the console would look something like this:
[codeblock]
Frame 0 - res://test.gd:16 in function '_process'
[/codeblock]
+ [b]Note:[/b] [method print_stack] only works if the running instance is connected to a debugging server (i.e. an editor instance). [method print_stack] will not work in projects exported in release mode, or in projects exported in debug mode if not connected to a debugging server.
[b]Note:[/b] Not supported for calling from threads. Instead of the stack trace, this will print the thread ID.
</description>
</method>
@@ -448,7 +450,7 @@
<param index="1" name="prefix" type="String" default="&quot;&quot;" />
<description>
Define a new group for the following exported properties. This helps to organize properties in the Inspector dock. Groups can be added with an optional [param prefix], which would make group to only consider properties that have this prefix. The grouping will break on the first property that doesn't have a prefix. The prefix is also removed from the property's name in the Inspector dock.
- If no [param prefix] is provided, the every following property is added to the group. The group ends when then next group or category is defined. You can also force end a group by using this annotation with empty strings for paramters, [code]@export_group("", "")[/code].
+ If no [param prefix] is provided, the every following property is added to the group. The group ends when then next group or category is defined. You can also force end a group by using this annotation with empty strings for parameters, [code]@export_group("", "")[/code].
Groups cannot be nested, use [annotation @export_subgroup] to add subgroups to your groups.
See also [constant PROPERTY_USAGE_GROUP].
[codeblock]
@@ -555,7 +557,7 @@
<annotation name="@onready">
<return type="void" />
<description>
- Mark the following property as assigned on [Node]'s ready state change. Values for these properties are no assigned immediately upon the node's creation, and instead are computed and stored right before [method Node._ready].
+ Mark the following property as assigned on [Node]'s ready state change. Values for these properties are not assigned immediately upon the node's creation, and instead are computed and stored right before [method Node._ready].
[codeblock]
@onready var character_name: Label = $Label
[/codeblock]
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index afb59b486c..e0deea1106 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -39,10 +39,10 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
Type next_type = NONE;
Type current_type = NONE;
- Type previous_type = NONE;
+ Type prev_type = NONE;
- String previous_text = "";
- int previous_column = 0;
+ String prev_text = "";
+ int prev_column = 0;
bool prev_is_char = false;
bool prev_is_digit = false;
@@ -224,9 +224,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
}
}
- previous_type = REGION;
- previous_text = "";
- previous_column = j;
+ prev_type = REGION;
+ prev_text = "";
+ prev_column = j;
j = from + (end_key_length - 1);
if (region_end_index == -1) {
color_region_cache[p_line] = in_region;
@@ -243,17 +243,15 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
// A bit of a hack, but couldn't come up with anything better.
if (j > 0 && (str[j] == '&' || str[j] == '^' || str[j] == '%' || str[j] == '+' || str[j] == '-' || str[j] == '~' || str[j] == '.')) {
- if (!keywords.has(previous_text)) {
- if (previous_text == "PI" || previous_text == "TAU" || previous_text == "INF" || previous_text == "NAN") {
+ if (prev_text == "true" || prev_text == "false" || prev_text == "self" || prev_text == "null" || prev_text == "PI" || prev_text == "TAU" || prev_text == "INF" || prev_text == "NAN") {
+ is_binary_op = true;
+ } else if (!keywords.has(prev_text)) {
+ int k = j - 1;
+ while (k > 0 && is_whitespace(str[k])) {
+ k--;
+ }
+ if (!is_symbol(str[k]) || str[k] == '"' || str[k] == '\'' || str[k] == ')' || str[k] == ']' || str[k] == '}') {
is_binary_op = true;
- } else {
- int k = j - 1;
- while (k > 0 && is_whitespace(str[k])) {
- k--;
- }
- if (!is_symbol(str[k]) || str[k] == '"' || str[k] == '\'' || str[k] == ')' || str[k] == ']' || str[k] == '}') {
- is_binary_op = true;
- }
}
}
}
@@ -355,7 +353,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
}
if (!in_function_name && in_word && !in_keyword) {
- if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::SIGNAL)) {
+ if (prev_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::SIGNAL)) {
in_signal_declaration = true;
} else {
int k = j;
@@ -370,12 +368,12 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
if (str[k] == '(') {
in_function_name = true;
- } else if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::VAR)) {
+ } else if (prev_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::VAR)) {
in_variable_declaration = true;
}
// Check for lambda.
- if (in_function_name && previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) {
+ if (in_function_name && prev_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) {
k = j - 1;
while (k > 0 && is_whitespace(str[k])) {
k--;
@@ -491,7 +489,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
} else if (in_function_name) {
next_type = FUNCTION;
- if (!in_lambda && previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) {
+ if (!in_lambda && prev_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) {
color = function_definition_color;
} else {
color = function_color;
@@ -513,20 +511,20 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
if (current_type == NONE) {
current_type = next_type;
} else {
- previous_type = current_type;
+ prev_type = current_type;
current_type = next_type;
// no need to store regions...
- if (previous_type == REGION) {
- previous_text = "";
- previous_column = j;
+ if (prev_type == REGION) {
+ prev_text = "";
+ prev_column = j;
} else {
- String text = str.substr(previous_column, j - previous_column).strip_edges();
- previous_column = j;
+ String text = str.substr(prev_column, j - prev_column).strip_edges();
+ prev_column = j;
// ignore if just whitespace
if (!text.is_empty()) {
- previous_text = text;
+ prev_text = text;
}
}
}
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 1cff2181af..54cadf7df3 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -2390,7 +2390,7 @@ Ref<Resource> ResourceFormatLoaderGDScript::load(const String &p_path, const Str
}
Error err;
- Ref<GDScript> script = GDScriptCache::get_full_script(p_path, err);
+ Ref<GDScript> script = GDScriptCache::get_full_script(p_path, err, "", p_cache_mode == CACHE_MODE_IGNORE);
// TODO: Reintroduce binary and encrypted scripts.
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index b6e7dc397a..32d9aec84f 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -484,12 +484,23 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type
if (parser->script_path == ScriptServer::get_global_class_path(first)) {
result = parser->head->get_datatype();
} else {
- Ref<GDScriptParserRef> ref = get_parser_for(ScriptServer::get_global_class_path(first));
- if (!ref.is_valid() || ref->raise_status(GDScriptParserRef::INTERFACE_SOLVED) != OK) {
- push_error(vformat(R"(Could not parse global class "%s" from "%s".)", first, ScriptServer::get_global_class_path(first)), p_type);
- return GDScriptParser::DataType();
+ String path = ScriptServer::get_global_class_path(first);
+ String ext = path.get_extension();
+ if (ext == GDScriptLanguage::get_singleton()->get_extension()) {
+ Ref<GDScriptParserRef> ref = get_parser_for(path);
+ if (!ref.is_valid() || ref->raise_status(GDScriptParserRef::INTERFACE_SOLVED) != OK) {
+ push_error(vformat(R"(Could not parse global class "%s" from "%s".)", first, ScriptServer::get_global_class_path(first)), p_type);
+ return GDScriptParser::DataType();
+ }
+ result = ref->get_parser()->head->get_datatype();
+ } else {
+ result.kind = GDScriptParser::DataType::SCRIPT;
+ result.native_type = ScriptServer::get_global_class_native_base(first);
+ result.script_type = ResourceLoader::load(path, "Script");
+ result.script_path = path;
+ result.is_constant = true;
+ result.is_meta_type = false;
}
- result = ref->get_parser()->head->get_datatype();
}
} else if (ProjectSettings::get_singleton()->has_autoload(first) && ProjectSettings::get_singleton()->get_autoload(first).is_singleton) {
const ProjectSettings::AutoloadInfo &autoload = ProjectSettings::get_singleton()->get_autoload(first);
@@ -540,12 +551,13 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type
result = ref->get_parser()->head->get_datatype();
result.is_meta_type = false;
} else {
- Ref<GDScript> script = member.constant->initializer->reduced_value;
+ Ref<Script> script = member.constant->initializer->reduced_value;
result.kind = GDScriptParser::DataType::SCRIPT;
result.builtin_type = Variant::OBJECT;
result.script_type = script;
result.script_path = script->get_path();
result.native_type = script->get_instance_base_type();
+ result.is_meta_type = false;
}
break;
}
@@ -2676,31 +2688,45 @@ void GDScriptAnalyzer::reduce_get_node(GDScriptParser::GetNodeNode *p_get_node)
GDScriptParser::DataType GDScriptAnalyzer::make_global_class_meta_type(const StringName &p_class_name, const GDScriptParser::Node *p_source) {
GDScriptParser::DataType type;
- Ref<GDScriptParserRef> ref = get_parser_for(ScriptServer::get_global_class_path(p_class_name));
- if (ref.is_null()) {
- push_error(vformat(R"(Could not find script for class "%s".)", p_class_name), p_source);
- type.type_source = GDScriptParser::DataType::UNDETECTED;
- type.kind = GDScriptParser::DataType::VARIANT;
+ String path = ScriptServer::get_global_class_path(p_class_name);
+ String ext = path.get_extension();
+ if (ext == GDScriptLanguage::get_singleton()->get_extension()) {
+ Ref<GDScriptParserRef> ref = get_parser_for(path);
+ if (ref.is_null()) {
+ push_error(vformat(R"(Could not find script for class "%s".)", p_class_name), p_source);
+ type.type_source = GDScriptParser::DataType::UNDETECTED;
+ type.kind = GDScriptParser::DataType::VARIANT;
+ return type;
+ }
+
+ Error err = ref->raise_status(GDScriptParserRef::INTERFACE_SOLVED);
+ if (err) {
+ push_error(vformat(R"(Could not resolve class "%s", because of a parser error.)", p_class_name), p_source);
+ type.type_source = GDScriptParser::DataType::UNDETECTED;
+ type.kind = GDScriptParser::DataType::VARIANT;
+ return type;
+ }
+
+ type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
+ type.kind = GDScriptParser::DataType::CLASS;
+ type.builtin_type = Variant::OBJECT;
+ type.native_type = ScriptServer::get_global_class_native_base(p_class_name);
+ type.class_type = ref->get_parser()->head;
+ type.script_path = ref->get_parser()->script_path;
+ type.is_constant = true;
+ type.is_meta_type = true;
return type;
- }
-
- Error err = ref->raise_status(GDScriptParserRef::INTERFACE_SOLVED);
- if (err) {
- push_error(vformat(R"(Could not resolve class "%s", because of a parser error.)", p_class_name), p_source);
- type.type_source = GDScriptParser::DataType::UNDETECTED;
- type.kind = GDScriptParser::DataType::VARIANT;
+ } else {
+ type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
+ type.kind = GDScriptParser::DataType::SCRIPT;
+ type.builtin_type = Variant::OBJECT;
+ type.native_type = ScriptServer::get_global_class_native_base(p_class_name);
+ type.script_type = ResourceLoader::load(path, "Script");
+ type.script_path = path;
+ type.is_constant = true;
+ type.is_meta_type = true;
return type;
}
-
- type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
- type.kind = GDScriptParser::DataType::CLASS;
- type.builtin_type = Variant::OBJECT;
- type.native_type = ScriptServer::get_global_class_native_base(p_class_name);
- type.class_type = ref->get_parser()->head;
- type.script_path = ref->get_parser()->script_path;
- type.is_constant = true;
- type.is_meta_type = true;
- return type;
}
void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNode *p_identifier, GDScriptParser::DataType *p_base) {
@@ -3808,7 +3834,7 @@ bool GDScriptAnalyzer::get_function_signature(GDScriptParser::Node *p_source, bo
Ref<Script> base_script = p_base_type.script_type;
- while (base_script.is_valid() && base_script->is_valid()) {
+ while (base_script.is_valid() && base_script->has_method(function_name)) {
MethodInfo info = base_script->get_method_info(function_name);
if (!(info == MethodInfo())) {
diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp
index c25f5b58d5..271296c2f9 100644
--- a/modules/gdscript/gdscript_cache.cpp
+++ b/modules/gdscript/gdscript_cache.cpp
@@ -183,20 +183,26 @@ Ref<GDScript> GDScriptCache::get_shallow_script(const String &p_path, const Stri
return script;
}
-Ref<GDScript> GDScriptCache::get_full_script(const String &p_path, Error &r_error, const String &p_owner) {
+Ref<GDScript> GDScriptCache::get_full_script(const String &p_path, Error &r_error, const String &p_owner, bool p_update_from_disk) {
MutexLock lock(singleton->lock);
if (!p_owner.is_empty()) {
singleton->dependencies[p_owner].insert(p_path);
}
+ Ref<GDScript> script;
r_error = OK;
if (singleton->full_gdscript_cache.has(p_path)) {
- return singleton->full_gdscript_cache[p_path];
+ script = Ref<GDScript>(singleton->full_gdscript_cache[p_path]);
+ if (!p_update_from_disk) {
+ return script;
+ }
}
- Ref<GDScript> script = get_shallow_script(p_path);
- ERR_FAIL_COND_V(script.is_null(), Ref<GDScript>());
+ if (script.is_null()) {
+ script = get_shallow_script(p_path);
+ ERR_FAIL_COND_V(script.is_null(), Ref<GDScript>());
+ }
r_error = script->load_source_code(p_path);
diff --git a/modules/gdscript/gdscript_cache.h b/modules/gdscript/gdscript_cache.h
index b971bdd984..3d111ea229 100644
--- a/modules/gdscript/gdscript_cache.h
+++ b/modules/gdscript/gdscript_cache.h
@@ -88,7 +88,7 @@ public:
static Ref<GDScriptParserRef> get_parser(const String &p_path, GDScriptParserRef::Status status, Error &r_error, const String &p_owner = String());
static String get_source_code(const String &p_path);
static Ref<GDScript> get_shallow_script(const String &p_path, const String &p_owner = String());
- static Ref<GDScript> get_full_script(const String &p_path, Error &r_error, const String &p_owner = String());
+ static Ref<GDScript> get_full_script(const String &p_path, Error &r_error, const String &p_owner = String(), bool p_update_from_disk = false);
static Error finish_compiling(const String &p_owner);
GDScriptCache();
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 00e8223b9a..fd418ced47 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -2041,7 +2041,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
codegen.generator->write_newline(field->initializer->start_line);
// For typed arrays we need to make sure this is already initialized correctly so typed assignment work.
- if (field_type.is_hard_type() && field_type.builtin_type == Variant::ARRAY && field_type.has_container_element_type()) {
+ if (field_type.is_hard_type() && field_type.builtin_type == Variant::ARRAY) {
if (field_type.has_container_element_type()) {
codegen.generator->write_construct_typed_array(dst_address, _gdtype_from_datatype(field_type.get_container_element_type(), codegen.script), Vector<GDScriptCodeGenerator::Address>());
} else {
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 888cd782fb..f1c841e9dc 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -2937,6 +2937,10 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_call(ExpressionNode *p_pre
push_error(R"(Expected expression as the function argument.)");
} else {
call->arguments.push_back(argument);
+
+ if (argument->type == Node::IDENTIFIER && current.cursor_place == GDScriptTokenizer::CURSOR_BEGINNING) {
+ completion_context.type = COMPLETION_IDENTIFIER;
+ }
}
ct = COMPLETION_CALL_ARGUMENTS;
} while (match(GDScriptTokenizer::Token::COMMA));
@@ -3758,6 +3762,33 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
return false;
}
break;
+ case GDScriptParser::DataType::CLASS:
+ // Can assume type is a global GDScript class.
+ if (!ClassDB::is_parent_class(export_type.native_type, SNAME("Resource"))) {
+ push_error(R"(Exported script type must extend Resource.)");
+ return false;
+ }
+ variable->export_info.type = Variant::OBJECT;
+ variable->export_info.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ variable->export_info.hint_string = export_type.class_type->identifier->name;
+ break;
+ case GDScriptParser::DataType::SCRIPT: {
+ StringName class_name;
+ if (export_type.script_type != nullptr && export_type.script_type.is_valid()) {
+ class_name = export_type.script_type->get_language()->get_global_class_name(export_type.script_type->get_path());
+ }
+ if (class_name == StringName()) {
+ Ref<Script> script = ResourceLoader::load(export_type.script_path, SNAME("Script"));
+ if (script.is_valid()) {
+ class_name = script->get_language()->get_global_class_name(export_type.script_path);
+ }
+ }
+ if (class_name != StringName() && ClassDB::is_parent_class(ScriptServer::get_global_class_native_base(class_name), SNAME("Resource"))) {
+ variable->export_info.type = Variant::OBJECT;
+ variable->export_info.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ variable->export_info.hint_string = class_name;
+ }
+ } break;
case GDScriptParser::DataType::ENUM: {
variable->export_info.type = Variant::INT;
variable->export_info.hint = PROPERTY_HINT_ENUM;
@@ -3974,7 +4005,7 @@ String GDScriptParser::DataType::to_string() const {
if (is_meta_type) {
return script_type->get_class_name().operator String();
}
- String name = script_type->get_name();
+ String name = script_type != nullptr ? script_type->get_name() : "";
if (!name.is_empty()) {
return name;
}
diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp
index 5ad9680ea0..ccde0521f2 100644
--- a/modules/gdscript/language_server/gdscript_text_document.cpp
+++ b/modules/gdscript/language_server/gdscript_text_document.cpp
@@ -422,6 +422,7 @@ void GDScriptTextDocument::sync_script_content(const String &p_path, const Strin
if (error == OK) {
if (script->load_source_code(path) == OK) {
script->reload(true);
+ ScriptEditor::get_singleton()->reload_scripts(true); // Refresh scripts opened in the internal editor.
}
}
}
diff --git a/modules/gltf/SCsub b/modules/gltf/SCsub
index 71f3ba58d9..d1f337715f 100644
--- a/modules/gltf/SCsub
+++ b/modules/gltf/SCsub
@@ -7,7 +7,7 @@ env_gltf = env_modules.Clone()
# Godot source files
env_gltf.add_source_files(env.modules_sources, "*.cpp")
-env_gltf.add_source_files(env.modules_sources, "extensions/*.cpp")
env_gltf.add_source_files(env.modules_sources, "structures/*.cpp")
-if env["tools"]:
+SConscript("extensions/SCsub")
+if env.editor_build:
env_gltf.add_source_files(env.modules_sources, "editor/*.cpp")
diff --git a/modules/gltf/doc_classes/GLTFDocumentExtension.xml b/modules/gltf/doc_classes/GLTFDocumentExtension.xml
index d2a9022445..936794976d 100644
--- a/modules/gltf/doc_classes/GLTFDocumentExtension.xml
+++ b/modules/gltf/doc_classes/GLTFDocumentExtension.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="GLTFDocumentExtension" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
+ [GLTFDocument] extension class.
</brief_description>
<description>
+ Extends the functionality of the [GLTFDocument] class by allowing you to run arbitrary code at various stages of GLTF import or export.
</description>
<tutorials>
</tutorials>
@@ -28,6 +30,12 @@
<description>
</description>
</method>
+ <method name="_get_supported_extensions" qualifiers="virtual">
+ <return type="PackedStringArray" />
+ <description>
+ Returns an array of the GLTF extensions supported by this GLTFDocumentExtension class. This is used to validate if a GLTF file with required extensions can be loaded.
+ </description>
+ </method>
<method name="_import_node" qualifiers="virtual">
<return type="int" />
<param index="0" name="state" type="GLTFState" />
diff --git a/modules/gltf/doc_classes/GLTFNode.xml b/modules/gltf/doc_classes/GLTFNode.xml
index e933e6046a..4d1aa89ac9 100644
--- a/modules/gltf/doc_classes/GLTFNode.xml
+++ b/modules/gltf/doc_classes/GLTFNode.xml
@@ -1,10 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="GLTFNode" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
+ GLTF node class.
</brief_description>
<description>
+ Represents a GLTF node. GLTF nodes may have names, transforms, children (other GLTF nodes), and more specialized properties (represented by their own classes).
</description>
<tutorials>
+ <link title="GLTF scene and node spec">https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_004_ScenesNodes.md"</link>
</tutorials>
<members>
<member name="camera" type="int" setter="set_camera" getter="get_camera" default="-1">
diff --git a/modules/gltf/doc_classes/GLTFState.xml b/modules/gltf/doc_classes/GLTFState.xml
index 1dbd89aed8..6c2f488c1c 100644
--- a/modules/gltf/doc_classes/GLTFState.xml
+++ b/modules/gltf/doc_classes/GLTFState.xml
@@ -7,6 +7,14 @@
<tutorials>
</tutorials>
<methods>
+ <method name="add_used_extension">
+ <return type="void" />
+ <param index="0" name="extension_name" type="String" />
+ <param index="1" name="required" type="bool" />
+ <description>
+ Appends an extension to the list of extensions used by this GLTF file during serialization. If [param required] is true, the extension will also be added to the list of required extensions. Do not run this in [method GLTFDocumentExtension._export_post], as that stage is too late to add extensions. The final list is sorted alphabetically.
+ </description>
+ </method>
<method name="get_accessors">
<return type="GLTFAccessor[]" />
<description>
diff --git a/modules/gltf/extensions/SCsub b/modules/gltf/extensions/SCsub
new file mode 100644
index 0000000000..ad214bb79c
--- /dev/null
+++ b/modules/gltf/extensions/SCsub
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+
+Import("env")
+Import("env_modules")
+
+env_gltf = env_modules.Clone()
+
+# Godot source files
+env_gltf.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/gltf/gltf_defines.h b/modules/gltf/gltf_defines.h
index c20c87f798..9ee2397968 100644
--- a/modules/gltf/gltf_defines.h
+++ b/modules/gltf/gltf_defines.h
@@ -66,9 +66,9 @@ using GLTFBufferIndex = int;
using GLTFBufferViewIndex = int;
using GLTFCameraIndex = int;
using GLTFImageIndex = int;
+using GLTFLightIndex = int;
using GLTFMaterialIndex = int;
using GLTFMeshIndex = int;
-using GLTFLightIndex = int;
using GLTFNodeIndex = int;
using GLTFSkeletonIndex = int;
using GLTFSkinIndex = int;
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index f5730e7137..8d2e37be3a 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -191,14 +191,14 @@ Error GLTFDocument::_serialize(Ref<GLTFState> state, const String &p_path) {
return Error::FAILED;
}
- /* STEP SERIALIZE SCENE */
+ /* STEP SERIALIZE LIGHTS */
err = _serialize_lights(state);
if (err != OK) {
return Error::FAILED;
}
/* STEP SERIALIZE EXTENSIONS */
- err = _serialize_extensions(state);
+ err = _serialize_gltf_extensions(state);
if (err != OK) {
return Error::FAILED;
}
@@ -219,9 +219,9 @@ Error GLTFDocument::_serialize(Ref<GLTFState> state, const String &p_path) {
return OK;
}
-Error GLTFDocument::_serialize_extensions(Ref<GLTFState> state) const {
- Array extensions_used;
- Array extensions_required;
+Error GLTFDocument::_serialize_gltf_extensions(Ref<GLTFState> state) const {
+ Vector<String> extensions_used = state->extensions_used;
+ Vector<String> extensions_required = state->extensions_required;
if (!state->lights.is_empty()) {
extensions_used.push_back("KHR_lights_punctual");
}
@@ -230,9 +230,11 @@ Error GLTFDocument::_serialize_extensions(Ref<GLTFState> state) const {
extensions_required.push_back("KHR_texture_transform");
}
if (!extensions_used.is_empty()) {
+ extensions_used.sort();
state->json["extensionsUsed"] = extensions_used;
}
if (!extensions_required.is_empty()) {
+ extensions_required.sort();
state->json["extensionsRequired"] = extensions_required;
}
return OK;
@@ -401,47 +403,47 @@ Error GLTFDocument::_serialize_nodes(Ref<GLTFState> state) {
Array nodes;
for (int i = 0; i < state->nodes.size(); i++) {
Dictionary node;
- Ref<GLTFNode> n = state->nodes[i];
+ Ref<GLTFNode> gltf_node = state->nodes[i];
Dictionary extensions;
node["extensions"] = extensions;
- if (!n->get_name().is_empty()) {
- node["name"] = n->get_name();
+ if (!gltf_node->get_name().is_empty()) {
+ node["name"] = gltf_node->get_name();
}
- if (n->camera != -1) {
- node["camera"] = n->camera;
+ if (gltf_node->camera != -1) {
+ node["camera"] = gltf_node->camera;
}
- if (n->light != -1) {
+ if (gltf_node->light != -1) {
Dictionary lights_punctual;
extensions["KHR_lights_punctual"] = lights_punctual;
- lights_punctual["light"] = n->light;
+ lights_punctual["light"] = gltf_node->light;
}
- if (n->mesh != -1) {
- node["mesh"] = n->mesh;
+ if (gltf_node->mesh != -1) {
+ node["mesh"] = gltf_node->mesh;
}
- if (n->skin != -1) {
- node["skin"] = n->skin;
+ if (gltf_node->skin != -1) {
+ node["skin"] = gltf_node->skin;
}
- if (n->skeleton != -1 && n->skin < 0) {
+ if (gltf_node->skeleton != -1 && gltf_node->skin < 0) {
}
- if (n->xform != Transform3D()) {
- node["matrix"] = _xform_to_array(n->xform);
+ if (gltf_node->xform != Transform3D()) {
+ node["matrix"] = _xform_to_array(gltf_node->xform);
}
- if (!n->rotation.is_equal_approx(Quaternion())) {
- node["rotation"] = _quaternion_to_array(n->rotation);
+ if (!gltf_node->rotation.is_equal_approx(Quaternion())) {
+ node["rotation"] = _quaternion_to_array(gltf_node->rotation);
}
- if (!n->scale.is_equal_approx(Vector3(1.0f, 1.0f, 1.0f))) {
- node["scale"] = _vec3_to_arr(n->scale);
+ if (!gltf_node->scale.is_equal_approx(Vector3(1.0f, 1.0f, 1.0f))) {
+ node["scale"] = _vec3_to_arr(gltf_node->scale);
}
- if (!n->position.is_zero_approx()) {
- node["translation"] = _vec3_to_arr(n->position);
+ if (!gltf_node->position.is_zero_approx()) {
+ node["translation"] = _vec3_to_arr(gltf_node->position);
}
- if (n->children.size()) {
+ if (gltf_node->children.size()) {
Array children;
- for (int j = 0; j < n->children.size(); j++) {
- children.push_back(n->children[j]);
+ for (int j = 0; j < gltf_node->children.size(); j++) {
+ children.push_back(gltf_node->children[j]);
}
node["children"] = children;
}
@@ -450,7 +452,7 @@ Error GLTFDocument::_serialize_nodes(Ref<GLTFState> state) {
Ref<GLTFDocumentExtension> ext = document_extensions[ext_i];
ERR_CONTINUE(ext.is_null());
ERR_CONTINUE(!state->scene_nodes.find(i));
- Error err = ext->export_node(state, n, state->json, state->scene_nodes[i]);
+ Error err = ext->export_node(state, gltf_node, node, state->scene_nodes[i]);
ERR_CONTINUE(err != OK);
}
@@ -5046,7 +5048,7 @@ ImporterMeshInstance3D *GLTFDocument::_generate_mesh_instance(Ref<GLTFState> sta
return mi;
}
-Node3D *GLTFDocument::_generate_light(Ref<GLTFState> state, const GLTFNodeIndex node_index) {
+Light3D *GLTFDocument::_generate_light(Ref<GLTFState> state, const GLTFNodeIndex node_index) {
Ref<GLTFNode> gltf_node = state->nodes[node_index];
ERR_FAIL_INDEX_V(gltf_node->light, state->lights.size(), nullptr);
@@ -5102,6 +5104,7 @@ Node3D *GLTFDocument::_generate_spatial(Ref<GLTFState> state, const GLTFNodeInde
return spatial;
}
+
void GLTFDocument::_convert_scene_node(Ref<GLTFState> state, Node *p_current, const GLTFNodeIndex p_gltf_parent, const GLTFNodeIndex p_gltf_root) {
bool retflag = true;
_check_visibility(p_current, retflag);
@@ -6916,12 +6919,32 @@ Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> r_state, uint
Error GLTFDocument::_parse_gltf_extensions(Ref<GLTFState> state) {
ERR_FAIL_NULL_V(state, ERR_PARSE_ERROR);
- if (state->json.has("extensionsRequired") && state->json["extensionsRequired"].get_type() == Variant::ARRAY) {
- Array extensions_required = state->json["extensionsRequired"];
- if (extensions_required.find("KHR_draco_mesh_compression") != -1) {
- ERR_PRINT("glTF2 extension KHR_draco_mesh_compression is not supported.");
- return ERR_UNAVAILABLE;
+ if (state->json.has("extensionsUsed")) {
+ Vector<String> ext_array = state->json["extensionsUsed"];
+ state->extensions_used = ext_array;
+ }
+ if (state->json.has("extensionsRequired")) {
+ Vector<String> ext_array = state->json["extensionsRequired"];
+ state->extensions_required = ext_array;
+ }
+ HashSet<String> supported_extensions;
+ supported_extensions.insert("KHR_lights_punctual");
+ supported_extensions.insert("KHR_materials_pbrSpecularGlossiness");
+ supported_extensions.insert("KHR_texture_transform");
+ for (int ext_i = 0; ext_i < document_extensions.size(); ext_i++) {
+ Ref<GLTFDocumentExtension> ext = document_extensions[ext_i];
+ ERR_CONTINUE(ext.is_null());
+ Vector<String> ext_supported_extensions = ext->get_supported_extensions();
+ for (int i = 0; i < ext_supported_extensions.size(); ++i) {
+ supported_extensions.insert(ext_supported_extensions[i]);
}
}
- return OK;
+ Error ret = Error::OK;
+ for (int i = 0; i < state->extensions_required.size(); i++) {
+ if (!supported_extensions.has(state->extensions_required[i])) {
+ ERR_PRINT("GLTF: Can't import file '" + state->filename + "', required extension '" + String(state->extensions_required[i]) + "' is not supported. Are you missing a GLTFDocumentExtension plugin?");
+ ret = ERR_UNAVAILABLE;
+ }
+ }
+ return ret;
}
diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h
index 36a2f94a4e..750d3d403e 100644
--- a/modules/gltf/gltf_document.h
+++ b/modules/gltf/gltf_document.h
@@ -188,7 +188,7 @@ private:
const GLTFNodeIndex bone_index);
ImporterMeshInstance3D *_generate_mesh_instance(Ref<GLTFState> state, const GLTFNodeIndex node_index);
Camera3D *_generate_camera(Ref<GLTFState> state, const GLTFNodeIndex node_index);
- Node3D *_generate_light(Ref<GLTFState> state, const GLTFNodeIndex node_index);
+ Light3D *_generate_light(Ref<GLTFState> state, const GLTFNodeIndex node_index);
Node3D *_generate_spatial(Ref<GLTFState> state, const GLTFNodeIndex node_index);
void _assign_scene_names(Ref<GLTFState> state);
template <class T>
@@ -265,7 +265,7 @@ private:
Dictionary _serialize_texture_transform_uv2(Ref<BaseMaterial3D> p_material);
Error _serialize_version(Ref<GLTFState> state);
Error _serialize_file(Ref<GLTFState> state, const String p_path);
- Error _serialize_extensions(Ref<GLTFState> state) const;
+ Error _serialize_gltf_extensions(Ref<GLTFState> state) const;
public:
// https://www.itu.int/rec/R-REC-BT.601
diff --git a/modules/gltf/gltf_document_extension.cpp b/modules/gltf/gltf_document_extension.cpp
index d0bd7651e0..3b952f8246 100644
--- a/modules/gltf/gltf_document_extension.cpp
+++ b/modules/gltf/gltf_document_extension.cpp
@@ -31,6 +31,7 @@
#include "gltf_document_extension.h"
void GLTFDocumentExtension::_bind_methods() {
+ GDVIRTUAL_BIND(_get_supported_extensions);
GDVIRTUAL_BIND(_import_preflight, "state");
GDVIRTUAL_BIND(_import_post_parse, "state");
GDVIRTUAL_BIND(_import_node, "state", "gltf_node", "json", "node");
@@ -40,6 +41,12 @@ void GLTFDocumentExtension::_bind_methods() {
GDVIRTUAL_BIND(_export_post, "state");
}
+Vector<String> GLTFDocumentExtension::get_supported_extensions() {
+ Vector<String> ret;
+ GDVIRTUAL_CALL(_get_supported_extensions, ret);
+ return ret;
+}
+
Error GLTFDocumentExtension::import_post(Ref<GLTFState> p_state, Node *p_root) {
ERR_FAIL_NULL_V(p_root, ERR_INVALID_PARAMETER);
ERR_FAIL_NULL_V(p_state, ERR_INVALID_PARAMETER);
diff --git a/modules/gltf/gltf_document_extension.h b/modules/gltf/gltf_document_extension.h
index 0ef9109584..d4bb3993dc 100644
--- a/modules/gltf/gltf_document_extension.h
+++ b/modules/gltf/gltf_document_extension.h
@@ -41,6 +41,7 @@ protected:
static void _bind_methods();
public:
+ virtual Vector<String> get_supported_extensions();
virtual Error import_preflight(Ref<GLTFState> p_state);
virtual Error import_post_parse(Ref<GLTFState> p_state);
virtual Error export_post(Ref<GLTFState> p_state);
@@ -48,6 +49,7 @@ public:
virtual Error export_preflight(Node *p_state);
virtual Error import_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_json, Node *p_node);
virtual Error export_node(Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node, Dictionary &r_json, Node *p_node);
+ GDVIRTUAL0R(Vector<String>, _get_supported_extensions);
GDVIRTUAL1R(int, _import_preflight, Ref<GLTFState>);
GDVIRTUAL1R(int, _import_post_parse, Ref<GLTFState>);
GDVIRTUAL4R(int, _import_node, Ref<GLTFState>, Ref<GLTFNode>, Dictionary, Node *);
diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp
index 85bac446cc..a23fb39503 100644
--- a/modules/gltf/gltf_state.cpp
+++ b/modules/gltf/gltf_state.cpp
@@ -31,6 +31,7 @@
#include "gltf_state.h"
void GLTFState::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("add_used_extension", "extension_name", "required"), &GLTFState::add_used_extension);
ClassDB::bind_method(D_METHOD("get_json"), &GLTFState::get_json);
ClassDB::bind_method(D_METHOD("set_json", "json"), &GLTFState::set_json);
ClassDB::bind_method(D_METHOD("get_major_version"), &GLTFState::get_major_version);
@@ -112,6 +113,17 @@ void GLTFState::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_animations", "get_animations"); // Vector<Ref<GLTFAnimation>>
}
+void GLTFState::add_used_extension(const String &p_extension_name, bool p_required) {
+ if (!extensions_used.has(p_extension_name)) {
+ extensions_used.push_back(p_extension_name);
+ }
+ if (p_required) {
+ if (!extensions_required.has(p_extension_name)) {
+ extensions_required.push_back(p_extension_name);
+ }
+ }
+}
+
Dictionary GLTFState::get_json() {
return json;
}
diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h
index 6b2d1ca228..791431f376 100644
--- a/modules/gltf/gltf_state.h
+++ b/modules/gltf/gltf_state.h
@@ -78,6 +78,8 @@ class GLTFState : public Resource {
Vector<int> root_nodes;
Vector<Ref<GLTFTexture>> textures;
Vector<Ref<Texture2D>> images;
+ Vector<String> extensions_used;
+ Vector<String> extensions_required;
Vector<Ref<GLTFSkin>> skins;
Vector<Ref<GLTFCamera>> cameras;
@@ -97,6 +99,8 @@ protected:
static void _bind_methods();
public:
+ void add_used_extension(const String &p_extension, bool p_required = false);
+
Dictionary get_json();
void set_json(Dictionary p_json);
diff --git a/modules/gltf/register_types.h b/modules/gltf/register_types.h
index 90b9a83c88..bf2730d2ef 100644
--- a/modules/gltf/register_types.h
+++ b/modules/gltf/register_types.h
@@ -28,7 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef GLTF_REGISTER_TYPES_H
+#define GLTF_REGISTER_TYPES_H
+
#include "modules/register_module_types.h"
void initialize_gltf_module(ModuleInitializationLevel p_level);
void uninitialize_gltf_module(ModuleInitializationLevel p_level);
+
+#endif // GLTF_REGISTER_TYPES_H
diff --git a/modules/gridmap/SCsub b/modules/gridmap/SCsub
index da3f7d4dd9..282d772592 100644
--- a/modules/gridmap/SCsub
+++ b/modules/gridmap/SCsub
@@ -7,5 +7,5 @@ env_gridmap = env_modules.Clone()
# Godot source files
env_gridmap.add_source_files(env.modules_sources, "*.cpp")
-if env["tools"]:
+if env.editor_build:
env_gridmap.add_source_files(env.modules_sources, "editor/*.cpp")
diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml
index ed6cb8656a..0f3662c3cf 100644
--- a/modules/gridmap/doc_classes/GridMap.xml
+++ b/modules/gridmap/doc_classes/GridMap.xml
@@ -57,7 +57,7 @@
<return type="Basis" />
<param index="0" name="position" type="Vector3i" />
<description>
- Returns the basis that gives the specificed cell its orientation.
+ Returns the basis that gives the specified cell its orientation.
</description>
</method>
<method name="get_cell_item_orientation" qualifiers="const">
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index 466a2efd21..05ce2b6147 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -1149,7 +1149,7 @@ TypedArray<Vector3i> GridMap::get_used_cells() const {
TypedArray<Vector3i> GridMap::get_used_cells_by_item(int p_item) const {
TypedArray<Vector3i> a;
for (const KeyValue<IndexKey, Cell> &E : cell_map) {
- if (E.value.item == p_item) {
+ if ((int)E.value.item == p_item) {
Vector3i p(E.key.x, E.key.y, E.key.z);
a.push_back(p);
}
diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp
index e7c6fe592d..6f0bc16a26 100644
--- a/modules/hdr/image_loader_hdr.cpp
+++ b/modules/hdr/image_loader_hdr.cpp
@@ -33,7 +33,7 @@
#include "core/os/os.h"
#include "core/string/print_string.h"
-Error ImageLoaderHDR::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) {
+Error ImageLoaderHDR::load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale) {
String header = f->get_token();
ERR_FAIL_COND_V_MSG(header != "#?RADIANCE" && header != "#?RGBE", ERR_FILE_UNRECOGNIZED, "Unsupported header information in HDR: " + header + ".");
diff --git a/modules/hdr/image_loader_hdr.h b/modules/hdr/image_loader_hdr.h
index 1bff05129b..5f817f0ba8 100644
--- a/modules/hdr/image_loader_hdr.h
+++ b/modules/hdr/image_loader_hdr.h
@@ -35,7 +35,7 @@
class ImageLoaderHDR : public ImageFormatLoader {
public:
- virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale);
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderHDR();
};
diff --git a/modules/hdr/register_types.cpp b/modules/hdr/register_types.cpp
index b988bf4587..18b1a73f1c 100644
--- a/modules/hdr/register_types.cpp
+++ b/modules/hdr/register_types.cpp
@@ -32,14 +32,14 @@
#include "image_loader_hdr.h"
-static ImageLoaderHDR *image_loader_hdr = nullptr;
+static Ref<ImageLoaderHDR> image_loader_hdr;
void initialize_hdr_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}
- image_loader_hdr = memnew(ImageLoaderHDR);
+ image_loader_hdr.instantiate();
ImageLoader::add_image_format_loader(image_loader_hdr);
}
@@ -48,5 +48,6 @@ void uninitialize_hdr_module(ModuleInitializationLevel p_level) {
return;
}
- memdelete(image_loader_hdr);
+ ImageLoader::remove_image_format_loader(image_loader_hdr);
+ image_loader_hdr.unref();
}
diff --git a/modules/jpg/image_loader_jpegd.cpp b/modules/jpg/image_loader_jpegd.cpp
index 3e138bf633..ce20ac9060 100644
--- a/modules/jpg/image_loader_jpegd.cpp
+++ b/modules/jpg/image_loader_jpegd.cpp
@@ -104,7 +104,7 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p
return OK;
}
-Error ImageLoaderJPG::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) {
+Error ImageLoaderJPG::load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale) {
Vector<uint8_t> src_image;
uint64_t src_image_len = f->get_length();
ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
diff --git a/modules/jpg/image_loader_jpegd.h b/modules/jpg/image_loader_jpegd.h
index caa0461d05..f63db51521 100644
--- a/modules/jpg/image_loader_jpegd.h
+++ b/modules/jpg/image_loader_jpegd.h
@@ -35,7 +35,7 @@
class ImageLoaderJPG : public ImageFormatLoader {
public:
- virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale);
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderJPG();
};
diff --git a/modules/jpg/register_types.cpp b/modules/jpg/register_types.cpp
index b8b48a550f..7da216bbe2 100644
--- a/modules/jpg/register_types.cpp
+++ b/modules/jpg/register_types.cpp
@@ -32,14 +32,14 @@
#include "image_loader_jpegd.h"
-static ImageLoaderJPG *image_loader_jpg = nullptr;
+static Ref<ImageLoaderJPG> image_loader_jpg;
void initialize_jpg_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}
- image_loader_jpg = memnew(ImageLoaderJPG);
+ image_loader_jpg.instantiate();
ImageLoader::add_image_format_loader(image_loader_jpg);
}
@@ -48,5 +48,6 @@ void uninitialize_jpg_module(ModuleInitializationLevel p_level) {
return;
}
- memdelete(image_loader_jpg);
+ ImageLoader::remove_image_format_loader(image_loader_jpg);
+ image_loader_jpg.unref();
}
diff --git a/modules/minimp3/audio_stream_mp3.cpp b/modules/minimp3/audio_stream_mp3.cpp
index 98bcdea8f4..acb92b25e1 100644
--- a/modules/minimp3/audio_stream_mp3.cpp
+++ b/modules/minimp3/audio_stream_mp3.cpp
@@ -104,7 +104,7 @@ float AudioStreamPlaybackMP3::get_stream_sampling_rate() {
return mp3_stream->sample_rate;
}
-void AudioStreamPlaybackMP3::start(float p_from_pos) {
+void AudioStreamPlaybackMP3::start(double p_from_pos) {
active = true;
seek(p_from_pos);
loops = 0;
@@ -123,11 +123,11 @@ int AudioStreamPlaybackMP3::get_loop_count() const {
return loops;
}
-float AudioStreamPlaybackMP3::get_playback_position() const {
- return float(frames_mixed) / mp3_stream->sample_rate;
+double AudioStreamPlaybackMP3::get_playback_position() const {
+ return double(frames_mixed) / mp3_stream->sample_rate;
}
-void AudioStreamPlaybackMP3::seek(float p_time) {
+void AudioStreamPlaybackMP3::seek(double p_time) {
if (!active) {
return;
}
@@ -217,15 +217,15 @@ bool AudioStreamMP3::has_loop() const {
return loop;
}
-void AudioStreamMP3::set_loop_offset(float p_seconds) {
+void AudioStreamMP3::set_loop_offset(double p_seconds) {
loop_offset = p_seconds;
}
-float AudioStreamMP3::get_loop_offset() const {
+double AudioStreamMP3::get_loop_offset() const {
return loop_offset;
}
-float AudioStreamMP3::get_length() const {
+double AudioStreamMP3::get_length() const {
return length;
}
diff --git a/modules/minimp3/audio_stream_mp3.h b/modules/minimp3/audio_stream_mp3.h
index 428ac1240e..c34c1dc5fa 100644
--- a/modules/minimp3/audio_stream_mp3.h
+++ b/modules/minimp3/audio_stream_mp3.h
@@ -61,14 +61,14 @@ protected:
virtual float get_stream_sampling_rate() override;
public:
- virtual void start(float p_from_pos = 0.0) override;
+ virtual void start(double p_from_pos = 0.0) override;
virtual void stop() override;
virtual bool is_playing() const override;
virtual int get_loop_count() const override; //times it looped
- virtual float get_playback_position() const override;
- virtual void seek(float p_time) override;
+ virtual double get_playback_position() const override;
+ virtual void seek(double p_time) override;
virtual void tag_used_streams() override;
@@ -104,8 +104,8 @@ public:
void set_loop(bool p_enable);
virtual bool has_loop() const override;
- void set_loop_offset(float p_seconds);
- float get_loop_offset() const;
+ void set_loop_offset(double p_seconds);
+ double get_loop_offset() const;
void set_bpm(double p_bpm);
virtual double get_bpm() const override;
@@ -122,7 +122,7 @@ public:
void set_data(const Vector<uint8_t> &p_data);
Vector<uint8_t> get_data() const;
- virtual float get_length() const override;
+ virtual double get_length() const override;
virtual bool is_monophonic() const override;
diff --git a/modules/mono/SCsub b/modules/mono/SCsub
index 7764ba0b45..a4667f784d 100644
--- a/modules/mono/SCsub
+++ b/modules/mono/SCsub
@@ -26,6 +26,6 @@ if env["platform"] in ["macos", "ios"]:
elif env["platform"] == "android":
env_mono.add_source_files(env.modules_sources, "mono_gd/android_mono_config.gen.cpp")
-if env["tools"]:
+if env.editor_build:
env_mono.add_source_files(env.modules_sources, "editor/*.cpp")
SConscript("editor/script_templates/SCsub")
diff --git a/modules/mono/build_scripts/build_assemblies.py b/modules/mono/build_scripts/build_assemblies.py
index 6f66ce9efa..d28c3a0c3a 100755
--- a/modules/mono/build_scripts/build_assemblies.py
+++ b/modules/mono/build_scripts/build_assemblies.py
@@ -5,6 +5,7 @@ import os.path
import shlex
import subprocess
from dataclasses import dataclass
+from typing import Optional, List
def find_dotnet_cli():
@@ -150,10 +151,7 @@ def find_any_msbuild_tool(mono_prefix):
return None
-def run_msbuild(tools: ToolsLocation, sln: str, msbuild_args: [str] = None):
- if msbuild_args is None:
- msbuild_args = []
-
+def run_msbuild(tools: ToolsLocation, sln: str, msbuild_args: Optional[List[str]] = None):
using_msbuild_mono = False
# Preference order: dotnet CLI > Standalone MSBuild > Mono's MSBuild
@@ -169,7 +167,7 @@ def run_msbuild(tools: ToolsLocation, sln: str, msbuild_args: [str] = None):
args += [sln]
- if len(msbuild_args) > 0:
+ if msbuild_args:
args += msbuild_args
print("Running MSBuild: ", " ".join(shlex.quote(arg) for arg in args), flush=True)
@@ -315,6 +313,8 @@ def main():
output_dir = os.path.abspath(args.godot_output_dir)
+ push_nupkgs_local = os.path.abspath(args.push_nupkgs_local) if args.push_nupkgs_local else None
+
msbuild_tool = find_any_msbuild_tool(args.mono_prefix)
if msbuild_tool is None:
@@ -327,7 +327,7 @@ def main():
output_dir,
args.godot_platform,
args.dev_debug,
- args.push_nupkgs_local,
+ push_nupkgs_local,
args.float,
)
sys.exit(exit_code)
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py
index 5d63773096..5cec8f41f5 100644
--- a/modules/mono/build_scripts/mono_configure.py
+++ b/modules/mono/build_scripts/mono_configure.py
@@ -20,10 +20,7 @@ def configure(env, env_mono):
# is_ios = env["platform"] == "ios"
# is_ios_sim = is_ios and env["arch"] in ["x86_32", "x86_64"]
- tools_enabled = env["tools"]
-
- if tools_enabled and not module_supports_tools_on(env["platform"]):
- raise RuntimeError("This module does not currently support building for this platform with tools enabled")
-
- if env["tools"]:
+ if env.editor_build:
+ if not module_supports_tools_on(env["platform"]):
+ raise RuntimeError("This module does not currently support building for this platform for editor builds.")
env_mono.Append(CPPDEFINES=["GD_MONO_HOT_RELOAD"])
diff --git a/modules/mono/config.py b/modules/mono/config.py
index 15fe79ef8c..a36083b64b 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -7,7 +7,7 @@ def can_build(env, platform):
if env["arch"].startswith("rv"):
return False
- if env["tools"]:
+ if env.editor_build:
env.module_add_dependencies("mono", ["regex"])
return True
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 8fd3626a20..97a1d5c8d8 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -1299,7 +1299,7 @@ GDNativeBool CSharpLanguage::_instance_binding_reference_callback(void *p_token,
MonoGCHandleData &gchandle = script_binding.gchandle;
- int refcount = rc_owner->reference_get_count();
+ int refcount = rc_owner->get_reference_count();
if (!script_binding.inited) {
return refcount == 0;
@@ -1818,7 +1818,7 @@ void CSharpInstance::refcount_incremented() {
RefCounted *rc_owner = Object::cast_to<RefCounted>(owner);
- if (rc_owner->reference_get_count() > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
+ if (rc_owner->get_reference_count() > 1 && gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
// The reference count was increased after the managed side was the only one referencing our owner.
// This means the owner is being referenced again by the unmanaged side,
// so the owner must hold the managed side alive again to avoid it from being GCed.
@@ -1849,7 +1849,7 @@ bool CSharpInstance::refcount_decremented() {
RefCounted *rc_owner = Object::cast_to<RefCounted>(owner);
- int refcount = rc_owner->reference_get_count();
+ int refcount = rc_owner->get_reference_count();
if (refcount == 1 && !gchandle.is_weak()) { // The managed side also holds a reference, hence 1 instead of 0
// If owner owner is no longer referenced by the unmanaged side,
@@ -1995,7 +1995,7 @@ CSharpInstance::~CSharpInstance() {
#ifdef DEBUG_ENABLED
// The "instance binding" holds a reference so the refcount should be at least 2 before `scope_keep_owner_alive` goes out of scope
- CRASH_COND(rc_owner->reference_get_count() <= 1);
+ CRASH_COND(rc_owner->get_reference_count() <= 1);
#endif
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/EventHandlerSuffixSuppressor.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/EventHandlerSuffixSuppressor.cs
new file mode 100644
index 0000000000..ddde730fa2
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/EventHandlerSuffixSuppressor.cs
@@ -0,0 +1,53 @@
+using System.Collections.Immutable;
+using System.Linq;
+using System.Threading;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Diagnostics;
+
+namespace Godot.SourceGenerators
+{
+ [DiagnosticAnalyzer(LanguageNames.CSharp)]
+ public class EventHandlerSuffixSuppressor : DiagnosticSuppressor
+ {
+ private static readonly SuppressionDescriptor _descriptor = new(
+ id: "GDSP0001",
+ suppressedDiagnosticId: "CA1711",
+ justification: "Signal delegates are used in events so the naming follows the guidelines.");
+
+ public override ImmutableArray<SuppressionDescriptor> SupportedSuppressions =>
+ ImmutableArray.Create(_descriptor);
+
+ public override void ReportSuppressions(SuppressionAnalysisContext context)
+ {
+ foreach (var diagnostic in context.ReportedDiagnostics)
+ {
+ AnalyzeDiagnostic(context, diagnostic, context.CancellationToken);
+ }
+ }
+
+ private static void AnalyzeDiagnostic(SuppressionAnalysisContext context, Diagnostic diagnostic, CancellationToken cancellationToken = default)
+ {
+ var location = diagnostic.Location;
+ var root = location.SourceTree?.GetRoot(cancellationToken);
+ var dds = root?
+ .FindNode(location.SourceSpan)
+ .DescendantNodesAndSelf()
+ .OfType<DelegateDeclarationSyntax>()
+ .FirstOrDefault();
+
+ if (dds == null)
+ return;
+
+ var semanticModel = context.GetSemanticModel(dds.SyntaxTree);
+ var delegateSymbol = semanticModel.GetDeclaredSymbol(dds, cancellationToken);
+ if (delegateSymbol == null)
+ return;
+
+ if (delegateSymbol.GetAttributes().Any(a => a.AttributeClass?.IsGodotSignalAttribute() ?? false))
+ {
+ context.ReportSuppression(Suppression.Create(_descriptor, diagnostic));
+ }
+ }
+ }
+}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
index de3b6c862a..8de12de23b 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
@@ -29,7 +29,7 @@ namespace Godot.SourceGenerators
{
while (symbol != null)
{
- if (symbol.ContainingAssembly.Name == assemblyName &&
+ if (symbol.ContainingAssembly?.Name == assemblyName &&
symbol.ToString() == typeFullName)
{
return true;
@@ -47,7 +47,7 @@ namespace Godot.SourceGenerators
while (symbol != null)
{
- if (symbol.ContainingAssembly.Name == "GodotSharp")
+ if (symbol.ContainingAssembly?.Name == "GodotSharp")
return symbol;
symbol = symbol.BaseType;
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
index efdd50098e..bd40675fd3 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
@@ -124,8 +124,8 @@ namespace Godot.SourceGenerators
if (typeKind == TypeKind.Struct)
{
- if (type.ContainingAssembly.Name == "GodotSharp" &&
- type.ContainingNamespace.Name == "Godot")
+ if (type.ContainingAssembly?.Name == "GodotSharp" &&
+ type.ContainingNamespace?.Name == "Godot")
{
return type switch
{
@@ -156,6 +156,10 @@ namespace Godot.SourceGenerators
else if (typeKind == TypeKind.Array)
{
var arrayType = (IArrayTypeSymbol)type;
+
+ if (arrayType.Rank != 1)
+ return null;
+
var elementType = arrayType.ElementType;
switch (elementType.SpecialType)
@@ -177,8 +181,8 @@ namespace Godot.SourceGenerators
if (elementType.SimpleDerivesFrom(typeCache.GodotObjectType))
return MarshalType.GodotObjectOrDerivedArray;
- if (elementType.ContainingAssembly.Name == "GodotSharp" &&
- elementType.ContainingNamespace.Name == "Godot")
+ if (elementType.ContainingAssembly?.Name == "GodotSharp" &&
+ elementType.ContainingNamespace?.Name == "Godot")
{
switch (elementType)
{
@@ -204,9 +208,9 @@ namespace Godot.SourceGenerators
if (type.SimpleDerivesFrom(typeCache.GodotObjectType))
return MarshalType.GodotObjectOrDerived;
- if (type.ContainingAssembly.Name == "GodotSharp")
+ if (type.ContainingAssembly?.Name == "GodotSharp")
{
- switch (type.ContainingNamespace.Name)
+ switch (type.ContainingNamespace?.Name)
{
case "Godot":
return type switch
@@ -216,7 +220,7 @@ namespace Godot.SourceGenerators
_ => null
};
case "Collections"
- when type.ContainingNamespace.FullQualifiedName() == "Godot.Collections":
+ when type.ContainingNamespace?.FullQualifiedName() == "Godot.Collections":
return type switch
{
{ Name: "Dictionary" } =>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
index 1df41a905b..ea7cc3fe38 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
@@ -7,7 +7,7 @@ using Microsoft.CodeAnalysis.Text;
// TODO:
// Determine a proper way to emit the signal.
-// 'Emit(nameof(TheEvent))' creates a StringName everytime and has the overhead of string marshaling.
+// 'Emit(nameof(TheEvent))' creates a StringName every time and has the overhead of string marshaling.
// I haven't decided on the best option yet. Some possibilities:
// - Expose the generated StringName fields to the user, for use with 'Emit(...)'.
// - Generate a 'EmitSignalName' method for each event signal.
@@ -235,6 +235,8 @@ namespace Godot.SourceGenerators
.Append(signalName)
.Append(";\n");
+ source.Append($" /// <inheritdoc cref=\"{signalDelegate.DelegateSymbol.FullQualifiedName()}\"/>\n");
+
source.Append(" public event ")
.Append(signalDelegate.DelegateSymbol.FullQualifiedName())
.Append(" ")
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
index ad4fce8daa..4d40724a83 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildOutputView.cs
@@ -69,51 +69,41 @@ namespace GodotTools.Build
private void LoadIssuesFromFile(string csvFile)
{
- using (var file = new Godot.File())
+ using var file = FileAccess.Open(csvFile, FileAccess.ModeFlags.Read);
+
+ if (file == null)
+ return;
+
+ while (!file.EofReached())
{
- try
- {
- Error openError = file.Open(csvFile, Godot.File.ModeFlags.Read);
+ string[] csvColumns = file.GetCsvLine();
- if (openError != Error.Ok)
- return;
+ if (csvColumns.Length == 1 && string.IsNullOrEmpty(csvColumns[0]))
+ return;
- while (!file.EofReached())
- {
- string[] csvColumns = file.GetCsvLine();
-
- if (csvColumns.Length == 1 && string.IsNullOrEmpty(csvColumns[0]))
- return;
-
- if (csvColumns.Length != 7)
- {
- GD.PushError($"Expected 7 columns, got {csvColumns.Length}");
- continue;
- }
-
- var issue = new BuildIssue
- {
- Warning = csvColumns[0] == "warning",
- File = csvColumns[1],
- Line = int.Parse(csvColumns[2]),
- Column = int.Parse(csvColumns[3]),
- Code = csvColumns[4],
- Message = csvColumns[5],
- ProjectFile = csvColumns[6]
- };
-
- if (issue.Warning)
- WarningCount += 1;
- else
- ErrorCount += 1;
-
- _issues.Add(issue);
- }
- }
- finally
+ if (csvColumns.Length != 7)
{
- file.Close(); // Disposing it is not enough. We need to call Close()
+ GD.PushError($"Expected 7 columns, got {csvColumns.Length}");
+ continue;
}
+
+ var issue = new BuildIssue
+ {
+ Warning = csvColumns[0] == "warning",
+ File = csvColumns[1],
+ Line = int.Parse(csvColumns[2]),
+ Column = int.Parse(csvColumns[3]),
+ Code = csvColumns[4],
+ Message = csvColumns[5],
+ ProjectFile = csvColumns[6]
+ };
+
+ if (issue.Warning)
+ WarningCount += 1;
+ else
+ ErrorCount += 1;
+
+ _issues.Add(issue);
}
}
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index ce4ac9b796..95a44d3b7e 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -2229,6 +2229,15 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
// Generate signal
{
+ p_output.append(MEMBER_BEGIN "/// <summary>\n");
+ p_output.append(INDENT1 "/// ");
+ p_output.append("Represents the method that handles the ");
+ p_output.append("<see cref=\"" BINDINGS_NAMESPACE "." + p_itype.proxy_name + "." + p_isignal.proxy_name + "\"/>");
+ p_output.append(" event of a ");
+ p_output.append("<see cref=\"" BINDINGS_NAMESPACE "." + p_itype.proxy_name + "\"/>");
+ p_output.append(" class.\n");
+ p_output.append(INDENT1 "/// </summary>");
+
if (p_isignal.is_deprecated) {
if (p_isignal.deprecation_message.is_empty()) {
WARN_PRINT("An empty deprecation message is discouraged. Signal: '" + p_isignal.proxy_name + "'.");
diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp
index 6f42ad6916..91392c8f79 100644
--- a/modules/mono/editor/editor_internal_calls.cpp
+++ b/modules/mono/editor/editor_internal_calls.cpp
@@ -152,7 +152,7 @@ bool godot_icall_Internal_ScriptEditorEdit(Resource *p_resource, int32_t p_line,
}
void godot_icall_Internal_EditorNodeShowScriptScreen() {
- EditorNode::get_singleton()->call("_editor_select", EditorNode::EDITOR_SCRIPT);
+ EditorNode::get_singleton()->editor_select(EditorNode::EDITOR_SCRIPT);
}
void godot_icall_Internal_EditorRunPlay() {
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
index 44f951e314..d77baab24b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
@@ -1245,12 +1245,12 @@ namespace Godot
/// <summary>
/// If the string is a path, this concatenates <paramref name="file"/>
/// at the end of the string as a subpath.
- /// E.g. <c>"this/is".PlusFile("path") == "this/is/path"</c>.
+ /// E.g. <c>"this/is".PathJoin("path") == "this/is/path"</c>.
/// </summary>
/// <param name="instance">The path that will be concatenated.</param>
/// <param name="file">File name to concatenate with the path.</param>
/// <returns>The concatenated path with the given file name.</returns>
- public static string PlusFile(this string instance, string file)
+ public static string PathJoin(this string instance, string file)
{
if (instance.Length > 0 && instance[instance.Length - 1] == '/')
return instance + file;
diff --git a/modules/mono/utils/macos_utils.h b/modules/mono/utils/macos_utils.h
index ca4957f5a7..0b74114685 100644
--- a/modules/mono/utils/macos_utils.h
+++ b/modules/mono/utils/macos_utils.h
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "core/string/ustring.h"
-
#ifndef MONO_MACOS_UTILS_H
#define MONO_MACOS_UTILS_H
#ifdef MACOS_ENABLED
+#include "core/string/ustring.h"
+
bool macos_is_app_bundle_installed(const String &p_bundle_id);
#endif
diff --git a/modules/multiplayer/SCsub b/modules/multiplayer/SCsub
index ff33655537..e89038c3e0 100644
--- a/modules/multiplayer/SCsub
+++ b/modules/multiplayer/SCsub
@@ -8,7 +8,7 @@ env_mp = env_modules.Clone()
module_obj = []
env_mp.add_source_files(module_obj, "*.cpp")
-if env["tools"]:
+if env.editor_build:
env_mp.add_source_files(module_obj, "editor/*.cpp")
env.modules_sources += module_obj
diff --git a/modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml b/modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml
index 9a4d755d64..42c190f504 100644
--- a/modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml
+++ b/modules/multiplayer/doc_classes/MultiplayerSynchronizer.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
By default, [MultiplayerSynchronizer] synchronizes configured properties to all peers.
- Visiblity can be handled directly with [method set_visibility_for] or as-needed with [method add_visibility_filter] and [method update_visibility].
+ Visibility can be handled directly with [method set_visibility_for] or as-needed with [method add_visibility_filter] and [method update_visibility].
[MultiplayerSpawner]s will handle nodes according to visibility of synchronizers as long as the node at [member root_path] was spawned by one.
@@ -34,7 +34,7 @@
<return type="void" />
<param index="0" name="filter" type="Callable" />
<description>
- Removes a peer visiblity filter from this synchronizer.
+ Removes a peer visibility filter from this synchronizer.
</description>
</method>
<method name="set_visibility_for">
diff --git a/modules/multiplayer/multiplayer_spawner.cpp b/modules/multiplayer/multiplayer_spawner.cpp
index d46972ffb6..620e4f2f6c 100644
--- a/modules/multiplayer/multiplayer_spawner.cpp
+++ b/modules/multiplayer/multiplayer_spawner.cpp
@@ -86,6 +86,23 @@ void MultiplayerSpawner::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
#endif
+
+PackedStringArray MultiplayerSpawner::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
+
+ if (spawn_path.is_empty() || !has_node(spawn_path)) {
+ warnings.push_back(RTR("A valid NodePath must be set in the \"Spawn Path\" property in order for MultiplayerSpawner to be able to spawn Nodes."));
+ }
+ bool has_scenes = get_spawnable_scene_count() > 0;
+ // Can't check if method is overridden in placeholder scripts.
+ bool has_placeholder_script = get_script_instance() && get_script_instance()->is_placeholder();
+ if (!has_scenes && !GDVIRTUAL_IS_OVERRIDDEN(_spawn_custom) && !has_placeholder_script) {
+ warnings.push_back(RTR("A list of PackedScenes must be set in the \"Auto Spawn List\" property in order for MultiplayerSpawner to automatically spawn them remotely when added as child of \"spawn_path\"."));
+ warnings.push_back(RTR("Alternatively, a Script implementing the function \"_spawn_custom\" must be set for this MultiplayerSpawner, and \"spawn\" must be called explicitly in code."));
+ }
+ return warnings;
+}
+
void MultiplayerSpawner::add_spawnable_scene(const String &p_path) {
SpawnableScene sc;
sc.path = p_path;
@@ -94,13 +111,16 @@ void MultiplayerSpawner::add_spawnable_scene(const String &p_path) {
}
spawnable_scenes.push_back(sc);
}
+
int MultiplayerSpawner::get_spawnable_scene_count() const {
return spawnable_scenes.size();
}
+
String MultiplayerSpawner::get_spawnable_scene(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, (int)spawnable_scenes.size(), "");
return spawnable_scenes[p_idx].path;
}
+
void MultiplayerSpawner::clear_spawnable_scenes() {
spawnable_scenes.clear();
}
diff --git a/modules/multiplayer/multiplayer_spawner.h b/modules/multiplayer/multiplayer_spawner.h
index fc3befc2d4..587c99efd1 100644
--- a/modules/multiplayer/multiplayer_spawner.h
+++ b/modules/multiplayer/multiplayer_spawner.h
@@ -91,6 +91,8 @@ protected:
void _get_property_list(List<PropertyInfo> *p_list) const;
#endif
public:
+ PackedStringArray get_configuration_warnings() const override;
+
Node *get_spawn_node() const {
return spawn_node.is_valid() ? Object::cast_to<Node>(ObjectDB::get_instance(spawn_node)) : nullptr;
}
diff --git a/modules/multiplayer/multiplayer_synchronizer.cpp b/modules/multiplayer/multiplayer_synchronizer.cpp
index eee1495c14..2c3ebccaeb 100644
--- a/modules/multiplayer/multiplayer_synchronizer.cpp
+++ b/modules/multiplayer/multiplayer_synchronizer.cpp
@@ -94,6 +94,16 @@ void MultiplayerSynchronizer::_update_process() {
}
}
+PackedStringArray MultiplayerSynchronizer::get_configuration_warnings() const {
+ PackedStringArray warnings = Node::get_configuration_warnings();
+
+ if (root_path.is_empty() || !has_node(root_path)) {
+ warnings.push_back(RTR("A valid NodePath must be set in the \"Root Path\" property in order for MultiplayerSynchronizer to be able to synchronize properties."));
+ }
+
+ return warnings;
+}
+
Error MultiplayerSynchronizer::get_state(const List<NodePath> &p_properties, Object *p_obj, Vector<Variant> &r_variant, Vector<const Variant *> &r_variant_ptrs) {
ERR_FAIL_COND_V(!p_obj, ERR_INVALID_PARAMETER);
r_variant.resize(p_properties.size());
diff --git a/modules/multiplayer/multiplayer_synchronizer.h b/modules/multiplayer/multiplayer_synchronizer.h
index e84d41db86..f10a95a1d4 100644
--- a/modules/multiplayer/multiplayer_synchronizer.h
+++ b/modules/multiplayer/multiplayer_synchronizer.h
@@ -66,6 +66,8 @@ public:
static Error get_state(const List<NodePath> &p_properties, Object *p_obj, Vector<Variant> &r_variant, Vector<const Variant *> &r_variant_ptrs);
static Error set_state(const List<NodePath> &p_properties, Object *p_obj, const Vector<Variant> &p_state);
+ PackedStringArray get_configuration_warnings() const override;
+
void set_replication_interval(double p_interval);
double get_replication_interval() const;
uint64_t get_replication_interval_msec() const;
diff --git a/modules/multiplayer/scene_replication_interface.cpp b/modules/multiplayer/scene_replication_interface.cpp
index 6e3dbfab47..53d8e82dfc 100644
--- a/modules/multiplayer/scene_replication_interface.cpp
+++ b/modules/multiplayer/scene_replication_interface.cpp
@@ -125,9 +125,12 @@ Error SceneReplicationInterface::on_replication_start(Object *p_obj, Variant p_c
MultiplayerSynchronizer *sync = Object::cast_to<MultiplayerSynchronizer>(p_config.get_validated_object());
ERR_FAIL_COND_V(!sync, ERR_INVALID_PARAMETER);
+ const ObjectID oid = node->get_instance_id();
+ MultiplayerSpawner *spawner = rep_state->get_spawner(oid);
+ ERR_FAIL_COND_V_MSG(spawner && spawner->get_multiplayer_authority() != sync->get_multiplayer_authority(), ERR_INVALID_PARAMETER, "The authority of the MultiplayerSynchronizer \"" + String(sync->get_path()) + "\" differs from the authority of its \"root_node\" spawner and will not sync. Change the \"root_node\" of the MultiplayerSynchronizer to be a child of the scene root instead.");
+
// Add to synchronizer list and setup visibility.
rep_state->config_add_sync(node, sync);
- const ObjectID oid = node->get_instance_id();
sync->connect("visibility_changed", callable_mp(this, &SceneReplicationInterface::_visibility_changed).bind(oid));
if (multiplayer->has_multiplayer_peer() && sync->is_multiplayer_authority()) {
_update_sync_visibility(0, oid);
diff --git a/modules/navigation/SCsub b/modules/navigation/SCsub
index 24a6b12639..0b0822db2d 100644
--- a/modules/navigation/SCsub
+++ b/modules/navigation/SCsub
@@ -57,7 +57,7 @@ env.modules_sources += thirdparty_obj
module_obj = []
env_navigation.add_source_files(module_obj, "*.cpp")
-if env["tools"]:
+if env.editor_build:
env_navigation.add_source_files(module_obj, "editor/*.cpp")
env.modules_sources += module_obj
diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp
index 9e5d666a51..8ca73a3adb 100644
--- a/modules/navigation/godot_navigation_server.cpp
+++ b/modules/navigation/godot_navigation_server.cpp
@@ -810,6 +810,32 @@ void GodotNavigationServer::process(real_t p_delta_time) {
}
}
+NavigationUtilities::PathQueryResult GodotNavigationServer::_query_path(const NavigationUtilities::PathQueryParameters &p_parameters) const {
+ NavigationUtilities::PathQueryResult r_query_result;
+
+ const NavMap *map = map_owner.get_or_null(p_parameters.map);
+ ERR_FAIL_COND_V(map == nullptr, r_query_result);
+
+ // run the pathfinding
+
+ if (p_parameters.pathfinding_algorithm == NavigationUtilities::PathfindingAlgorithm::PATHFINDING_ALGORITHM_ASTAR) {
+ // while postprocessing is still part of map.get_path() need to check and route it here for the correct "optimize" post-processing
+ if (p_parameters.path_postprocessing == NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_CORRIDORFUNNEL) {
+ r_query_result.path = map->get_path(p_parameters.start_position, p_parameters.target_position, true, p_parameters.navigation_layers);
+ } else if (p_parameters.path_postprocessing == NavigationUtilities::PathPostProcessing::PATH_POSTPROCESSING_EDGECENTERED) {
+ r_query_result.path = map->get_path(p_parameters.start_position, p_parameters.target_position, false, p_parameters.navigation_layers);
+ }
+ } else {
+ return r_query_result;
+ }
+
+ // add path postprocessing
+
+ // add path stats
+
+ return r_query_result;
+}
+
#undef COMMAND_1
#undef COMMAND_2
#undef COMMAND_4
diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h
index e6ef7e3bb1..ab5e722d35 100644
--- a/modules/navigation/godot_navigation_server.h
+++ b/modules/navigation/godot_navigation_server.h
@@ -175,6 +175,8 @@ public:
void flush_queries();
virtual void process(real_t p_delta_time) override;
+
+ virtual NavigationUtilities::PathQueryResult _query_path(const NavigationUtilities::PathQueryParameters &p_parameters) const override;
};
#undef COMMAND_1
diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp
index 100db9bc82..394c32f20d 100644
--- a/modules/navigation/nav_map.cpp
+++ b/modules/navigation/nav_map.cpp
@@ -140,20 +140,17 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
// This is an implementation of the A* algorithm.
int least_cost_id = 0;
+ int prev_least_cost_id = -1;
bool found_route = false;
const gd::Polygon *reachable_end = nullptr;
float reachable_d = 1e30;
bool is_reachable = true;
- gd::NavigationPoly *prev_least_cost_poly = nullptr;
-
while (true) {
// Takes the current least_cost_poly neighbors (iterating over its edges) and compute the traveled_distance.
for (size_t i = 0; i < navigation_polys[least_cost_id].poly->edges.size(); i++) {
- gd::NavigationPoly *least_cost_poly = &navigation_polys[least_cost_id];
-
- const gd::Edge &edge = least_cost_poly->poly->edges[i];
+ const gd::Edge &edge = navigation_polys[least_cost_id].poly->edges[i];
// Iterate over connections in this edge, then compute the new optimized travel distance assigned to this polygon.
for (int connection_index = 0; connection_index < edge.connections.size(); connection_index++) {
@@ -164,17 +161,18 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
continue;
}
+ const gd::NavigationPoly &least_cost_poly = navigation_polys[least_cost_id];
float poly_enter_cost = 0.0;
- float poly_travel_cost = least_cost_poly->poly->owner->get_travel_cost();
+ float poly_travel_cost = least_cost_poly.poly->owner->get_travel_cost();
- if (prev_least_cost_poly != nullptr && (prev_least_cost_poly->poly->owner->get_self() != least_cost_poly->poly->owner->get_self())) {
- poly_enter_cost = least_cost_poly->poly->owner->get_enter_cost();
+ if (prev_least_cost_id != -1 && (navigation_polys[prev_least_cost_id].poly->owner->get_self() != least_cost_poly.poly->owner->get_self())) {
+ poly_enter_cost = least_cost_poly.poly->owner->get_enter_cost();
}
- prev_least_cost_poly = least_cost_poly;
+ prev_least_cost_id = least_cost_id;
Vector3 pathway[2] = { connection.pathway_start, connection.pathway_end };
- const Vector3 new_entry = Geometry3D::get_closest_point_to_segment(least_cost_poly->entry, pathway);
- const float new_distance = (least_cost_poly->entry.distance_to(new_entry) * poly_travel_cost) + poly_enter_cost + least_cost_poly->traveled_distance;
+ const Vector3 new_entry = Geometry3D::get_closest_point_to_segment(least_cost_poly.entry, pathway);
+ const float new_distance = (least_cost_poly.entry.distance_to(new_entry) * poly_travel_cost) + poly_enter_cost + least_cost_poly.traveled_distance;
int64_t already_visited_polygon_index = navigation_polys.find(gd::NavigationPoly(connection.polygon));
diff --git a/modules/openxr/SCsub b/modules/openxr/SCsub
index 593d1ff3c1..d4469b110b 100644
--- a/modules/openxr/SCsub
+++ b/modules/openxr/SCsub
@@ -18,38 +18,36 @@ env_openxr.Prepend(
thirdparty_dir + "/src",
thirdparty_dir + "/src/common",
thirdparty_dir + "/src/external/jsoncpp/include",
- thirdparty_dir + "/src/loader",
]
)
-# may need to check and set:
-# - XR_USE_TIMESPEC
-
-env_thirdparty = env_openxr.Clone()
-env_thirdparty.disable_warnings()
-env_thirdparty.AppendUnique(CPPDEFINES=["DISABLE_STD_FILESYSTEM"])
-
if env["platform"] == "android":
# may need to set OPENXR_ANDROID_VERSION_SUFFIX
- env_thirdparty.AppendUnique(CPPDEFINES=["XR_OS_ANDROID", "XR_USE_PLATFORM_ANDROID"])
+ env_openxr.AppendUnique(CPPDEFINES=["XR_OS_ANDROID", "XR_USE_PLATFORM_ANDROID"])
+ env_openxr.AppendUnique(CPPDEFINES=["JSON_USE_EXCEPTION=0"])
# may need to include java parts of the openxr loader
elif env["platform"] == "linuxbsd":
- env_thirdparty.AppendUnique(CPPDEFINES=["XR_OS_LINUX"])
+ env_openxr.AppendUnique(CPPDEFINES=["XR_OS_LINUX"])
if env["x11"]:
- env_thirdparty.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_XLIB"])
+ env_openxr.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_XLIB"])
# FIXME: Review what needs to be set for Android and macOS.
- env_thirdparty.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"])
+ env_openxr.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"])
elif env["platform"] == "windows":
- env_thirdparty.AppendUnique(CPPDEFINES=["XR_OS_WINDOWS", "NOMINMAX", "XR_USE_PLATFORM_WIN32"])
+ env_openxr.AppendUnique(CPPDEFINES=["XR_OS_WINDOWS", "NOMINMAX", "XR_USE_PLATFORM_WIN32"])
-env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/xr_generated_dispatch_table.c")
+# may need to check and set:
+# - XR_USE_TIMESPEC
-# add in common files (hope these don't clash with us)
-env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/common/filesystem_utils.cpp")
-env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/common/object_info.cpp")
+env_thirdparty = env_openxr.Clone()
+env_thirdparty.disable_warnings()
+env_thirdparty.AppendUnique(CPPDEFINES=["DISABLE_STD_FILESYSTEM"])
+
+if "-fno-exceptions" in env_thirdparty["CXXFLAGS"]:
+ env_thirdparty["CXXFLAGS"].remove("-fno-exceptions")
+env_thirdparty.Append(CPPPATH=[thirdparty_dir + "/src/loader"])
# add in external jsoncpp dependency
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/jsoncpp/src/lib_json/json_reader.cpp")
@@ -57,17 +55,24 @@ env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/external/jsoncpp/src/lib_json/json_writer.cpp")
# add in load
-if env["platform"] == "android":
- env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/android_utilities.cpp")
-
-env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/api_layer_interface.cpp")
-env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/loader_core.cpp")
-env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/loader_instance.cpp")
-env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/loader_logger_recorders.cpp")
-env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/loader_logger.cpp")
-env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/manifest_file.cpp")
-env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/runtime_interface.cpp")
-env_thirdparty.add_source_files(thirdparty_obj, thirdparty_dir + "/src/loader/xr_generated_loader.cpp")
+if env["platform"] != "android":
+ # On Android the openxr_loader is provided by separate plugins for each device
+ # Build the engine using object files
+ khrloader_obj = []
+ env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/xr_generated_dispatch_table.c")
+
+ env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/common/filesystem_utils.cpp")
+ env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/common/object_info.cpp")
+
+ env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/api_layer_interface.cpp")
+ env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_core.cpp")
+ env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_instance.cpp")
+ env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_logger_recorders.cpp")
+ env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/loader_logger.cpp")
+ env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/manifest_file.cpp")
+ env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/runtime_interface.cpp")
+ env_thirdparty.add_source_files(khrloader_obj, thirdparty_dir + "/src/loader/xr_generated_loader.cpp")
+ env.modules_sources += khrloader_obj
env.modules_sources += thirdparty_obj
@@ -78,6 +83,7 @@ module_obj = []
env_openxr.add_source_files(module_obj, "*.cpp")
env_openxr.add_source_files(module_obj, "action_map/*.cpp")
+env_openxr.add_source_files(module_obj, "scene/*.cpp")
# We're a little more targeted with our extensions
if env["platform"] == "android":
@@ -85,11 +91,14 @@ if env["platform"] == "android":
if env["vulkan"]:
env_openxr.add_source_files(module_obj, "extensions/openxr_vulkan_extension.cpp")
+env_openxr.add_source_files(module_obj, "extensions/openxr_palm_pose_extension.cpp")
env_openxr.add_source_files(module_obj, "extensions/openxr_htc_vive_tracker_extension.cpp")
+env_openxr.add_source_files(module_obj, "extensions/openxr_hand_tracking_extension.cpp")
+env_openxr.add_source_files(module_obj, "extensions/openxr_fb_passthrough_extension_wrapper.cpp")
env.modules_sources += module_obj
-if env["tools"]:
+if env.editor_build:
SConscript("editor/SCsub")
# Needed to force rebuilding the module files when the thirdparty library is updated.
diff --git a/modules/openxr/action_map/openxr_action_map.cpp b/modules/openxr/action_map/openxr_action_map.cpp
index 0eb5302442..185e44c29d 100644
--- a/modules/openxr/action_map/openxr_action_map.cpp
+++ b/modules/openxr/action_map/openxr_action_map.cpp
@@ -157,7 +157,11 @@ void OpenXRActionMap::remove_interaction_profile(Ref<OpenXRInteractionProfile> p
}
void OpenXRActionMap::create_default_action_sets() {
- // Note, if you make changes here make sure to delete your default_action_map.tres file of it will load an old version.
+ // Note:
+ // - if you make changes here make sure to delete your default_action_map.tres file of it will load an old version.
+ // - our palm pose is only available if the relevant extension is supported,
+ // we still want it to be part of our action map as we may deploy the same game to platforms that do and don't support it.
+ // - the same applies for interaction profiles that are only supported if the relevant extension is supported.
// Create our Godot action set
Ref<OpenXRActionSet> action_set = OpenXRActionSet::new_action_set("godot", "Godot action set");
@@ -200,6 +204,7 @@ void OpenXRActionMap::create_default_action_sets() {
"/user/vive_tracker_htcx/role/keyboard");
Ref<OpenXRAction> aim_pose = action_set->add_new_action("aim_pose", "Aim pose", OpenXRAction::OPENXR_ACTION_POSE, "/user/hand/left,/user/hand/right");
Ref<OpenXRAction> grip_pose = action_set->add_new_action("grip_pose", "Grip pose", OpenXRAction::OPENXR_ACTION_POSE, "/user/hand/left,/user/hand/right");
+ Ref<OpenXRAction> palm_pose = action_set->add_new_action("palm_pose", "Palm pose", OpenXRAction::OPENXR_ACTION_POSE, "/user/hand/left,/user/hand/right");
Ref<OpenXRAction> haptic = action_set->add_new_action("haptic", "Haptic", OpenXRAction::OPENXR_ACTION_HAPTIC,
"/user/hand/left,"
"/user/hand/right,"
@@ -222,6 +227,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
profile->add_new_binding(select_button, "/user/hand/left/input/select/click,/user/hand/right/input/select/click");
// generic has no support for triggers, grip, A/B buttons, nor joystick/trackpad inputs
@@ -233,6 +239,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
profile->add_new_binding(select_button, "/user/hand/left/input/system/click,/user/hand/right/input/system/click");
// wmr controller has no a/b/x/y buttons
@@ -253,6 +260,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
// wmr controllers have no select button we can use
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
// wmr controller has no a/b/x/y buttons
@@ -275,6 +283,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
// touch controllers have no select button we can use
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/system/click"); // right hand system click may not be available
profile->add_new_binding(ax_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand
@@ -299,6 +308,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
// index controllers have no select button we can use
profile->add_new_binding(menu_button, "/user/hand/left/input/system/click,/user/hand/right/input/system/click");
profile->add_new_binding(ax_button, "/user/hand/left/input/a/click,/user/hand/right/input/a/click"); // a on both controllers
@@ -321,16 +331,12 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(haptic, "/user/hand/left/output/haptic,/user/hand/right/output/haptic");
add_interaction_profile(profile);
- // Note, the following profiles are all part of extensions.
- // We include these regardless of whether the extension is active.
- // We want our action map to be as complete as possible so our game is as portable as possible.
- // It is very possible these will in due time become core.
-
// Create our HP MR controller profile
profile = OpenXRInteractionProfile::new_profile("/interaction_profiles/hp/mixed_reality_controller");
profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
// hpmr controllers have no select button we can use
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
// hpmr controllers only register click, not touch, on our a/b/x/y buttons
@@ -353,6 +359,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
// Odyssey controllers have no select button we can use
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click,/user/hand/right/input/menu/click");
// Odyssey controller has no a/b/x/y buttons
@@ -375,6 +382,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click");
profile->add_new_binding(select_button, "/user/hand/left/input/system/click"); // we'll map system to select
profile->add_new_binding(ax_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand
@@ -398,6 +406,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
profile->add_new_binding(menu_button, "/user/hand/left/input/menu/click");
profile->add_new_binding(select_button, "/user/hand/left/input/system/click"); // we'll map system to select
profile->add_new_binding(ax_button, "/user/hand/left/input/x/click,/user/hand/right/input/a/click"); // x on left hand, a on right hand
@@ -421,6 +430,7 @@ void OpenXRActionMap::create_default_action_sets() {
profile->add_new_binding(default_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
profile->add_new_binding(aim_pose, "/user/hand/left/input/aim/pose,/user/hand/right/input/aim/pose");
profile->add_new_binding(grip_pose, "/user/hand/left/input/grip/pose,/user/hand/right/input/grip/pose");
+ profile->add_new_binding(palm_pose, "/user/hand/left/input/palm_ext/pose,/user/hand/right/input/palm_ext/pose");
profile->add_new_binding(menu_button, "/user/hand/left/input/home/click,/user/hand/right/input/home/click");
profile->add_new_binding(trigger, "/user/hand/left/input/trigger/value,/user/hand/right/input/trigger/value");
profile->add_new_binding(trigger_click, "/user/hand/left/input/trigger/click,/user/hand/right/input/trigger/click");
diff --git a/modules/openxr/action_map/openxr_defs.cpp b/modules/openxr/action_map/openxr_defs.cpp
index 89860199be..59ce829f1b 100644
--- a/modules/openxr/action_map/openxr_defs.cpp
+++ b/modules/openxr/action_map/openxr_defs.cpp
@@ -62,6 +62,8 @@ OpenXRDefs::IOPath OpenXRDefs::simple_io_paths[] = {
{ "Grip pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/grip/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Menu click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/menu/click", OpenXRAction::OPENXR_ACTION_BOOL },
{ "Menu click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/menu/click", OpenXRAction::OPENXR_ACTION_BOOL },
@@ -78,6 +80,8 @@ OpenXRDefs::IOPath OpenXRDefs::vive_io_paths[] = {
{ "Grip pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/grip/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Menu click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/menu/click", OpenXRAction::OPENXR_ACTION_BOOL },
{ "Menu click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/menu/click", OpenXRAction::OPENXR_ACTION_BOOL },
@@ -109,6 +113,8 @@ OpenXRDefs::IOPath OpenXRDefs::motion_io_paths[] = {
{ "Grip pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/grip/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Menu click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/menu/click", OpenXRAction::OPENXR_ACTION_BOOL },
{ "Menu click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/menu/click", OpenXRAction::OPENXR_ACTION_BOOL },
@@ -143,6 +149,8 @@ OpenXRDefs::IOPath OpenXRDefs::hpmr_io_paths[] = {
{ "Grip pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/grip/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Menu click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/menu/click", OpenXRAction::OPENXR_ACTION_BOOL },
{ "Menu click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/menu/click", OpenXRAction::OPENXR_ACTION_BOOL },
@@ -175,6 +183,8 @@ OpenXRDefs::IOPath OpenXRDefs::touch_io_paths[] = {
{ "Grip pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/grip/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Menu click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/menu/click", OpenXRAction::OPENXR_ACTION_BOOL },
{ "System click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/system/click", OpenXRAction::OPENXR_ACTION_BOOL },
@@ -213,6 +223,8 @@ OpenXRDefs::IOPath OpenXRDefs::index_io_paths[] = {
{ "Grip pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/grip/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "System click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/system/click", OpenXRAction::OPENXR_ACTION_BOOL },
{ "System click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/system/click", OpenXRAction::OPENXR_ACTION_BOOL },
@@ -260,6 +272,8 @@ OpenXRDefs::IOPath OpenXRDefs::odyssey_io_paths[] = {
{ "Grip pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/grip/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Menu click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/menu/click", OpenXRAction::OPENXR_ACTION_BOOL },
{ "Menu click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/menu/click", OpenXRAction::OPENXR_ACTION_BOOL },
@@ -294,6 +308,8 @@ OpenXRDefs::IOPath OpenXRDefs::vive_cosmos_paths[] = {
{ "Grip pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/grip/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Menu click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/menu/click", OpenXRAction::OPENXR_ACTION_BOOL },
{ "System click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/system/click", OpenXRAction::OPENXR_ACTION_BOOL },
@@ -331,6 +347,8 @@ OpenXRDefs::IOPath OpenXRDefs::vive_focus3_paths[] = {
{ "Grip pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/grip/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Menu click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/menu/click", OpenXRAction::OPENXR_ACTION_BOOL },
{ "System click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/system/click", OpenXRAction::OPENXR_ACTION_BOOL },
@@ -371,6 +389,8 @@ OpenXRDefs::IOPath OpenXRDefs::huawei_controller_paths[] = {
{ "Grip pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/grip/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Aim pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/aim/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
+ { "Palm pose", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/palm_ext/pose", OpenXRAction::OPENXR_ACTION_POSE },
{ "Home click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_LEFT_HAND], "/user/hand/left/input/home/click", OpenXRAction::OPENXR_ACTION_BOOL },
{ "Home click", &OpenXRDefs::available_top_level_paths[OpenXRDefs::OPENXR_RIGHT_HAND], "/user/hand/right/input/home/click", OpenXRAction::OPENXR_ACTION_BOOL },
diff --git a/modules/openxr/config.py b/modules/openxr/config.py
index f91cb1359f..279168cc59 100644
--- a/modules/openxr/config.py
+++ b/modules/openxr/config.py
@@ -1,7 +1,5 @@
def can_build(env, platform):
- if (
- platform == "linuxbsd" or platform == "windows"
- ): # or platform == "android" -- temporarily disabled android support
+ if platform in ("linuxbsd", "windows", "android"):
return env["openxr"]
else:
# not supported on these platforms
@@ -20,6 +18,7 @@ def get_doc_classes():
"OpenXRActionMap",
"OpenXRInteractionProfile",
"OpenXRIPBinding",
+ "OpenXRHand",
]
diff --git a/modules/openxr/doc_classes/OpenXRHand.xml b/modules/openxr/doc_classes/OpenXRHand.xml
new file mode 100644
index 0000000000..5d5f8a6126
--- /dev/null
+++ b/modules/openxr/doc_classes/OpenXRHand.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="OpenXRHand" inherits="Node3D" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
+ <brief_description>
+ Node supporting finger tracking in OpenXR.
+ </brief_description>
+ <description>
+ This node enables OpenXR's hand tracking functionality. The node should be a child node of an [XROrigin3D] node, tracking will update its position to where the player's actual hand is positioned. This node also updates the skeleton of a properly skinned hand model. The hand mesh should be a child node of this node.
+ </description>
+ <tutorials>
+ </tutorials>
+ <members>
+ <member name="hand" type="int" setter="set_hand" getter="get_hand" enum="OpenXRHand.Hands" default="0">
+ Specifies whether this node tracks the left or right hand of the player.
+ </member>
+ <member name="hand_skeleton" type="NodePath" setter="set_hand_skeleton" getter="get_hand_skeleton" default="NodePath(&quot;&quot;)">
+ Set a [Skeleton3D] node for which the pose positions will be updated.
+ </member>
+ <member name="motion_range" type="int" setter="set_motion_range" getter="get_motion_range" enum="OpenXRHand.MotionRange" default="0">
+ Set the motion range (if supported) limiting the hand motion.
+ </member>
+ </members>
+ <constants>
+ <constant name="HAND_LEFT" value="0" enum="Hands">
+ Tracking the player's left hand.
+ </constant>
+ <constant name="HAND_RIGHT" value="1" enum="Hands">
+ Tracking the player's right hand.
+ </constant>
+ <constant name="HAND_MAX" value="2" enum="Hands">
+ Maximum supported hands.
+ </constant>
+ <constant name="MOTION_RANGE_UNOBSTRUCTED" value="0" enum="MotionRange">
+ When player grips, hand skeleton will form a full fist.
+ </constant>
+ <constant name="MOTION_RANGE_CONFORM_TO_CONTROLLER" value="1" enum="MotionRange">
+ When player grips, hand skeleton conforms to the controller the player is holding.
+ </constant>
+ <constant name="MOTION_RANGE_MAX" value="2" enum="MotionRange">
+ Maximum supported motion ranges.
+ </constant>
+ </constants>
+</class>
diff --git a/modules/openxr/extensions/openxr_android_extension.cpp b/modules/openxr/extensions/openxr_android_extension.cpp
index 3bd4db169c..8f6d5c28db 100644
--- a/modules/openxr/extensions/openxr_android_extension.cpp
+++ b/modules/openxr/extensions/openxr_android_extension.cpp
@@ -29,7 +29,12 @@
/*************************************************************************/
#include "openxr_android_extension.h"
+#include "java_godot_wrapper.h"
+#include "os_android.h"
+#include "thread_jandroid.h"
+#include <jni.h>
+#include <modules/openxr/openxr_api.h>
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>
@@ -42,19 +47,16 @@ OpenXRAndroidExtension *OpenXRAndroidExtension::get_singleton() {
OpenXRAndroidExtension::OpenXRAndroidExtension(OpenXRAPI *p_openxr_api) :
OpenXRExtensionWrapper(p_openxr_api) {
singleton = this;
-
request_extensions[XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME] = nullptr; // must be available
+}
- // Initialize the loader
- PFN_xrInitializeLoaderKHR xrInitializeLoaderKHR;
- result = xrGetInstanceProcAddr(XR_NULL_HANDLE, "xrInitializeLoaderKHR", (PFN_xrVoidFunction *)(&xrInitializeLoaderKHR));
- ERR_FAIL_COND_MSG(XR_FAILED(result), "Failed to retrieve pointer to xrInitializeLoaderKHR");
+void OpenXRAndroidExtension::on_before_instance_created() {
+ EXT_INIT_XR_FUNC(xrInitializeLoaderKHR);
- // TODO fix this code, this is still code from GDNative!
- JNIEnv *env = android_api->godot_android_get_env();
+ JNIEnv *env = get_jni_env();
JavaVM *vm;
env->GetJavaVM(&vm);
- jobject activity_object = env->NewGlobalRef(android_api->godot_android_get_activity());
+ jobject activity_object = env->NewGlobalRef(static_cast<OS_Android *>(OS::get_singleton())->get_godot_java()->get_activity());
XrLoaderInitInfoAndroidKHR loader_init_info_android = {
.type = XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR,
@@ -62,7 +64,7 @@ OpenXRAndroidExtension::OpenXRAndroidExtension(OpenXRAPI *p_openxr_api) :
.applicationVM = vm,
.applicationContext = activity_object
};
- xrInitializeLoaderKHR((const XrLoaderInitInfoBaseHeaderKHR *)&loader_init_info_android);
+ XrResult result = xrInitializeLoaderKHR((const XrLoaderInitInfoBaseHeaderKHR *)&loader_init_info_android);
ERR_FAIL_COND_MSG(XR_FAILED(result), "Failed to call xrInitializeLoaderKHR");
}
diff --git a/modules/openxr/extensions/openxr_android_extension.h b/modules/openxr/extensions/openxr_android_extension.h
index 88b0e310e7..eda7022064 100644
--- a/modules/openxr/extensions/openxr_android_extension.h
+++ b/modules/openxr/extensions/openxr_android_extension.h
@@ -31,6 +31,7 @@
#ifndef OPENXR_ANDROID_EXTENSION_H
#define OPENXR_ANDROID_EXTENSION_H
+#include "../util.h"
#include "openxr_extension_wrapper.h"
class OpenXRAndroidExtension : public OpenXRExtensionWrapper {
@@ -38,10 +39,16 @@ public:
static OpenXRAndroidExtension *get_singleton();
OpenXRAndroidExtension(OpenXRAPI *p_openxr_api);
+
+ virtual void on_before_instance_created() override;
+
virtual ~OpenXRAndroidExtension() override;
private:
static OpenXRAndroidExtension *singleton;
+
+ // Initialize the loader
+ EXT_PROTO_XRRESULT_FUNC1(xrInitializeLoaderKHR, (const XrLoaderInitInfoBaseHeaderKHR *), loaderInitInfo)
};
#endif // OPENXR_ANDROID_EXTENSION_H
diff --git a/modules/openxr/extensions/openxr_composition_layer_provider.h b/modules/openxr/extensions/openxr_composition_layer_provider.h
index 019dffa2a8..ba51389f7d 100644
--- a/modules/openxr/extensions/openxr_composition_layer_provider.h
+++ b/modules/openxr/extensions/openxr_composition_layer_provider.h
@@ -36,10 +36,9 @@
// Interface for OpenXR extensions that provide a composition layer.
class OpenXRCompositionLayerProvider {
public:
- // TODO changed to normal method definition for now
- // CI complains until we implement this, haven't ported it yet from plugin
- // virtual XrCompositionLayerBaseHeader *get_composition_layer() = 0;
- XrCompositionLayerBaseHeader *get_composition_layer() { return nullptr; };
+ virtual XrCompositionLayerBaseHeader *get_composition_layer() = 0;
+
+ virtual ~OpenXRCompositionLayerProvider() {}
};
#endif // OPENXR_COMPOSITION_LAYER_PROVIDER_H
diff --git a/modules/openxr/extensions/openxr_extension_wrapper.h b/modules/openxr/extensions/openxr_extension_wrapper.h
index ecc6e0dd4e..623c264e6e 100644
--- a/modules/openxr/extensions/openxr_extension_wrapper.h
+++ b/modules/openxr/extensions/openxr_extension_wrapper.h
@@ -66,6 +66,7 @@ public:
virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) { return p_next_pointer; }
virtual void *set_swapchain_create_info_and_get_next_pointer(void *p_next_pointer) { return p_next_pointer; }
+ virtual void on_before_instance_created() {}
virtual void on_instance_created(const XrInstance p_instance) {}
virtual void on_instance_destroyed() {}
virtual void on_session_created(const XrSession p_instance) {}
@@ -87,6 +88,11 @@ public:
return false;
}
+ // Return false if this extension is responsible for this path but the path is not enabled
+ virtual bool is_path_supported(const String &p_path) {
+ return true;
+ }
+
OpenXRExtensionWrapper(OpenXRAPI *p_openxr_api) { openxr_api = p_openxr_api; };
virtual ~OpenXRExtensionWrapper() = default;
};
diff --git a/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.cpp b/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.cpp
new file mode 100644
index 0000000000..259b1236a3
--- /dev/null
+++ b/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.cpp
@@ -0,0 +1,234 @@
+/*************************************************************************/
+/* openxr_fb_passthrough_extension_wrapper.cpp */
+/*************************************************************************/
+/* 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. */
+/*************************************************************************/
+
+#include "openxr_fb_passthrough_extension_wrapper.h"
+
+#include "core/os/os.h"
+#include "scene/main/viewport.h"
+#include "scene/main/window.h"
+
+using namespace godot;
+
+OpenXRFbPassthroughExtensionWrapper *OpenXRFbPassthroughExtensionWrapper::singleton = nullptr;
+
+OpenXRFbPassthroughExtensionWrapper *OpenXRFbPassthroughExtensionWrapper::get_singleton() {
+ return singleton;
+}
+
+OpenXRFbPassthroughExtensionWrapper::OpenXRFbPassthroughExtensionWrapper(OpenXRAPI *p_openxr_api) :
+ OpenXRExtensionWrapper(p_openxr_api) {
+ request_extensions[XR_FB_PASSTHROUGH_EXTENSION_NAME] = &fb_passthrough_ext;
+ request_extensions[XR_FB_TRIANGLE_MESH_EXTENSION_NAME] = &fb_triangle_mesh_ext;
+ singleton = this;
+}
+
+OpenXRFbPassthroughExtensionWrapper::~OpenXRFbPassthroughExtensionWrapper() {
+ cleanup();
+}
+
+void OpenXRFbPassthroughExtensionWrapper::cleanup() {
+ fb_passthrough_ext = false;
+ fb_triangle_mesh_ext = false;
+}
+
+Viewport *OpenXRFbPassthroughExtensionWrapper::get_main_viewport() {
+ MainLoop *main_loop = OS::get_singleton()->get_main_loop();
+ if (!main_loop) {
+ print_error("Unable to retrieve main loop");
+ return nullptr;
+ }
+
+ auto *scene_tree = Object::cast_to<SceneTree>(main_loop);
+ if (!scene_tree) {
+ print_error("Unable to retrieve scene tree");
+ return nullptr;
+ }
+
+ Viewport *viewport = scene_tree->get_root()->get_viewport();
+ return viewport;
+}
+
+void OpenXRFbPassthroughExtensionWrapper::on_instance_created(const XrInstance instance) {
+ if (fb_passthrough_ext) {
+ bool result = initialize_fb_passthrough_extension(instance);
+ if (!result) {
+ print_error("Failed to initialize fb_passthrough extension");
+ fb_passthrough_ext = false;
+ }
+ }
+
+ if (fb_triangle_mesh_ext) {
+ bool result = initialize_fb_triangle_mesh_extension(instance);
+ if (!result) {
+ print_error("Failed to initialize fb_triangle_mesh extension");
+ fb_triangle_mesh_ext = false;
+ }
+ }
+
+ if (fb_passthrough_ext) {
+ openxr_api->register_composition_layer_provider(this);
+ }
+}
+
+bool OpenXRFbPassthroughExtensionWrapper::is_passthrough_enabled() {
+ return fb_passthrough_ext && passthrough_handle != XR_NULL_HANDLE && passthrough_layer != XR_NULL_HANDLE;
+}
+
+bool OpenXRFbPassthroughExtensionWrapper::is_composition_passthrough_layer_ready() {
+ return fb_passthrough_ext && passthrough_handle != XR_NULL_HANDLE && composition_passthrough_layer.layerHandle != XR_NULL_HANDLE;
+}
+
+bool OpenXRFbPassthroughExtensionWrapper::start_passthrough() {
+ if (passthrough_handle == XR_NULL_HANDLE) {
+ return false;
+ }
+
+ if (is_passthrough_enabled()) {
+ return true;
+ }
+
+ // Start the passthrough feature
+ XrResult result = xrPassthroughStartFB(passthrough_handle);
+ if (!is_valid_passthrough_result(result, "Failed to start passthrough")) {
+ stop_passthrough();
+ return false;
+ }
+
+ // Create the passthrough layer
+ result = xrCreatePassthroughLayerFB(openxr_api->get_session(), &passthrough_layer_config, &passthrough_layer);
+ if (!is_valid_passthrough_result(result, "Failed to create the passthrough layer")) {
+ stop_passthrough();
+ return false;
+ }
+
+ // Check if the the viewport has transparent background
+ Viewport *viewport = get_main_viewport();
+ if (viewport && !viewport->has_transparent_background()) {
+ print_error("Main viewport doesn't have transparent background! Passthrough may not properly render.");
+ }
+
+ composition_passthrough_layer.layerHandle = passthrough_layer;
+
+ return true;
+}
+
+void OpenXRFbPassthroughExtensionWrapper::on_session_created(const XrSession session) {
+ if (fb_passthrough_ext) {
+ // Create the passthrough feature and start it.
+ XrResult result = xrCreatePassthroughFB(openxr_api->get_session(), &passthrough_create_info, &passthrough_handle);
+ if (!openxr_api->xr_result(result, "Failed to create passthrough")) {
+ passthrough_handle = XR_NULL_HANDLE;
+ return;
+ }
+ }
+}
+
+XrCompositionLayerBaseHeader *OpenXRFbPassthroughExtensionWrapper::get_composition_layer() {
+ if (is_composition_passthrough_layer_ready()) {
+ return (XrCompositionLayerBaseHeader *)&composition_passthrough_layer;
+ } else {
+ return nullptr;
+ }
+}
+
+void OpenXRFbPassthroughExtensionWrapper::stop_passthrough() {
+ if (!fb_passthrough_ext) {
+ return;
+ }
+
+ composition_passthrough_layer.layerHandle = XR_NULL_HANDLE;
+
+ XrResult result;
+ if (passthrough_layer != XR_NULL_HANDLE) {
+ // Destroy the layer
+ result = xrDestroyPassthroughLayerFB(passthrough_layer);
+ openxr_api->xr_result(result, "Unable to destroy passthrough layer");
+ passthrough_layer = XR_NULL_HANDLE;
+ }
+
+ if (passthrough_handle != XR_NULL_HANDLE) {
+ result = xrPassthroughPauseFB(passthrough_handle);
+ openxr_api->xr_result(result, "Unable to stop passthrough feature");
+ }
+}
+
+void OpenXRFbPassthroughExtensionWrapper::on_session_destroyed() {
+ if (fb_passthrough_ext) {
+ stop_passthrough();
+
+ XrResult result;
+ if (passthrough_handle != XR_NULL_HANDLE) {
+ result = xrDestroyPassthroughFB(passthrough_handle);
+ openxr_api->xr_result(result, "Unable to destroy passthrough feature");
+ passthrough_handle = XR_NULL_HANDLE;
+ }
+ }
+}
+
+void OpenXRFbPassthroughExtensionWrapper::on_instance_destroyed() {
+ if (fb_passthrough_ext) {
+ openxr_api->unregister_composition_layer_provider(this);
+ }
+ cleanup();
+}
+
+bool OpenXRFbPassthroughExtensionWrapper::initialize_fb_passthrough_extension(const XrInstance p_instance) {
+ ERR_FAIL_NULL_V(openxr_api, false);
+
+ EXT_INIT_XR_FUNC_V(xrCreatePassthroughFB);
+ EXT_INIT_XR_FUNC_V(xrDestroyPassthroughFB);
+ EXT_INIT_XR_FUNC_V(xrPassthroughStartFB);
+ EXT_INIT_XR_FUNC_V(xrPassthroughPauseFB);
+ EXT_INIT_XR_FUNC_V(xrCreatePassthroughLayerFB);
+ EXT_INIT_XR_FUNC_V(xrDestroyPassthroughLayerFB);
+ EXT_INIT_XR_FUNC_V(xrPassthroughLayerPauseFB);
+ EXT_INIT_XR_FUNC_V(xrPassthroughLayerResumeFB);
+ EXT_INIT_XR_FUNC_V(xrPassthroughLayerSetStyleFB);
+ EXT_INIT_XR_FUNC_V(xrCreateGeometryInstanceFB);
+ EXT_INIT_XR_FUNC_V(xrDestroyGeometryInstanceFB);
+ EXT_INIT_XR_FUNC_V(xrGeometryInstanceSetTransformFB);
+
+ return true;
+}
+
+bool OpenXRFbPassthroughExtensionWrapper::initialize_fb_triangle_mesh_extension(const XrInstance p_instance) {
+ ERR_FAIL_NULL_V(openxr_api, false);
+
+ EXT_INIT_XR_FUNC_V(xrCreateTriangleMeshFB);
+ EXT_INIT_XR_FUNC_V(xrDestroyTriangleMeshFB);
+ EXT_INIT_XR_FUNC_V(xrTriangleMeshGetVertexBufferFB);
+ EXT_INIT_XR_FUNC_V(xrTriangleMeshGetIndexBufferFB);
+ EXT_INIT_XR_FUNC_V(xrTriangleMeshBeginUpdateFB);
+ EXT_INIT_XR_FUNC_V(xrTriangleMeshEndUpdateFB);
+ EXT_INIT_XR_FUNC_V(xrTriangleMeshBeginVertexBufferUpdateFB);
+ EXT_INIT_XR_FUNC_V(xrTriangleMeshEndVertexBufferUpdateFB);
+
+ return true;
+}
diff --git a/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.h b/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.h
new file mode 100644
index 0000000000..1959f3fdc4
--- /dev/null
+++ b/modules/openxr/extensions/openxr_fb_passthrough_extension_wrapper.h
@@ -0,0 +1,254 @@
+/*************************************************************************/
+/* openxr_fb_passthrough_extension_wrapper.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 OPENXR_FB_PASSTHROUGH_EXTENSION_WRAPPER_H
+#define OPENXR_FB_PASSTHROUGH_EXTENSION_WRAPPER_H
+
+#include "../openxr_api.h"
+#include "../util.h"
+
+#include "openxr_composition_layer_provider.h"
+#include "openxr_extension_wrapper.h"
+
+#include <map>
+
+class Viewport;
+
+// Wrapper for the set of Facebook XR passthrough extensions.
+class OpenXRFbPassthroughExtensionWrapper : public OpenXRExtensionWrapper, public OpenXRCompositionLayerProvider {
+ friend class OpenXRAPI;
+
+public:
+ void on_instance_created(const XrInstance instance) override;
+
+ void on_session_created(const XrSession session) override;
+
+ void on_session_destroyed() override;
+
+ void on_instance_destroyed() override;
+
+ XrCompositionLayerBaseHeader *get_composition_layer() override;
+
+ bool is_passthrough_supported() {
+ return fb_passthrough_ext;
+ }
+
+ bool is_passthrough_enabled();
+
+ bool start_passthrough();
+
+ void stop_passthrough();
+
+ static OpenXRFbPassthroughExtensionWrapper *get_singleton();
+
+protected:
+ OpenXRFbPassthroughExtensionWrapper(OpenXRAPI *p_openxr_api);
+ ~OpenXRFbPassthroughExtensionWrapper();
+
+private:
+ // Create a passthrough feature
+ EXT_PROTO_XRRESULT_FUNC3(xrCreatePassthroughFB,
+ (XrSession), session,
+ (const XrPassthroughCreateInfoFB *), create_info,
+ (XrPassthroughFB *), feature_out)
+
+ // Destroy a previously created passthrough feature
+ EXT_PROTO_XRRESULT_FUNC1(xrDestroyPassthroughFB, (XrPassthroughFB), feature)
+
+ //*** Passthrough feature state management functions *********
+ // Start the passthrough feature
+ EXT_PROTO_XRRESULT_FUNC1(xrPassthroughStartFB, (XrPassthroughFB), passthrough)
+ // Pause the passthrough feature
+ EXT_PROTO_XRRESULT_FUNC1(xrPassthroughPauseFB, (XrPassthroughFB), passthrough)
+
+ EXT_PROTO_XRRESULT_FUNC3(xrCreatePassthroughLayerFB, (XrSession), session,
+ (const XrPassthroughLayerCreateInfoFB *), config,
+ (XrPassthroughLayerFB *), layer_out)
+
+ EXT_PROTO_XRRESULT_FUNC1(xrDestroyPassthroughLayerFB, (XrPassthroughLayerFB), layer)
+
+ EXT_PROTO_XRRESULT_FUNC1(xrPassthroughLayerPauseFB, (XrPassthroughLayerFB), layer)
+ EXT_PROTO_XRRESULT_FUNC1(xrPassthroughLayerResumeFB, (XrPassthroughLayerFB), layer)
+
+ // Set the style of an existing passthrough layer. If the enabled feature set
+ // doesn’t change, this is a lightweight operation that can be called in every
+ // frame to animate the style. Changes that may incur a bigger cost:
+ // - Enabling/disabling the color mapping, or changing the type of mapping
+ // (monochromatic to RGBA or back).
+ // - Changing `textureOpacityFactor` from 0 to non-zero or vice versa
+ // - Changing `edgeColor[3]` from 0 to non-zero or vice versa
+ // NOTE: For XR_FB_passthrough, all color values are treated as linear.
+ EXT_PROTO_XRRESULT_FUNC2(xrPassthroughLayerSetStyleFB,
+ (XrPassthroughLayerFB), layer,
+ (const XrPassthroughStyleFB *), style)
+
+ // Create a geometry instance to be used as a projection surface for passthrough.
+ // A geometry instance assigns a triangle mesh as part of the specified layer's
+ // projection surface.
+ // The operation is only valid if the passthrough layer's purpose has been set to
+ // `XR_PASSTHROUGH_LAYER_PURPOSE_PROJECTED_FB`. Otherwise, the call this function will
+ // result in an error. In the specified layer, Passthrough will be visible where the view
+ // is covered by the user-specified geometries.
+ //
+ // A triangle mesh object can be instantiated multiple times - in the same or different layers'
+ // projection surface. Each instantiation has its own transformation, which
+ // can be updated using `xrGeometryInstanceSetTransformFB`.
+ EXT_PROTO_XRRESULT_FUNC3(xrCreateGeometryInstanceFB,
+ (XrSession), session,
+ (const XrGeometryInstanceCreateInfoFB *), create_info,
+ (XrGeometryInstanceFB *), out_geometry_instance)
+
+ // Destroys a previously created geometry instance from passthrough rendering.
+ // This removes the geometry instance from passthrough rendering.
+ // The operation has no effect on other instances or the underlying mesh.
+ EXT_PROTO_XRRESULT_FUNC1(xrDestroyGeometryInstanceFB, (XrGeometryInstanceFB), instance)
+
+ // Update the transformation of a passthrough geometry instance.
+ EXT_PROTO_XRRESULT_FUNC2(xrGeometryInstanceSetTransformFB,
+ (XrGeometryInstanceFB), instance,
+ (const XrGeometryInstanceTransformFB *), transformation)
+
+ // Create a triangle mesh geometry object.
+ // Depending on the behavior flags, the mesh could be created immutable (data is assigned
+ // at creation and cannot be changed) or mutable (the mesh is created empty and can be updated
+ // by calling begin/end update functions).
+ EXT_PROTO_XRRESULT_FUNC3(xrCreateTriangleMeshFB,
+ (XrSession), session,
+ (const XrTriangleMeshCreateInfoFB *), create_info,
+ (XrTriangleMeshFB *), out_triangle_mesh)
+
+ // Destroy an `XrTriangleMeshFB` object along with its data. The mesh buffers must not be
+ // accessed anymore after their parent mesh object has been destroyed.
+ EXT_PROTO_XRRESULT_FUNC1(xrDestroyTriangleMeshFB, (XrTriangleMeshFB), mesh)
+
+ // Retrieve a pointer to the vertex buffer. The vertex buffer is structured as an array of 3 floats
+ // per vertex representing x, y, and z: `[x0, y0, z0, x1, y1, z1, ...]`. The size of the buffer is
+ // `maxVertexCount * 3` floats. The application must call `xrTriangleMeshBeginUpdateFB` or
+ // `xrTriangleMeshBeginVertexBufferUpdateFB` before making modifications to the vertex
+ // buffer. The buffer location is guaranteed to remain constant over the lifecycle of the mesh
+ // object.
+ EXT_PROTO_XRRESULT_FUNC2(xrTriangleMeshGetVertexBufferFB,
+ (XrTriangleMeshFB), mesh,
+ (XrVector3f **), out_vertex_buffer)
+
+ // Retrieve the index buffer that defines the topology of the triangle mesh. Each triplet of
+ // consecutive elements point to three vertices in the vertex buffer and thus form a triangle. The
+ // size of each element is `indexElementSize` bytes, and thus the size of the buffer is
+ // `maxTriangleCount * 3 * indexElementSize` bytes. The application must call
+ // `xrTriangleMeshBeginUpdateFB` before making modifications to the index buffer. The buffer
+ // location is guaranteed to remain constant over the lifecycle of the mesh object.
+ EXT_PROTO_XRRESULT_FUNC2(xrTriangleMeshGetIndexBufferFB,
+ (XrTriangleMeshFB), mesh,
+ (uint32_t **), out_index_buffer)
+
+ // Begin updating the mesh buffer data. The application must call this function before it makes any
+ // modifications to the buffers retrieved by `xrTriangleMeshGetVertexBufferFB` and
+ // `xrTriangleMeshGetIndexBufferFB`. If only the vertex buffer needs to be updated,
+ // `xrTriangleMeshBeginVertexBufferUpdateFB` can be used instead. To commit the
+ // modifications, the application must call `xrTriangleMeshEndUpdateFB`.
+ EXT_PROTO_XRRESULT_FUNC1(xrTriangleMeshBeginUpdateFB, (XrTriangleMeshFB), mesh)
+
+ // Signal the API that the application has finished updating the mesh buffers after a call to
+ // `xrTriangleMeshBeginUpdateFB`. `vertexCount` and `triangleCount` specify the actual
+ // number of primitives that make up the mesh after the update. They must be larger than zero but
+ // smaller or equal to the maximum counts defined at create time. Buffer data beyond these counts
+ // is ignored.
+ EXT_PROTO_XRRESULT_FUNC3(xrTriangleMeshEndUpdateFB,
+ (XrTriangleMeshFB), mesh,
+ (uint32_t), vertexCount,
+ (uint32_t), triangle_count)
+
+ // Update the vertex positions of a triangle mesh. Can only be called once the mesh topology has
+ // been set using `xrTriangleMeshBeginUpdateFB`/`xrTriangleMeshEndUpdateFB`. The
+ // vertex count is defined by the last invocation to `xrTriangleMeshEndUpdateFB`. Once the
+ // modification is done, `xrTriangleMeshEndVertexBufferUpdateFB` must be called.
+ EXT_PROTO_XRRESULT_FUNC2(xrTriangleMeshBeginVertexBufferUpdateFB,
+ (XrTriangleMeshFB), mesh,
+ (uint32_t *), out_vertex_count)
+
+ // Signal the API that the contents of the vertex buffer data has been updated
+ // after a call to `xrTriangleMeshBeginVertexBufferUpdateFB`.
+ EXT_PROTO_XRRESULT_FUNC1(xrTriangleMeshEndVertexBufferUpdateFB, (XrTriangleMeshFB), mesh)
+
+ bool initialize_fb_passthrough_extension(const XrInstance instance);
+
+ bool initialize_fb_triangle_mesh_extension(const XrInstance instance);
+
+ void cleanup();
+
+ // TODO: Temporary workaround (https://github.com/GodotVR/godot_openxr/issues/138)
+ // Address a bug in the passthrough api where XR_ERROR_UNEXPECTED_STATE_PASSTHROUGH_FB is
+ // returned even when the operation is valid on Meta Quest devices.
+ // The issue should be addressed on that platform in OS release v37.
+ inline bool is_valid_passthrough_result(XrResult result, const char *format) {
+ return openxr_api->xr_result(result, format) || result == XR_ERROR_UNEXPECTED_STATE_PASSTHROUGH_FB;
+ }
+
+ Viewport *get_main_viewport();
+
+ bool is_composition_passthrough_layer_ready();
+
+ static OpenXRFbPassthroughExtensionWrapper *singleton;
+
+ bool fb_passthrough_ext = false; // required for any passthrough functionality
+ bool fb_triangle_mesh_ext = false; // only use for projected passthrough
+
+ XrPassthroughCreateInfoFB passthrough_create_info = {
+ XR_TYPE_PASSTHROUGH_CREATE_INFO_FB,
+ nullptr,
+ 0,
+ };
+ XrPassthroughFB passthrough_handle = XR_NULL_HANDLE;
+
+ XrPassthroughLayerCreateInfoFB passthrough_layer_config = {
+ XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_FB,
+ nullptr,
+ passthrough_handle,
+ XR_PASSTHROUGH_IS_RUNNING_AT_CREATION_BIT_FB,
+ XR_PASSTHROUGH_LAYER_PURPOSE_RECONSTRUCTION_FB,
+ };
+ XrPassthroughStyleFB passthrough_layer_style = {
+ XR_TYPE_PASSTHROUGH_STYLE_FB,
+ nullptr,
+ 1,
+ { 0, 0, 0, 0 },
+ };
+ XrPassthroughLayerFB passthrough_layer = XR_NULL_HANDLE;
+
+ XrCompositionLayerPassthroughFB composition_passthrough_layer = {
+ XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_FB,
+ nullptr,
+ XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT,
+ XR_NULL_HANDLE,
+ XR_NULL_HANDLE,
+ };
+};
+
+#endif // OPENXR_FB_PASSTHROUGH_EXTENSION_WRAPPER_H
diff --git a/modules/openxr/extensions/openxr_hand_tracking_extension.cpp b/modules/openxr/extensions/openxr_hand_tracking_extension.cpp
new file mode 100644
index 0000000000..4b30965ce5
--- /dev/null
+++ b/modules/openxr/extensions/openxr_hand_tracking_extension.cpp
@@ -0,0 +1,268 @@
+/*************************************************************************/
+/* openxr_hand_tracking_extension.cpp */
+/*************************************************************************/
+/* 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. */
+/*************************************************************************/
+
+#include "openxr_hand_tracking_extension.h"
+#include "../openxr_api.h"
+#include "core/string/print_string.h"
+#include "servers/xr_server.h"
+
+#include <openxr/openxr.h>
+
+OpenXRHandTrackingExtension *OpenXRHandTrackingExtension::singleton = nullptr;
+
+OpenXRHandTrackingExtension *OpenXRHandTrackingExtension::get_singleton() {
+ return singleton;
+}
+
+OpenXRHandTrackingExtension::OpenXRHandTrackingExtension(OpenXRAPI *p_openxr_api) :
+ OpenXRExtensionWrapper(p_openxr_api) {
+ singleton = this;
+
+ // Extensions we use for our hand tracking.
+ request_extensions[XR_EXT_HAND_TRACKING_EXTENSION_NAME] = &hand_tracking_ext;
+ request_extensions[XR_EXT_HAND_JOINTS_MOTION_RANGE_EXTENSION_NAME] = &hand_motion_range_ext;
+ request_extensions[XR_FB_HAND_TRACKING_AIM_EXTENSION_NAME] = &hand_tracking_aim_state_ext;
+
+ // Make sure this is cleared until we actually request it
+ handTrackingSystemProperties.supportsHandTracking = false;
+}
+
+OpenXRHandTrackingExtension::~OpenXRHandTrackingExtension() {
+ singleton = nullptr;
+}
+
+void OpenXRHandTrackingExtension::on_instance_created(const XrInstance p_instance) {
+ if (hand_tracking_ext) {
+ EXT_INIT_XR_FUNC(xrCreateHandTrackerEXT);
+ EXT_INIT_XR_FUNC(xrDestroyHandTrackerEXT);
+ EXT_INIT_XR_FUNC(xrLocateHandJointsEXT);
+
+ hand_tracking_ext = xrCreateHandTrackerEXT_ptr && xrDestroyHandTrackerEXT_ptr && xrLocateHandJointsEXT_ptr;
+ }
+}
+
+void OpenXRHandTrackingExtension::on_session_destroyed() {
+ cleanup_hand_tracking();
+}
+
+void OpenXRHandTrackingExtension::on_instance_destroyed() {
+ xrCreateHandTrackerEXT_ptr = nullptr;
+ xrDestroyHandTrackerEXT_ptr = nullptr;
+ xrLocateHandJointsEXT_ptr = nullptr;
+}
+
+void *OpenXRHandTrackingExtension::set_system_properties_and_get_next_pointer(void *p_next_pointer) {
+ if (!hand_tracking_ext) {
+ // not supported...
+ return p_next_pointer;
+ }
+
+ handTrackingSystemProperties = {
+ XR_TYPE_SYSTEM_HAND_TRACKING_PROPERTIES_EXT, // type
+ p_next_pointer, // next
+ false, // supportsHandTracking
+ };
+
+ return &handTrackingSystemProperties;
+}
+
+void OpenXRHandTrackingExtension::on_state_ready() {
+ if (!handTrackingSystemProperties.supportsHandTracking) {
+ // not supported...
+ return;
+ }
+
+ // Setup our hands and reset data
+ for (int i = 0; i < MAX_OPENXR_TRACKED_HANDS; i++) {
+ // we'll do this later
+ hand_trackers[i].is_initialised = false;
+ hand_trackers[i].hand_tracker = XR_NULL_HANDLE;
+
+ hand_trackers[i].aimState.aimPose = { { 0.0, 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 } };
+ hand_trackers[i].aimState.pinchStrengthIndex = 0.0;
+ hand_trackers[i].aimState.pinchStrengthMiddle = 0.0;
+ hand_trackers[i].aimState.pinchStrengthRing = 0.0;
+ hand_trackers[i].aimState.pinchStrengthLittle = 0.0;
+
+ hand_trackers[i].locations.isActive = false;
+
+ for (int j = 0; j < XR_HAND_JOINT_COUNT_EXT; j++) {
+ hand_trackers[i].joint_locations[j] = { 0, { { 0.0, 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 } }, 0.0 };
+ hand_trackers[i].joint_velocities[j] = { 0, { 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 } };
+ }
+ }
+}
+
+void OpenXRHandTrackingExtension::on_process() {
+ if (!handTrackingSystemProperties.supportsHandTracking) {
+ // not supported...
+ return;
+ }
+
+ // process our hands
+ const XrTime time = openxr_api->get_next_frame_time(); // This data will be used for the next frame we render
+
+ XrResult result;
+
+ for (int i = 0; i < MAX_OPENXR_TRACKED_HANDS; i++) {
+ if (hand_trackers[i].hand_tracker == XR_NULL_HANDLE) {
+ XrHandTrackerCreateInfoEXT createInfo = {
+ XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT, // type
+ nullptr, // next
+ i == 0 ? XR_HAND_LEFT_EXT : XR_HAND_RIGHT_EXT, // hand
+ XR_HAND_JOINT_SET_DEFAULT_EXT, // handJointSet
+ };
+
+ result = xrCreateHandTrackerEXT(openxr_api->get_session(), &createInfo, &hand_trackers[i].hand_tracker);
+ if (XR_FAILED(result)) {
+ // not successful? then we do nothing.
+ print_line("OpenXR: Failed to obtain hand tracking information [", openxr_api->get_error_string(result), "]");
+ hand_trackers[i].is_initialised = false;
+ } else {
+ void *next_pointer = nullptr;
+ if (hand_tracking_aim_state_ext) {
+ hand_trackers[i].aimState.type = XR_TYPE_HAND_TRACKING_AIM_STATE_FB;
+ hand_trackers[i].aimState.next = next_pointer;
+ hand_trackers[i].aimState.status = 0;
+ hand_trackers[i].aimState.aimPose = { { 0.0, 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0 } };
+ hand_trackers[i].aimState.pinchStrengthIndex = 0.0;
+ hand_trackers[i].aimState.pinchStrengthMiddle = 0.0;
+ hand_trackers[i].aimState.pinchStrengthRing = 0.0;
+ hand_trackers[i].aimState.pinchStrengthLittle = 0.0;
+
+ next_pointer = &hand_trackers[i].aimState;
+ }
+
+ hand_trackers[i].velocities.type = XR_TYPE_HAND_JOINT_VELOCITIES_EXT;
+ hand_trackers[i].velocities.next = next_pointer;
+ hand_trackers[i].velocities.jointCount = XR_HAND_JOINT_COUNT_EXT;
+ hand_trackers[i].velocities.jointVelocities = hand_trackers[i].joint_velocities;
+ next_pointer = &hand_trackers[i].velocities;
+
+ hand_trackers[i].locations.type = XR_TYPE_HAND_JOINT_LOCATIONS_EXT;
+ hand_trackers[i].locations.next = next_pointer;
+ hand_trackers[i].locations.isActive = false;
+ hand_trackers[i].locations.jointCount = XR_HAND_JOINT_COUNT_EXT;
+ hand_trackers[i].locations.jointLocations = hand_trackers[i].joint_locations;
+
+ hand_trackers[i].is_initialised = true;
+ }
+ }
+
+ if (hand_trackers[i].is_initialised) {
+ void *next_pointer = nullptr;
+
+ XrHandJointsMotionRangeInfoEXT motionRangeInfo;
+
+ if (hand_motion_range_ext) {
+ motionRangeInfo.type = XR_TYPE_HAND_JOINTS_MOTION_RANGE_INFO_EXT;
+ motionRangeInfo.next = next_pointer;
+ motionRangeInfo.handJointsMotionRange = hand_trackers[i].motion_range;
+
+ next_pointer = &motionRangeInfo;
+ }
+
+ XrHandJointsLocateInfoEXT locateInfo = {
+ XR_TYPE_HAND_JOINTS_LOCATE_INFO_EXT, // type
+ next_pointer, // next
+ openxr_api->get_play_space(), // baseSpace
+ time, // time
+ };
+
+ result = xrLocateHandJointsEXT(hand_trackers[i].hand_tracker, &locateInfo, &hand_trackers[i].locations);
+ if (XR_FAILED(result)) {
+ // not successful? then we do nothing.
+ print_line("OpenXR: Failed to get tracking for hand", i, "[", openxr_api->get_error_string(result), "]");
+ continue;
+ }
+
+ // For some reason an inactive controller isn't coming back as inactive but has coordinates either as NAN or very large
+ const XrPosef &palm = hand_trackers[i].joint_locations[XR_HAND_JOINT_PALM_EXT].pose;
+ if (
+ !hand_trackers[i].locations.isActive || isnan(palm.position.x) || palm.position.x < -1000000.00 || palm.position.x > 1000000.00) {
+ hand_trackers[i].locations.isActive = false; // workaround, make sure its inactive
+ }
+
+ /* TODO change this to managing the controller from openxr_interface
+ if (hand_tracking_aim_state_ext && hand_trackers[i].locations.isActive && check_bit(XR_HAND_TRACKING_AIM_VALID_BIT_FB, hand_trackers[i].aimState.status)) {
+ // Controllers are updated based on the aim state's pose and pinches' strength
+ if (hand_trackers[i].aim_state_godot_controller == -1) {
+ hand_trackers[i].aim_state_godot_controller =
+ arvr_api->godot_arvr_add_controller(
+ const_cast<char *>(hand_controller_names[i]),
+ i + HAND_CONTROLLER_ID_OFFSET,
+ true,
+ true);
+ }
+ }
+ */
+ }
+ }
+}
+
+void OpenXRHandTrackingExtension::on_state_stopping() {
+ // cleanup
+ cleanup_hand_tracking();
+}
+
+void OpenXRHandTrackingExtension::cleanup_hand_tracking() {
+ XRServer *xr_server = XRServer::get_singleton();
+ ERR_FAIL_NULL(xr_server);
+
+ for (int i = 0; i < MAX_OPENXR_TRACKED_HANDS; i++) {
+ if (hand_trackers[i].hand_tracker != XR_NULL_HANDLE) {
+ xrDestroyHandTrackerEXT(hand_trackers[i].hand_tracker);
+
+ hand_trackers[i].is_initialised = false;
+ hand_trackers[i].hand_tracker = XR_NULL_HANDLE;
+ }
+ }
+}
+
+bool OpenXRHandTrackingExtension::get_active() {
+ return handTrackingSystemProperties.supportsHandTracking;
+}
+
+const OpenXRHandTrackingExtension::HandTracker *OpenXRHandTrackingExtension::get_hand_tracker(uint32_t p_hand) const {
+ ERR_FAIL_UNSIGNED_INDEX_V(p_hand, MAX_OPENXR_TRACKED_HANDS, nullptr);
+
+ return &hand_trackers[p_hand];
+}
+
+XrHandJointsMotionRangeEXT OpenXRHandTrackingExtension::get_motion_range(uint32_t p_hand) const {
+ ERR_FAIL_UNSIGNED_INDEX_V(p_hand, MAX_OPENXR_TRACKED_HANDS, XR_HAND_JOINTS_MOTION_RANGE_MAX_ENUM_EXT);
+
+ return hand_trackers[p_hand].motion_range;
+}
+
+void OpenXRHandTrackingExtension::set_motion_range(uint32_t p_hand, XrHandJointsMotionRangeEXT p_motion_range) {
+ ERR_FAIL_UNSIGNED_INDEX(p_hand, MAX_OPENXR_TRACKED_HANDS);
+ hand_trackers[p_hand].motion_range = p_motion_range;
+}
diff --git a/modules/openxr/extensions/openxr_hand_tracking_extension.h b/modules/openxr/extensions/openxr_hand_tracking_extension.h
new file mode 100644
index 0000000000..f8c26339b0
--- /dev/null
+++ b/modules/openxr/extensions/openxr_hand_tracking_extension.h
@@ -0,0 +1,96 @@
+/*************************************************************************/
+/* openxr_hand_tracking_extension.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 OPENXR_HAND_TRACKING_EXTENSION_H
+#define OPENXR_HAND_TRACKING_EXTENSION_H
+
+#include "openxr_extension_wrapper.h"
+
+#include "../util.h"
+
+#define MAX_OPENXR_TRACKED_HANDS 2
+
+class OpenXRHandTrackingExtension : public OpenXRExtensionWrapper {
+public:
+ struct HandTracker {
+ bool is_initialised = false;
+ XrHandJointsMotionRangeEXT motion_range = XR_HAND_JOINTS_MOTION_RANGE_UNOBSTRUCTED_EXT;
+
+ XrHandTrackerEXT hand_tracker = XR_NULL_HANDLE;
+ XrHandJointLocationEXT joint_locations[XR_HAND_JOINT_COUNT_EXT];
+ XrHandJointVelocityEXT joint_velocities[XR_HAND_JOINT_COUNT_EXT];
+
+ XrHandTrackingAimStateFB aimState;
+ XrHandJointVelocitiesEXT velocities;
+ XrHandJointLocationsEXT locations;
+ };
+
+ static OpenXRHandTrackingExtension *get_singleton();
+
+ OpenXRHandTrackingExtension(OpenXRAPI *p_openxr_api);
+ virtual ~OpenXRHandTrackingExtension() override;
+
+ virtual void on_instance_created(const XrInstance p_instance) override;
+ virtual void on_instance_destroyed() override;
+ virtual void on_session_destroyed() override;
+
+ virtual void *set_system_properties_and_get_next_pointer(void *p_next_pointer) override;
+ virtual void on_state_ready() override;
+ virtual void on_process() override;
+ virtual void on_state_stopping() override;
+
+ bool get_active();
+ const HandTracker *get_hand_tracker(uint32_t p_hand) const;
+
+ XrHandJointsMotionRangeEXT get_motion_range(uint32_t p_hand) const;
+ void set_motion_range(uint32_t p_hand, XrHandJointsMotionRangeEXT p_motion_range);
+
+private:
+ static OpenXRHandTrackingExtension *singleton;
+
+ // state
+ XrSystemHandTrackingPropertiesEXT handTrackingSystemProperties;
+ HandTracker hand_trackers[MAX_OPENXR_TRACKED_HANDS]; // Fixed for left and right hand
+
+ // related extensions
+ bool hand_tracking_ext = false;
+ bool hand_motion_range_ext = false;
+ bool hand_tracking_aim_state_ext = false;
+
+ // functions
+ void cleanup_hand_tracking();
+
+ // OpenXR API call wrappers
+ EXT_PROTO_XRRESULT_FUNC3(xrCreateHandTrackerEXT, (XrSession), p_session, (const XrHandTrackerCreateInfoEXT *), p_createInfo, (XrHandTrackerEXT *), p_handTracker)
+ EXT_PROTO_XRRESULT_FUNC1(xrDestroyHandTrackerEXT, (XrHandTrackerEXT), p_handTracker)
+ EXT_PROTO_XRRESULT_FUNC3(xrLocateHandJointsEXT, (XrHandTrackerEXT), p_handTracker, (const XrHandJointsLocateInfoEXT *), p_locateInfo, (XrHandJointLocationsEXT *), p_locations)
+};
+
+#endif // OPENXR_HAND_TRACKING_EXTENSION_H
diff --git a/modules/openxr/extensions/openxr_htc_vive_tracker_extension.cpp b/modules/openxr/extensions/openxr_htc_vive_tracker_extension.cpp
index 302acf4e30..88cc7c061c 100644
--- a/modules/openxr/extensions/openxr_htc_vive_tracker_extension.cpp
+++ b/modules/openxr/extensions/openxr_htc_vive_tracker_extension.cpp
@@ -65,3 +65,12 @@ bool OpenXRHTCViveTrackerExtension::on_event_polled(const XrEventDataBuffer &eve
} break;
}
}
+
+bool OpenXRHTCViveTrackerExtension::is_path_supported(const String &p_path) {
+ if (p_path == "/interaction_profiles/htc/vive_tracker_htcx") {
+ return available;
+ }
+
+ // Not a path under this extensions control, so we return true;
+ return true;
+}
diff --git a/modules/openxr/extensions/openxr_htc_vive_tracker_extension.h b/modules/openxr/extensions/openxr_htc_vive_tracker_extension.h
index 7f37351f27..ab8e8535f1 100644
--- a/modules/openxr/extensions/openxr_htc_vive_tracker_extension.h
+++ b/modules/openxr/extensions/openxr_htc_vive_tracker_extension.h
@@ -41,7 +41,9 @@ public:
virtual ~OpenXRHTCViveTrackerExtension() override;
bool is_available();
+
virtual bool on_event_polled(const XrEventDataBuffer &event) override;
+ virtual bool is_path_supported(const String &p_path) override;
private:
static OpenXRHTCViveTrackerExtension *singleton;
diff --git a/modules/openxr/extensions/openxr_palm_pose_extension.cpp b/modules/openxr/extensions/openxr_palm_pose_extension.cpp
new file mode 100644
index 0000000000..fd3b8f50fe
--- /dev/null
+++ b/modules/openxr/extensions/openxr_palm_pose_extension.cpp
@@ -0,0 +1,66 @@
+/*************************************************************************/
+/* openxr_palm_pose_extension.cpp */
+/*************************************************************************/
+/* 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. */
+/*************************************************************************/
+
+#include "openxr_palm_pose_extension.h"
+#include "core/string/print_string.h"
+
+OpenXRPalmPoseExtension *OpenXRPalmPoseExtension::singleton = nullptr;
+
+OpenXRPalmPoseExtension *OpenXRPalmPoseExtension::get_singleton() {
+ return singleton;
+}
+
+OpenXRPalmPoseExtension::OpenXRPalmPoseExtension(OpenXRAPI *p_openxr_api) :
+ OpenXRExtensionWrapper(p_openxr_api) {
+ singleton = this;
+
+ request_extensions[XR_EXT_PALM_POSE_EXTENSION_NAME] = &available;
+}
+
+OpenXRPalmPoseExtension::~OpenXRPalmPoseExtension() {
+ singleton = nullptr;
+}
+
+bool OpenXRPalmPoseExtension::is_available() {
+ return available;
+}
+
+bool OpenXRPalmPoseExtension::is_path_supported(const String &p_path) {
+ if (p_path == "/user/hand/left/input/palm_ext/pose") {
+ return available;
+ }
+
+ if (p_path == "/user/hand/right/input/palm_ext/pose") {
+ return available;
+ }
+
+ // Not a path under this extensions control, so we return true;
+ return true;
+}
diff --git a/modules/openxr/extensions/openxr_palm_pose_extension.h b/modules/openxr/extensions/openxr_palm_pose_extension.h
new file mode 100644
index 0000000000..a7ef83c5d5
--- /dev/null
+++ b/modules/openxr/extensions/openxr_palm_pose_extension.h
@@ -0,0 +1,53 @@
+/*************************************************************************/
+/* openxr_palm_pose_extension.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 OPENXR_PALM_POSE_EXTENSION_H
+#define OPENXR_PALM_POSE_EXTENSION_H
+
+#include "openxr_extension_wrapper.h"
+
+class OpenXRPalmPoseExtension : public OpenXRExtensionWrapper {
+public:
+ static OpenXRPalmPoseExtension *get_singleton();
+
+ OpenXRPalmPoseExtension(OpenXRAPI *p_openxr_api);
+ virtual ~OpenXRPalmPoseExtension() override;
+
+ bool is_available();
+
+ virtual bool is_path_supported(const String &p_path) override;
+
+private:
+ static OpenXRPalmPoseExtension *singleton;
+
+ bool available = false;
+};
+
+#endif // OPENXR_PALM_POSE_EXTENSION_H
diff --git a/modules/openxr/extensions/openxr_vulkan_extension.cpp b/modules/openxr/extensions/openxr_vulkan_extension.cpp
index 2608c4ac17..f9e771c934 100644
--- a/modules/openxr/extensions/openxr_vulkan_extension.cpp
+++ b/modules/openxr/extensions/openxr_vulkan_extension.cpp
@@ -31,30 +31,12 @@
#include "core/string/print_string.h"
#include "../extensions/openxr_vulkan_extension.h"
-#include "../openxr_api.h"
#include "../openxr_util.h"
#include "servers/rendering/renderer_rd/effects/copy_effects.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_globals.h"
#include "servers/rendering_server.h"
-// need to include Vulkan so we know of type definitions
-#define XR_USE_GRAPHICS_API_VULKAN
-
-#ifdef WINDOWS_ENABLED
-// Including windows.h here is absolutely evil, we shouldn't be doing this outside of platform
-// however due to the way the openxr headers are put together, we have no choice.
-#include <windows.h>
-#endif
-
-// include platform dependent structs
-#include <openxr/openxr_platform.h>
-
-PFN_xrGetVulkanGraphicsRequirements2KHR xrGetVulkanGraphicsRequirements2KHR_ptr = nullptr;
-PFN_xrCreateVulkanInstanceKHR xrCreateVulkanInstanceKHR_ptr = nullptr;
-PFN_xrGetVulkanGraphicsDevice2KHR xrGetVulkanGraphicsDevice2KHR_ptr = nullptr;
-PFN_xrCreateVulkanDeviceKHR xrCreateVulkanDeviceKHR_ptr = nullptr;
-
OpenXRVulkanExtension::OpenXRVulkanExtension(OpenXRAPI *p_openxr_api) :
OpenXRGraphicsExtensionWrapper(p_openxr_api) {
VulkanContext::set_vulkan_hooks(this);
@@ -69,36 +51,15 @@ OpenXRVulkanExtension::~OpenXRVulkanExtension() {
}
void OpenXRVulkanExtension::on_instance_created(const XrInstance p_instance) {
- XrResult result;
-
ERR_FAIL_NULL(openxr_api);
// Obtain pointers to functions we're accessing here, they are (not yet) part of core.
- result = xrGetInstanceProcAddr(p_instance, "xrGetVulkanGraphicsRequirements2KHR", (PFN_xrVoidFunction *)&xrGetVulkanGraphicsRequirements2KHR_ptr);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to xrGetVulkanGraphicsRequirements2KHR entry point [", openxr_api->get_error_string(result), "]");
- }
- result = xrGetInstanceProcAddr(p_instance, "xrCreateVulkanInstanceKHR", (PFN_xrVoidFunction *)&xrCreateVulkanInstanceKHR_ptr);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to xrCreateVulkanInstanceKHR entry point [", openxr_api->get_error_string(result), "]");
- }
-
- result = xrGetInstanceProcAddr(p_instance, "xrGetVulkanGraphicsDevice2KHR", (PFN_xrVoidFunction *)&xrGetVulkanGraphicsDevice2KHR_ptr);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to xrGetVulkanGraphicsDevice2KHR entry point [", openxr_api->get_error_string(result), "]");
- }
-
- result = xrGetInstanceProcAddr(p_instance, "xrCreateVulkanDeviceKHR", (PFN_xrVoidFunction *)&xrCreateVulkanDeviceKHR_ptr);
- if (XR_FAILED(result)) {
- print_line("OpenXR: Failed to xrCreateVulkanDeviceKHR entry point [", openxr_api->get_error_string(result), "]");
- }
-}
-
-XrResult OpenXRVulkanExtension::xrGetVulkanGraphicsRequirements2KHR(XrInstance p_instance, XrSystemId p_system_id, XrGraphicsRequirementsVulkanKHR *p_graphics_requirements) {
- ERR_FAIL_NULL_V(xrGetVulkanGraphicsRequirements2KHR_ptr, XR_ERROR_HANDLE_INVALID);
-
- return (*xrGetVulkanGraphicsRequirements2KHR_ptr)(p_instance, p_system_id, p_graphics_requirements);
+ EXT_INIT_XR_FUNC(xrGetVulkanGraphicsRequirements2KHR);
+ EXT_INIT_XR_FUNC(xrCreateVulkanInstanceKHR);
+ EXT_INIT_XR_FUNC(xrGetVulkanGraphicsDevice2KHR);
+ EXT_INIT_XR_FUNC(xrCreateVulkanDeviceKHR);
+ EXT_INIT_XR_FUNC(xrEnumerateSwapchainImages);
}
bool OpenXRVulkanExtension::check_graphics_api_support(XrVersion p_desired_version) {
@@ -141,12 +102,6 @@ bool OpenXRVulkanExtension::check_graphics_api_support(XrVersion p_desired_versi
return true;
}
-XrResult OpenXRVulkanExtension::xrCreateVulkanInstanceKHR(XrInstance p_instance, const XrVulkanInstanceCreateInfoKHR *p_create_info, VkInstance *r_vulkan_instance, VkResult *r_vulkan_result) {
- ERR_FAIL_NULL_V(xrCreateVulkanInstanceKHR_ptr, XR_ERROR_HANDLE_INVALID);
-
- return (*xrCreateVulkanInstanceKHR_ptr)(p_instance, p_create_info, r_vulkan_instance, r_vulkan_result);
-}
-
bool OpenXRVulkanExtension::create_vulkan_instance(const VkInstanceCreateInfo *p_vulkan_create_info, VkInstance *r_instance) {
// get the vulkan version we are creating
uint32_t vulkan_version = p_vulkan_create_info->pApplicationInfo->apiVersion;
@@ -195,12 +150,6 @@ bool OpenXRVulkanExtension::create_vulkan_instance(const VkInstanceCreateInfo *p
return true;
}
-XrResult OpenXRVulkanExtension::xrGetVulkanGraphicsDevice2KHR(XrInstance p_instance, const XrVulkanGraphicsDeviceGetInfoKHR *p_get_info, VkPhysicalDevice *r_vulkan_physical_device) {
- ERR_FAIL_NULL_V(xrGetVulkanGraphicsDevice2KHR_ptr, XR_ERROR_HANDLE_INVALID);
-
- return (*xrGetVulkanGraphicsDevice2KHR_ptr)(p_instance, p_get_info, r_vulkan_physical_device);
-}
-
bool OpenXRVulkanExtension::get_physical_device(VkPhysicalDevice *r_device) {
ERR_FAIL_NULL_V(openxr_api, false);
@@ -222,12 +171,6 @@ bool OpenXRVulkanExtension::get_physical_device(VkPhysicalDevice *r_device) {
return true;
}
-XrResult OpenXRVulkanExtension::xrCreateVulkanDeviceKHR(XrInstance p_instance, const XrVulkanDeviceCreateInfoKHR *p_create_info, VkDevice *r_device, VkResult *r_result) {
- ERR_FAIL_NULL_V(xrCreateVulkanDeviceKHR_ptr, XR_ERROR_HANDLE_INVALID);
-
- return (*xrCreateVulkanDeviceKHR_ptr)(p_instance, p_create_info, r_device, r_result);
-}
-
bool OpenXRVulkanExtension::create_vulkan_device(const VkDeviceCreateInfo *p_device_create_info, VkDevice *r_device) {
ERR_FAIL_NULL_V(openxr_api, false);
diff --git a/modules/openxr/extensions/openxr_vulkan_extension.h b/modules/openxr/extensions/openxr_vulkan_extension.h
index 5dddc4b9c9..d6e9917900 100644
--- a/modules/openxr/extensions/openxr_vulkan_extension.h
+++ b/modules/openxr/extensions/openxr_vulkan_extension.h
@@ -36,16 +36,25 @@
#include "drivers/vulkan/vulkan_context.h"
-// Forward declare these so we don't need OpenXR headers where-ever this is included
-// Including OpenXR at this point gives loads and loads of compile issues especially
-// on Windows because windows.h is EVIL and really shouldn't be included outside of platform
-// but we really don't have a choice in the matter
+#include "../openxr_api.h"
+#include "../util.h"
-struct XrGraphicsRequirementsVulkanKHR;
-struct XrVulkanInstanceCreateInfoKHR;
-struct XrVulkanGraphicsDeviceGetInfoKHR;
-struct XrVulkanDeviceCreateInfoKHR;
-struct XrGraphicsBindingVulkanKHR;
+// need to include Vulkan so we know of type definitions
+#define XR_USE_GRAPHICS_API_VULKAN
+
+#ifdef WINDOWS_ENABLED
+// Including windows.h here is absolutely evil, we shouldn't be doing this outside of platform
+// however due to the way the openxr headers are put together, we have no choice.
+#include <windows.h>
+#endif
+
+#ifdef ANDROID_ENABLED
+// The jobject type from jni.h is used by openxr_platform.h on Android.
+#include <jni.h>
+#endif
+
+// include platform dependent structs
+#include <openxr/openxr_platform.h>
class OpenXRVulkanExtension : public OpenXRGraphicsExtensionWrapper, VulkanHooks {
public:
@@ -84,10 +93,11 @@ private:
uint32_t vulkan_queue_family_index = 0;
uint32_t vulkan_queue_index = 0;
- XrResult xrGetVulkanGraphicsRequirements2KHR(XrInstance p_instance, XrSystemId p_system_id, XrGraphicsRequirementsVulkanKHR *p_graphics_requirements);
- XrResult xrCreateVulkanInstanceKHR(XrInstance p_instance, const XrVulkanInstanceCreateInfoKHR *p_create_info, VkInstance *r_vulkan_instance, VkResult *r_vulkan_result);
- XrResult xrGetVulkanGraphicsDevice2KHR(XrInstance p_instance, const XrVulkanGraphicsDeviceGetInfoKHR *p_get_info, VkPhysicalDevice *r_vulkan_physical_device);
- XrResult xrCreateVulkanDeviceKHR(XrInstance p_instance, const XrVulkanDeviceCreateInfoKHR *p_create_info, VkDevice *r_device, VkResult *r_result);
+ EXT_PROTO_XRRESULT_FUNC3(xrGetVulkanGraphicsRequirements2KHR, (XrInstance), p_instance, (XrSystemId), p_system_id, (XrGraphicsRequirementsVulkanKHR *), p_graphics_requirements)
+ EXT_PROTO_XRRESULT_FUNC4(xrCreateVulkanInstanceKHR, (XrInstance), p_instance, (const XrVulkanInstanceCreateInfoKHR *), p_create_info, (VkInstance *), r_vulkan_instance, (VkResult *), r_vulkan_result)
+ EXT_PROTO_XRRESULT_FUNC3(xrGetVulkanGraphicsDevice2KHR, (XrInstance), p_instance, (const XrVulkanGraphicsDeviceGetInfoKHR *), p_get_info, (VkPhysicalDevice *), r_vulkan_physical_device)
+ EXT_PROTO_XRRESULT_FUNC4(xrCreateVulkanDeviceKHR, (XrInstance), p_instance, (const XrVulkanDeviceCreateInfoKHR *), p_create_info, (VkDevice *), r_device, (VkResult *), r_result)
+ EXT_PROTO_XRRESULT_FUNC4(xrEnumerateSwapchainImages, (XrSwapchain), p_swapchain, (uint32_t), p_image_capacity_input, (uint32_t *), p_image_count_output, (XrSwapchainImageBaseHeader *), p_images)
};
#endif // OPENXR_VULKAN_EXTENSION_H
diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp
index 92d074cb75..16879ac4e5 100644
--- a/modules/openxr/openxr_api.cpp
+++ b/modules/openxr/openxr_api.cpp
@@ -41,6 +41,7 @@
#endif
#ifdef ANDROID_ENABLED
+#define OPENXR_LOADER_NAME "libopenxr_loader.so"
#include "extensions/openxr_android_extension.h"
#endif
@@ -48,7 +49,10 @@
#include "extensions/openxr_vulkan_extension.h"
#endif
+#include "extensions/openxr_fb_passthrough_extension_wrapper.h"
+#include "extensions/openxr_hand_tracking_extension.h"
#include "extensions/openxr_htc_vive_tracker_extension.h"
+#include "extensions/openxr_palm_pose_extension.h"
#include "modules/openxr/openxr_interface.h"
@@ -184,6 +188,20 @@ bool OpenXRAPI::is_extension_supported(const String &p_extension) const {
return false;
}
+bool OpenXRAPI::is_path_supported(const String &p_path) {
+ // This checks with extensions whether a path is *unsupported* and returns false if this is so.
+ // This allows us to filter out paths that are only available if related extensions are supported.
+ // WARNING: This method will return true for unknown/mistyped paths as we have no way to validate those.
+
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ if (!wrapper->is_path_supported(p_path)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
void OpenXRAPI::copy_string_to_char_buffer(const String p_string, char *p_buffer, int p_buffer_len) {
CharString char_string = p_string.utf8();
int len = char_string.length();
@@ -284,6 +302,9 @@ bool OpenXRAPI::create_instance() {
0, // runtimeVersion, from here will be set by our get call
"" // runtimeName
};
+
+ OPENXR_API_INIT_XR_FUNC_V(xrGetInstanceProperties);
+
result = xrGetInstanceProperties(instance, &instanceProps);
if (XR_FAILED(result)) {
// not fatal probably
@@ -992,9 +1013,94 @@ bool OpenXRAPI::is_running() {
return running;
}
+bool OpenXRAPI::openxr_loader_init() {
+#ifdef ANDROID_ENABLED
+ ERR_FAIL_COND_V_MSG(openxr_loader_library_handle != nullptr, false, "OpenXR Loader library is already loaded.");
+
+ {
+ Error error_code = OS::get_singleton()->open_dynamic_library(OPENXR_LOADER_NAME, openxr_loader_library_handle);
+ ERR_FAIL_COND_V_MSG(error_code != OK, false, "OpenXR loader not found.");
+ }
+
+ {
+ Error error_code = OS::get_singleton()->get_dynamic_library_symbol_handle(openxr_loader_library_handle, "xrGetInstanceProcAddr", (void *&)xrGetInstanceProcAddr);
+ ERR_FAIL_COND_V_MSG(error_code != OK, false, "Symbol xrGetInstanceProcAddr not found in OpenXR Loader library.");
+ }
+#endif
+
+ // Resolve the symbols that don't require an instance
+ OPENXR_API_INIT_XR_FUNC_V(xrCreateInstance);
+ OPENXR_API_INIT_XR_FUNC_V(xrEnumerateApiLayerProperties);
+ OPENXR_API_INIT_XR_FUNC_V(xrEnumerateInstanceExtensionProperties);
+
+ return true;
+}
+
+bool OpenXRAPI::resolve_instance_openxr_symbols() {
+ ERR_FAIL_COND_V(instance == XR_NULL_HANDLE, false);
+
+ OPENXR_API_INIT_XR_FUNC_V(xrAcquireSwapchainImage);
+ OPENXR_API_INIT_XR_FUNC_V(xrApplyHapticFeedback);
+ OPENXR_API_INIT_XR_FUNC_V(xrAttachSessionActionSets);
+ OPENXR_API_INIT_XR_FUNC_V(xrBeginFrame);
+ OPENXR_API_INIT_XR_FUNC_V(xrBeginSession);
+ OPENXR_API_INIT_XR_FUNC_V(xrCreateAction);
+ OPENXR_API_INIT_XR_FUNC_V(xrCreateActionSet);
+ OPENXR_API_INIT_XR_FUNC_V(xrCreateActionSpace);
+ OPENXR_API_INIT_XR_FUNC_V(xrCreateReferenceSpace);
+ OPENXR_API_INIT_XR_FUNC_V(xrCreateSession);
+ OPENXR_API_INIT_XR_FUNC_V(xrCreateSwapchain);
+ OPENXR_API_INIT_XR_FUNC_V(xrDestroyAction);
+ OPENXR_API_INIT_XR_FUNC_V(xrDestroyActionSet);
+ OPENXR_API_INIT_XR_FUNC_V(xrDestroyInstance);
+ OPENXR_API_INIT_XR_FUNC_V(xrDestroySession);
+ OPENXR_API_INIT_XR_FUNC_V(xrDestroySpace);
+ OPENXR_API_INIT_XR_FUNC_V(xrDestroySwapchain);
+ OPENXR_API_INIT_XR_FUNC_V(xrEndFrame);
+ OPENXR_API_INIT_XR_FUNC_V(xrEndSession);
+ OPENXR_API_INIT_XR_FUNC_V(xrEnumerateReferenceSpaces);
+ OPENXR_API_INIT_XR_FUNC_V(xrEnumerateSwapchainFormats);
+ OPENXR_API_INIT_XR_FUNC_V(xrEnumerateViewConfigurations);
+ OPENXR_API_INIT_XR_FUNC_V(xrEnumerateViewConfigurationViews);
+ OPENXR_API_INIT_XR_FUNC_V(xrGetActionStateBoolean);
+ OPENXR_API_INIT_XR_FUNC_V(xrGetActionStateFloat);
+ OPENXR_API_INIT_XR_FUNC_V(xrGetActionStateVector2f);
+ OPENXR_API_INIT_XR_FUNC_V(xrGetCurrentInteractionProfile);
+ OPENXR_API_INIT_XR_FUNC_V(xrGetSystem);
+ OPENXR_API_INIT_XR_FUNC_V(xrGetSystemProperties);
+ OPENXR_API_INIT_XR_FUNC_V(xrLocateViews);
+ OPENXR_API_INIT_XR_FUNC_V(xrLocateSpace);
+ OPENXR_API_INIT_XR_FUNC_V(xrPathToString);
+ OPENXR_API_INIT_XR_FUNC_V(xrPollEvent);
+ OPENXR_API_INIT_XR_FUNC_V(xrReleaseSwapchainImage);
+ OPENXR_API_INIT_XR_FUNC_V(xrResultToString);
+ OPENXR_API_INIT_XR_FUNC_V(xrStringToPath);
+ OPENXR_API_INIT_XR_FUNC_V(xrSuggestInteractionProfileBindings);
+ OPENXR_API_INIT_XR_FUNC_V(xrSyncActions);
+ OPENXR_API_INIT_XR_FUNC_V(xrWaitFrame);
+ OPENXR_API_INIT_XR_FUNC_V(xrWaitSwapchainImage);
+
+ return true;
+}
+
+XrResult OpenXRAPI::get_instance_proc_addr(const char *p_name, PFN_xrVoidFunction *p_addr) {
+ XrResult result = xrGetInstanceProcAddr(instance, p_name, p_addr);
+
+ if (result != XR_SUCCESS) {
+ String error_message = String("Symbol ") + p_name + " not found in OpenXR instance.";
+ ERR_FAIL_COND_V_MSG(true, result, error_message.utf8().get_data());
+ }
+
+ return result;
+}
+
bool OpenXRAPI::initialize(const String &p_rendering_driver) {
ERR_FAIL_COND_V_MSG(instance != XR_NULL_HANDLE, false, "OpenXR instance was already created");
+ if (!openxr_loader_init()) {
+ return false;
+ }
+
if (p_rendering_driver == "vulkan") {
#ifdef VULKAN_ENABLED
graphics_extension = memnew(OpenXRVulkanExtension(this));
@@ -1017,6 +1123,10 @@ bool OpenXRAPI::initialize(const String &p_rendering_driver) {
}
// initialize
+ for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
+ wrapper->on_before_instance_created();
+ }
+
if (!load_layer_properties()) {
destroy_instance();
return false;
@@ -1032,6 +1142,11 @@ bool OpenXRAPI::initialize(const String &p_rendering_driver) {
return false;
}
+ if (!resolve_instance_openxr_symbols()) {
+ destroy_instance();
+ return false;
+ }
+
if (!get_system_info()) {
destroy_instance();
return false;
@@ -1382,6 +1497,10 @@ void OpenXRAPI::pre_render() {
// 2) It will use the previous timing to pause our thread so that rendering starts as close to displaying as possible
// This must thus be called as close to when we start rendering as possible
XrFrameWaitInfo frame_wait_info = { XR_TYPE_FRAME_WAIT_INFO, nullptr };
+ frame_state.predictedDisplayTime = 0;
+ frame_state.predictedDisplayPeriod = 0;
+ frame_state.shouldRender = false;
+
XrResult result = xrWaitFrame(session, &frame_wait_info, &frame_state);
if (XR_FAILED(result)) {
print_line("OpenXR: xrWaitFrame() was not successful [", get_error_string(result), "]");
@@ -1557,7 +1676,7 @@ void OpenXRAPI::end_frame() {
XrCompositionLayerProjection projection_layer = {
XR_TYPE_COMPOSITION_LAYER_PROJECTION, // type
nullptr, // next
- layers_list.size() > 1 ? XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT | XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT : XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT, // layerFlags
+ layers_list.size() > 0 ? XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT | XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT : XR_COMPOSITION_LAYER_CORRECT_CHROMATIC_ABERRATION_BIT, // layerFlags
play_space, // space
view_count, // viewCount
projection_views, // views
@@ -1643,7 +1762,10 @@ OpenXRAPI::OpenXRAPI() {
#endif
// register our other extensions
+ register_extension_wrapper(memnew(OpenXRPalmPoseExtension(this)));
register_extension_wrapper(memnew(OpenXRHTCViveTrackerExtension(this)));
+ register_extension_wrapper(memnew(OpenXRHandTrackingExtension(this)));
+ register_extension_wrapper(memnew(OpenXRFbPassthroughExtensionWrapper(this)));
}
OpenXRAPI::~OpenXRAPI() {
@@ -1669,6 +1791,13 @@ OpenXRAPI::~OpenXRAPI() {
layer_properties = nullptr;
}
+#ifdef ANDROID_ENABLED
+ if (openxr_loader_library_handle) {
+ OS::get_singleton()->close_dynamic_library(openxr_loader_library_handle);
+ openxr_loader_library_handle = nullptr;
+ }
+#endif
+
singleton = nullptr;
}
@@ -1745,6 +1874,18 @@ void OpenXRAPI::parse_velocities(const XrSpaceVelocity &p_velocity, Vector3 &r_l
}
}
+bool OpenXRAPI::xr_result(XrResult result, const char *format, Array args) const {
+ if (XR_SUCCEEDED(result))
+ return true;
+
+ char resultString[XR_MAX_RESULT_STRING_SIZE];
+ xrResultToString(instance, result, resultString);
+
+ print_error(String("OpenXR ") + String(format).format(args) + String(" [") + String(resultString) + String("]"));
+
+ return false;
+}
+
RID OpenXRAPI::get_tracker_rid(XrPath p_path) {
List<RID> current;
tracker_owner.get_owned_list(&current);
@@ -2063,6 +2204,11 @@ XrPath OpenXRAPI::get_interaction_profile_path(RID p_interaction_profile) {
}
RID OpenXRAPI::interaction_profile_create(const String p_name) {
+ if (!is_path_supported(p_name)) {
+ // The extension enabling this path must not be active, we will silently skip this interaction profile
+ return RID();
+ }
+
InteractionProfile new_interaction_profile;
XrResult result = xrStringToPath(instance, p_name.utf8().get_data(), &new_interaction_profile.path);
@@ -2099,6 +2245,11 @@ void OpenXRAPI::interaction_profile_clear_bindings(RID p_interaction_profile) {
}
bool OpenXRAPI::interaction_profile_add_binding(RID p_interaction_profile, RID p_action, const String p_path) {
+ if (!is_path_supported(p_path)) {
+ // The extension enabling this path must not be active, we will silently skip this binding
+ return false;
+ }
+
InteractionProfile *ip = interaction_profile_owner.get_or_null(p_interaction_profile);
ERR_FAIL_NULL_V(ip, false);
@@ -2426,3 +2577,11 @@ bool OpenXRAPI::trigger_haptic_pulse(RID p_action, RID p_tracker, float p_freque
return true;
}
+
+void OpenXRAPI::register_composition_layer_provider(OpenXRCompositionLayerProvider *provider) {
+ composition_layer_providers.append(provider);
+}
+
+void OpenXRAPI::unregister_composition_layer_provider(OpenXRCompositionLayerProvider *provider) {
+ composition_layer_providers.erase(provider);
+}
diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h
index dc224c4237..316886239e 100644
--- a/modules/openxr/openxr_api.h
+++ b/modules/openxr/openxr_api.h
@@ -36,6 +36,7 @@
#include "core/math/transform_3d.h"
#include "core/math/vector2.h"
#include "core/os/memory.h"
+#include "core/string/print_string.h"
#include "core/string/ustring.h"
#include "core/templates/rb_map.h"
#include "core/templates/rid_owner.h"
@@ -50,6 +51,8 @@
#include "extensions/openxr_composition_layer_provider.h"
#include "extensions/openxr_extension_wrapper.h"
+#include "util.h"
+
// Note, OpenXR code that we wrote for our plugin makes use of C++20 notation for initialising structs which ensures zeroing out unspecified members.
// Godot is currently restricted to C++17 which doesn't allow this notation. Make sure critical fields are set.
@@ -81,6 +84,8 @@ private:
bool ext_vive_focus3_available = false;
bool ext_huawei_controller_available = false;
+ bool is_path_supported(const String &p_path);
+
// composition layer providers
Vector<OpenXRCompositionLayerProvider *> composition_layer_providers;
@@ -100,7 +105,7 @@ private:
XrFormFactor form_factor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
XrViewConfigurationType view_configuration = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
XrReferenceSpaceType reference_space = XR_REFERENCE_SPACE_TYPE_STAGE;
- XrEnvironmentBlendMode environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
+ // XrEnvironmentBlendMode environment_blend_mode = XR_ENVIRONMENT_BLEND_MODE_OPAQUE;
// state
XrInstance instance = XR_NULL_HANDLE;
@@ -134,6 +139,64 @@ private:
bool load_supported_extensions();
bool is_extension_supported(const String &p_extension) const;
+ bool openxr_loader_init();
+ bool resolve_instance_openxr_symbols();
+
+#ifdef ANDROID_ENABLED
+ // On Android we keep tracker of our external OpenXR loader
+ void *openxr_loader_library_handle = nullptr;
+#endif
+
+ // function pointers
+#ifdef ANDROID_ENABLED
+ // On non-Android platforms we use the OpenXR symbol linked into the engine binary.
+ PFN_xrGetInstanceProcAddr xrGetInstanceProcAddr = nullptr;
+#endif
+ EXT_PROTO_XRRESULT_FUNC3(xrAcquireSwapchainImage, (XrSwapchain), swapchain, (const XrSwapchainImageAcquireInfo *), acquireInfo, (uint32_t *), index)
+ EXT_PROTO_XRRESULT_FUNC3(xrApplyHapticFeedback, (XrSession), session, (const XrHapticActionInfo *), hapticActionInfo, (const XrHapticBaseHeader *), hapticFeedback)
+ EXT_PROTO_XRRESULT_FUNC2(xrAttachSessionActionSets, (XrSession), session, (const XrSessionActionSetsAttachInfo *), attachInfo)
+ EXT_PROTO_XRRESULT_FUNC2(xrBeginFrame, (XrSession), session, (const XrFrameBeginInfo *), frameBeginInfo)
+ EXT_PROTO_XRRESULT_FUNC2(xrBeginSession, (XrSession), session, (const XrSessionBeginInfo *), beginInfo)
+ EXT_PROTO_XRRESULT_FUNC3(xrCreateAction, (XrActionSet), actionSet, (const XrActionCreateInfo *), createInfo, (XrAction *), action)
+ EXT_PROTO_XRRESULT_FUNC3(xrCreateActionSet, (XrInstance), instance, (const XrActionSetCreateInfo *), createInfo, (XrActionSet *), actionSet)
+ EXT_PROTO_XRRESULT_FUNC3(xrCreateActionSpace, (XrSession), session, (const XrActionSpaceCreateInfo *), createInfo, (XrSpace *), space)
+ EXT_PROTO_XRRESULT_FUNC2(xrCreateInstance, (const XrInstanceCreateInfo *), createInfo, (XrInstance *), instance)
+ EXT_PROTO_XRRESULT_FUNC3(xrCreateReferenceSpace, (XrSession), session, (const XrReferenceSpaceCreateInfo *), createInfo, (XrSpace *), space)
+ EXT_PROTO_XRRESULT_FUNC3(xrCreateSession, (XrInstance), instance, (const XrSessionCreateInfo *), createInfo, (XrSession *), session)
+ EXT_PROTO_XRRESULT_FUNC3(xrCreateSwapchain, (XrSession), session, (const XrSwapchainCreateInfo *), createInfo, (XrSwapchain *), swapchain)
+ EXT_PROTO_XRRESULT_FUNC1(xrDestroyAction, (XrAction), action)
+ EXT_PROTO_XRRESULT_FUNC1(xrDestroyActionSet, (XrActionSet), actionSet)
+ EXT_PROTO_XRRESULT_FUNC1(xrDestroyInstance, (XrInstance), instance)
+ EXT_PROTO_XRRESULT_FUNC1(xrDestroySession, (XrSession), session)
+ EXT_PROTO_XRRESULT_FUNC1(xrDestroySpace, (XrSpace), space)
+ EXT_PROTO_XRRESULT_FUNC1(xrDestroySwapchain, (XrSwapchain), swapchain)
+ EXT_PROTO_XRRESULT_FUNC2(xrEndFrame, (XrSession), session, (const XrFrameEndInfo *), frameEndInfo)
+ EXT_PROTO_XRRESULT_FUNC1(xrEndSession, (XrSession), session)
+ EXT_PROTO_XRRESULT_FUNC3(xrEnumerateApiLayerProperties, (uint32_t), propertyCapacityInput, (uint32_t *), propertyCountOutput, (XrApiLayerProperties *), properties)
+ EXT_PROTO_XRRESULT_FUNC4(xrEnumerateInstanceExtensionProperties, (const char *), layerName, (uint32_t), propertyCapacityInput, (uint32_t *), propertyCountOutput, (XrExtensionProperties *), properties)
+ EXT_PROTO_XRRESULT_FUNC4(xrEnumerateReferenceSpaces, (XrSession), session, (uint32_t), spaceCapacityInput, (uint32_t *), spaceCountOutput, (XrReferenceSpaceType *), spaces)
+ EXT_PROTO_XRRESULT_FUNC4(xrEnumerateSwapchainFormats, (XrSession), session, (uint32_t), formatCapacityInput, (uint32_t *), formatCountOutput, (int64_t *), formats)
+ EXT_PROTO_XRRESULT_FUNC5(xrEnumerateViewConfigurations, (XrInstance), instance, (XrSystemId), systemId, (uint32_t), viewConfigurationTypeCapacityInput, (uint32_t *), viewConfigurationTypeCountOutput, (XrViewConfigurationType *), viewConfigurationTypes)
+ EXT_PROTO_XRRESULT_FUNC6(xrEnumerateViewConfigurationViews, (XrInstance), instance, (XrSystemId), systemId, (XrViewConfigurationType), viewConfigurationType, (uint32_t), viewCapacityInput, (uint32_t *), viewCountOutput, (XrViewConfigurationView *), views)
+ EXT_PROTO_XRRESULT_FUNC3(xrGetActionStateBoolean, (XrSession), session, (const XrActionStateGetInfo *), getInfo, (XrActionStateBoolean *), state)
+ EXT_PROTO_XRRESULT_FUNC3(xrGetActionStateFloat, (XrSession), session, (const XrActionStateGetInfo *), getInfo, (XrActionStateFloat *), state)
+ EXT_PROTO_XRRESULT_FUNC3(xrGetActionStateVector2f, (XrSession), session, (const XrActionStateGetInfo *), getInfo, (XrActionStateVector2f *), state)
+ EXT_PROTO_XRRESULT_FUNC3(xrGetCurrentInteractionProfile, (XrSession), session, (XrPath), topLevelUserPath, (XrInteractionProfileState *), interactionProfile)
+ EXT_PROTO_XRRESULT_FUNC2(xrGetInstanceProperties, (XrInstance), instance, (XrInstanceProperties *), instanceProperties)
+ EXT_PROTO_XRRESULT_FUNC3(xrGetSystem, (XrInstance), instance, (const XrSystemGetInfo *), getInfo, (XrSystemId *), systemId)
+ EXT_PROTO_XRRESULT_FUNC3(xrGetSystemProperties, (XrInstance), instance, (XrSystemId), systemId, (XrSystemProperties *), properties)
+ EXT_PROTO_XRRESULT_FUNC4(xrLocateSpace, (XrSpace), space, (XrSpace), baseSpace, (XrTime), time, (XrSpaceLocation *), location)
+ EXT_PROTO_XRRESULT_FUNC6(xrLocateViews, (XrSession), session, (const XrViewLocateInfo *), viewLocateInfo, (XrViewState *), viewState, (uint32_t), viewCapacityInput, (uint32_t *), viewCountOutput, (XrView *), views)
+ EXT_PROTO_XRRESULT_FUNC5(xrPathToString, (XrInstance), instance, (XrPath), path, (uint32_t), bufferCapacityInput, (uint32_t *), bufferCountOutput, (char *), buffer)
+ EXT_PROTO_XRRESULT_FUNC2(xrPollEvent, (XrInstance), instance, (XrEventDataBuffer *), eventData)
+ EXT_PROTO_XRRESULT_FUNC2(xrReleaseSwapchainImage, (XrSwapchain), swapchain, (const XrSwapchainImageReleaseInfo *), releaseInfo)
+ EXT_PROTO_XRRESULT_FUNC3(xrResultToString, (XrInstance), instance, (XrResult), value, (char *), buffer)
+ EXT_PROTO_XRRESULT_FUNC3(xrStringToPath, (XrInstance), instance, (const char *), pathString, (XrPath *), path)
+ EXT_PROTO_XRRESULT_FUNC2(xrSuggestInteractionProfileBindings, (XrInstance), instance, (const XrInteractionProfileSuggestedBinding *), suggestedBindings)
+ EXT_PROTO_XRRESULT_FUNC2(xrSyncActions, (XrSession), session, (const XrActionsSyncInfo *), syncInfo)
+ EXT_PROTO_XRRESULT_FUNC3(xrWaitFrame, (XrSession), session, (const XrFrameWaitInfo *), frameWaitInfo, (XrFrameState *), frameState)
+ EXT_PROTO_XRRESULT_FUNC2(xrWaitSwapchainImage, (XrSwapchain), swapchain, (const XrSwapchainImageWaitInfo *), waitInfo)
+
// instance
bool create_instance();
bool get_system_info();
@@ -212,9 +275,7 @@ private:
// convencience
void copy_string_to_char_buffer(const String p_string, char *p_buffer, int p_buffer_len);
-protected:
- friend class OpenXRVulkanExtension;
-
+public:
XrInstance get_instance() const { return instance; };
XrSystemId get_system_id() const { return system_id; };
XrSession get_session() const { return session; };
@@ -227,10 +288,12 @@ protected:
XRPose::TrackingConfidence transform_from_location(const XrHandJointLocationEXT &p_location, Transform3D &r_transform);
void parse_velocities(const XrSpaceVelocity &p_velocity, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity);
-public:
+ bool xr_result(XrResult result, const char *format, Array args = Array()) const;
+
static bool openxr_is_enabled(bool p_check_run_in_editor = true);
static OpenXRAPI *get_singleton();
+ XrResult get_instance_proc_addr(const char *p_name, PFN_xrVoidFunction *p_addr);
String get_error_string(XrResult result);
String get_swapchain_format_name(int64_t p_swapchain_format) const;
@@ -243,8 +306,9 @@ public:
bool initialize_session();
void finish();
- XrTime get_next_frame_time() { return frame_state.predictedDisplayTime + frame_state.predictedDisplayPeriod; };
- bool can_render() { return instance != XR_NULL_HANDLE && session != XR_NULL_HANDLE && running && view_pose_valid && frame_state.shouldRender; };
+ XrSpace get_play_space() const { return play_space; }
+ XrTime get_next_frame_time() { return frame_state.predictedDisplayTime + frame_state.predictedDisplayPeriod; }
+ bool can_render() { return instance != XR_NULL_HANDLE && session != XR_NULL_HANDLE && running && view_pose_valid && frame_state.shouldRender; }
Size2 get_recommended_target_size();
XRPose::TrackingConfidence get_head_center(Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity);
@@ -288,6 +352,9 @@ public:
XRPose::TrackingConfidence get_action_pose(RID p_action, RID p_tracker, Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity);
bool trigger_haptic_pulse(RID p_action, RID p_tracker, float p_frequency, float p_amplitude, XrDuration p_duration_ns);
+ void register_composition_layer_provider(OpenXRCompositionLayerProvider *provider);
+ void unregister_composition_layer_provider(OpenXRCompositionLayerProvider *provider);
+
OpenXRAPI();
~OpenXRAPI();
};
diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp
index 6c2f08e21d..01e148e00f 100644
--- a/modules/openxr/openxr_interface.cpp
+++ b/modules/openxr/openxr_interface.cpp
@@ -176,33 +176,35 @@ void OpenXRInterface::_load_action_map() {
// Note, we can only have one entry per interaction profile so if it already exists we clear it out
RID ip = openxr_api->interaction_profile_create(xr_interaction_profile->get_interaction_profile_path());
- openxr_api->interaction_profile_clear_bindings(ip);
-
- Array xr_bindings = xr_interaction_profile->get_bindings();
- for (int j = 0; j < xr_bindings.size(); j++) {
- Ref<OpenXRIPBinding> xr_binding = xr_bindings[j];
- Ref<OpenXRAction> xr_action = xr_binding->get_action();
-
- Action *action = nullptr;
- if (xr_actions.has(xr_action)) {
- action = xr_actions[xr_action];
- } else {
- print_line("Action ", xr_action->get_name(), " isn't part of an action set!");
- continue;
- }
+ if (ip.is_valid()) {
+ openxr_api->interaction_profile_clear_bindings(ip);
+
+ Array xr_bindings = xr_interaction_profile->get_bindings();
+ for (int j = 0; j < xr_bindings.size(); j++) {
+ Ref<OpenXRIPBinding> xr_binding = xr_bindings[j];
+ Ref<OpenXRAction> xr_action = xr_binding->get_action();
+
+ Action *action = nullptr;
+ if (xr_actions.has(xr_action)) {
+ action = xr_actions[xr_action];
+ } else {
+ print_line("Action ", xr_action->get_name(), " isn't part of an action set!");
+ continue;
+ }
- PackedStringArray paths = xr_binding->get_paths();
- for (int k = 0; k < paths.size(); k++) {
- openxr_api->interaction_profile_add_binding(ip, action->action_rid, paths[k]);
+ PackedStringArray paths = xr_binding->get_paths();
+ for (int k = 0; k < paths.size(); k++) {
+ openxr_api->interaction_profile_add_binding(ip, action->action_rid, paths[k]);
+ }
}
- }
- // Now submit our suggestions
- openxr_api->interaction_profile_suggest_bindings(ip);
+ // Now submit our suggestions
+ openxr_api->interaction_profile_suggest_bindings(ip);
- // And record it in our array so we can clean it up later on
- if (interaction_profiles.has(ip)) {
- interaction_profiles.push_back(ip);
+ // And record it in our array so we can clean it up later on
+ if (interaction_profiles.has(ip)) {
+ interaction_profiles.push_back(ip);
+ }
}
}
}
@@ -744,6 +746,24 @@ void OpenXRInterface::end_frame() {
}
}
+bool OpenXRInterface::is_passthrough_supported() {
+ return passthrough_wrapper != nullptr && passthrough_wrapper->is_passthrough_supported();
+}
+
+bool OpenXRInterface::is_passthrough_enabled() {
+ return passthrough_wrapper != nullptr && passthrough_wrapper->is_passthrough_enabled();
+}
+
+bool OpenXRInterface::start_passthrough() {
+ return passthrough_wrapper != nullptr && passthrough_wrapper->start_passthrough();
+}
+
+void OpenXRInterface::stop_passthrough() {
+ if (passthrough_wrapper) {
+ passthrough_wrapper->stop_passthrough();
+ }
+}
+
void OpenXRInterface::on_state_ready() {
emit_signal(SNAME("session_begun"));
}
@@ -774,6 +794,8 @@ OpenXRInterface::OpenXRInterface() {
_set_default_pos(head_transform, 1.0, 0);
_set_default_pos(transform_for_view[0], 1.0, 1);
_set_default_pos(transform_for_view[1], 1.0, 2);
+
+ passthrough_wrapper = OpenXRFbPassthroughExtensionWrapper::get_singleton();
}
OpenXRInterface::~OpenXRInterface() {
diff --git a/modules/openxr/openxr_interface.h b/modules/openxr/openxr_interface.h
index a99012fd1d..3765f18637 100644
--- a/modules/openxr/openxr_interface.h
+++ b/modules/openxr/openxr_interface.h
@@ -37,6 +37,8 @@
#include "action_map/openxr_action_map.h"
#include "openxr_api.h"
+#include "extensions/openxr_fb_passthrough_extension_wrapper.h"
+
// declare some default strings
#define INTERACTION_PROFILE_NONE "/interaction_profiles/none"
@@ -47,6 +49,7 @@ private:
OpenXRAPI *openxr_api = nullptr;
bool initialized = false;
XRInterface::TrackingStatus tracking_state;
+ OpenXRFbPassthroughExtensionWrapper *passthrough_wrapper = nullptr;
// At a minimum we need a tracker for our head
Ref<XRPositionalTracker> head;
@@ -129,6 +132,11 @@ public:
virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override;
virtual void end_frame() override;
+ virtual bool is_passthrough_supported() override;
+ virtual bool is_passthrough_enabled() override;
+ virtual bool start_passthrough() override;
+ virtual void stop_passthrough() override;
+
void on_state_ready();
void on_state_visible();
void on_state_focused();
diff --git a/modules/openxr/register_types.cpp b/modules/openxr/register_types.cpp
index c765f169dc..5694fffe39 100644
--- a/modules/openxr/register_types.cpp
+++ b/modules/openxr/register_types.cpp
@@ -38,6 +38,8 @@
#include "action_map/openxr_action_set.h"
#include "action_map/openxr_interaction_profile.h"
+#include "scene/openxr_hand.h"
+
#ifdef TOOLS_ENABLED
#include "editor/editor_node.h"
@@ -82,6 +84,8 @@ void initialize_openxr_module(ModuleInitializationLevel p_level) {
GDREGISTER_CLASS(OpenXRIPBinding);
GDREGISTER_CLASS(OpenXRInteractionProfile);
+ GDREGISTER_CLASS(OpenXRHand);
+
XRServer *xr_server = XRServer::get_singleton();
if (xr_server) {
openxr_interface.instantiate();
diff --git a/modules/openxr/scene/openxr_hand.cpp b/modules/openxr/scene/openxr_hand.cpp
new file mode 100644
index 0000000000..2ae13a1026
--- /dev/null
+++ b/modules/openxr/scene/openxr_hand.cpp
@@ -0,0 +1,307 @@
+/*************************************************************************/
+/* openxr_hand.cpp */
+/*************************************************************************/
+/* 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. */
+/*************************************************************************/
+
+#include "../extensions/openxr_hand_tracking_extension.h"
+#include "../openxr_api.h"
+
+#include "openxr_hand.h"
+#include "scene/3d/skeleton_3d.h"
+#include "servers/xr_server.h"
+
+void OpenXRHand::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_hand", "hand"), &OpenXRHand::set_hand);
+ ClassDB::bind_method(D_METHOD("get_hand"), &OpenXRHand::get_hand);
+
+ ClassDB::bind_method(D_METHOD("set_hand_skeleton", "hand_skeleton"), &OpenXRHand::set_hand_skeleton);
+ ClassDB::bind_method(D_METHOD("get_hand_skeleton"), &OpenXRHand::get_hand_skeleton);
+
+ ClassDB::bind_method(D_METHOD("set_motion_range", "motion_range"), &OpenXRHand::set_motion_range);
+ ClassDB::bind_method(D_METHOD("get_motion_range"), &OpenXRHand::get_motion_range);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "hand", PROPERTY_HINT_ENUM, "Left,Right"), "set_hand", "get_hand");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_range", PROPERTY_HINT_ENUM, "Unobstructed,Conform to controller"), "set_motion_range", "get_motion_range");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "hand_skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton3D"), "set_hand_skeleton", "get_hand_skeleton");
+
+ BIND_ENUM_CONSTANT(HAND_LEFT);
+ BIND_ENUM_CONSTANT(HAND_RIGHT);
+ BIND_ENUM_CONSTANT(HAND_MAX);
+
+ BIND_ENUM_CONSTANT(MOTION_RANGE_UNOBSTRUCTED);
+ BIND_ENUM_CONSTANT(MOTION_RANGE_CONFORM_TO_CONTROLLER);
+ BIND_ENUM_CONSTANT(MOTION_RANGE_MAX);
+}
+
+OpenXRHand::OpenXRHand() {
+ openxr_api = OpenXRAPI::get_singleton();
+ hand_tracking_ext = OpenXRHandTrackingExtension::get_singleton();
+}
+
+void OpenXRHand::set_hand(const Hands p_hand) {
+ ERR_FAIL_INDEX(p_hand, HAND_MAX);
+
+ hand = p_hand;
+}
+
+OpenXRHand::Hands OpenXRHand::get_hand() const {
+ return hand;
+}
+
+void OpenXRHand::set_hand_skeleton(const NodePath &p_hand_skeleton) {
+ hand_skeleton = p_hand_skeleton;
+
+ // TODO if inside tree call _get_bones()
+}
+
+void OpenXRHand::set_motion_range(const MotionRange p_motion_range) {
+ ERR_FAIL_INDEX(p_motion_range, MOTION_RANGE_MAX);
+ motion_range = p_motion_range;
+
+ _set_motion_range();
+}
+
+OpenXRHand::MotionRange OpenXRHand::get_motion_range() const {
+ return motion_range;
+}
+
+NodePath OpenXRHand::get_hand_skeleton() const {
+ return hand_skeleton;
+}
+
+void OpenXRHand::_set_motion_range() {
+ if (!hand_tracking_ext) {
+ return;
+ }
+
+ XrHandJointsMotionRangeEXT xr_motion_range;
+ switch (motion_range) {
+ case MOTION_RANGE_UNOBSTRUCTED:
+ xr_motion_range = XR_HAND_JOINTS_MOTION_RANGE_UNOBSTRUCTED_EXT;
+ break;
+ case MOTION_RANGE_CONFORM_TO_CONTROLLER:
+ xr_motion_range = XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT;
+ break;
+ default:
+ xr_motion_range = XR_HAND_JOINTS_MOTION_RANGE_CONFORMING_TO_CONTROLLER_EXT;
+ break;
+ }
+
+ hand_tracking_ext->set_motion_range(hand, xr_motion_range);
+}
+
+Skeleton3D *OpenXRHand::get_skeleton() {
+ if (!has_node(hand_skeleton)) {
+ return nullptr;
+ }
+
+ Node *node = get_node(hand_skeleton);
+ if (!node) {
+ return nullptr;
+ }
+
+ Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(node);
+ return skeleton;
+}
+
+void OpenXRHand::_get_bones() {
+ const char *bone_names[XR_HAND_JOINT_COUNT_EXT] = {
+ "Palm",
+ "Wrist",
+ "Thumb_Metacarpal",
+ "Thumb_Proximal",
+ "Thumb_Distal",
+ "Thumb_Tip",
+ "Index_Metacarpal",
+ "Index_Proximal",
+ "Index_Intermediate",
+ "Index_Distal",
+ "Index_Tip",
+ "Middle_Metacarpal",
+ "Middle_Proximal",
+ "Middle_Intermediate",
+ "Middle_Distal",
+ "Middle_Tip",
+ "Ring_Metacarpal",
+ "Ring_Proximal",
+ "Ring_Intermediate",
+ "Ring_Distal",
+ "Ring_Tip",
+ "Little_Metacarpal",
+ "Little_Proximal",
+ "Little_Intermediate",
+ "Little_Distal",
+ "Little_Tip",
+ };
+
+ // reset JIC
+ for (int i = 0; i < XR_HAND_JOINT_COUNT_EXT; i++) {
+ bones[i] = -1;
+ }
+
+ Skeleton3D *skeleton = get_skeleton();
+ if (!skeleton) {
+ return;
+ }
+
+ // We cast to spatials which should allow us to use any subclass of that.
+ for (int i = 0; i < XR_HAND_JOINT_COUNT_EXT; i++) {
+ String bone_name = bone_names[i];
+ if (hand == 0) {
+ bone_name += String("_L");
+ } else {
+ bone_name += String("_R");
+ }
+
+ bones[i] = skeleton->find_bone(bone_name);
+ if (bones[i] == -1) {
+ print_line("Couldn't obtain bone for", bone_name);
+ }
+ }
+}
+
+void OpenXRHand::_update_skeleton() {
+ if (openxr_api == nullptr || !openxr_api->is_initialized()) {
+ return;
+ } else if (hand_tracking_ext == nullptr || !hand_tracking_ext->get_active()) {
+ return;
+ }
+
+ Skeleton3D *skeleton = get_skeleton();
+ if (!skeleton) {
+ return;
+ }
+
+ // we cache our transforms so we can quickly calculate local transforms
+ XRPose::TrackingConfidence confidences[XR_HAND_JOINT_COUNT_EXT];
+ Quaternion quaternions[XR_HAND_JOINT_COUNT_EXT];
+ Quaternion inv_quaternions[XR_HAND_JOINT_COUNT_EXT];
+ Vector3 positions[XR_HAND_JOINT_COUNT_EXT];
+
+ const OpenXRHandTrackingExtension::HandTracker *hand_tracker = hand_tracking_ext->get_hand_tracker(hand);
+ const float ws = XRServer::get_singleton()->get_world_scale();
+
+ if (hand_tracker->is_initialised && hand_tracker->locations.isActive) {
+ for (int i = 0; i < XR_HAND_JOINT_COUNT_EXT; i++) {
+ confidences[i] = XRPose::XR_TRACKING_CONFIDENCE_NONE;
+ quaternions[i] = Quaternion();
+ positions[i] = Vector3();
+
+ const auto &location = hand_tracker->joint_locations[i];
+ const auto &pose = location.pose;
+
+ if (location.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) {
+ if (pose.orientation.x != 0 || pose.orientation.y != 0 || pose.orientation.y != 0 || pose.orientation.w != 0) {
+ quaternions[i] = Quaternion(pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w);
+ inv_quaternions[i] = quaternions[i].inverse();
+
+ if (location.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) {
+ confidences[i] = XRPose::XR_TRACKING_CONFIDENCE_HIGH;
+ positions[i] = Vector3(pose.position.x * ws, pose.position.y * ws, pose.position.z * ws);
+
+ // TODO get inverse of position, we'll do this later. For now we're ignoring bone positions which generally works better anyway
+ } else {
+ confidences[i] = XRPose::XR_TRACKING_CONFIDENCE_LOW;
+ }
+ }
+ }
+ }
+
+ if (confidences[XR_HAND_JOINT_PALM_EXT] != XRPose::XR_TRACKING_CONFIDENCE_NONE) {
+ // now update our skeleton
+ for (int i = 0; i < XR_HAND_JOINT_COUNT_EXT; i++) {
+ if (bones[i] != -1) {
+ int bone = bones[i];
+ int parent = skeleton->get_bone_parent(bone);
+
+ // Get our target quaternion
+ Quaternion q = quaternions[i];
+
+ // get local translation, parent should already be processed
+ if (parent == -1) {
+ // use our palm location here, that is what we are tracking
+ q = inv_quaternions[XR_HAND_JOINT_PALM_EXT] * q;
+ } else {
+ int found = false;
+ for (int b = 0; b < XR_HAND_JOINT_COUNT_EXT && !found; b++) {
+ if (bones[b] == parent) {
+ q = inv_quaternions[b] * q;
+ found = true;
+ }
+ }
+ }
+
+ // And get the movement from our rest position
+ // Transform3D rest = skeleton->get_bone_rest(bones[i]);
+ // q = rest.basis.get_quaternion().inverse() * q;
+
+ // and set our pose
+ // skeleton->set_bone_pose_position(bones[i], v);
+ skeleton->set_bone_pose_rotation(bones[i], q);
+ }
+ }
+
+ Transform3D t;
+ t.basis = Basis(quaternions[XR_HAND_JOINT_PALM_EXT]);
+ t.origin = positions[XR_HAND_JOINT_PALM_EXT];
+ set_transform(t);
+
+ // show it
+ set_visible(true);
+ } else {
+ // hide it
+ set_visible(false);
+ }
+ } else {
+ // hide it
+ set_visible(false);
+ }
+}
+
+void OpenXRHand::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ _get_bones();
+
+ set_process_internal(true);
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ set_process_internal(false);
+
+ // reset
+ for (int i = 0; i < XR_HAND_JOINT_COUNT_EXT; i++) {
+ bones[i] = -1;
+ }
+ } break;
+ case NOTIFICATION_INTERNAL_PROCESS: {
+ _update_skeleton();
+ } break;
+ default: {
+ } break;
+ }
+}
diff --git a/modules/openxr/scene/openxr_hand.h b/modules/openxr/scene/openxr_hand.h
new file mode 100644
index 0000000000..f8499cc172
--- /dev/null
+++ b/modules/openxr/scene/openxr_hand.h
@@ -0,0 +1,93 @@
+/*************************************************************************/
+/* openxr_hand.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 OPENXR_HAND_H
+#define OPENXR_HAND_H
+
+#include "scene/3d/node_3d.h"
+#include "scene/3d/skeleton_3d.h"
+
+class OpenXRAPI;
+class OpenXRHandTrackingExtension;
+
+class OpenXRHand : public Node3D {
+ GDCLASS(OpenXRHand, Node3D);
+
+public:
+ enum Hands {
+ HAND_LEFT,
+ HAND_RIGHT,
+ HAND_MAX
+ };
+
+ enum MotionRange {
+ MOTION_RANGE_UNOBSTRUCTED,
+ MOTION_RANGE_CONFORM_TO_CONTROLLER,
+ MOTION_RANGE_MAX
+ };
+
+private:
+ OpenXRAPI *openxr_api = nullptr;
+ OpenXRHandTrackingExtension *hand_tracking_ext = nullptr;
+
+ Hands hand = HAND_LEFT;
+ MotionRange motion_range = MOTION_RANGE_UNOBSTRUCTED;
+ NodePath hand_skeleton;
+
+ int64_t bones[XR_HAND_JOINT_COUNT_EXT];
+
+ void _set_motion_range();
+
+ Skeleton3D *get_skeleton();
+ void _get_bones();
+ void _update_skeleton();
+
+protected:
+ static void _bind_methods();
+
+public:
+ OpenXRHand();
+
+ void set_hand(const Hands p_hand);
+ Hands get_hand() const;
+
+ void set_motion_range(const MotionRange p_motion_range);
+ MotionRange get_motion_range() const;
+
+ void set_hand_skeleton(const NodePath &p_hand_skeleton);
+ NodePath get_hand_skeleton() const;
+
+ void _notification(int p_what);
+};
+
+VARIANT_ENUM_CAST(OpenXRHand::Hands)
+VARIANT_ENUM_CAST(OpenXRHand::MotionRange)
+
+#endif // OPENXR_HAND_H
diff --git a/modules/openxr/util.h b/modules/openxr/util.h
new file mode 100644
index 0000000000..5c79890830
--- /dev/null
+++ b/modules/openxr/util.h
@@ -0,0 +1,110 @@
+/*************************************************************************/
+/* util.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 UTIL_H
+#define UTIL_H
+
+#define UNPACK(...) __VA_ARGS__
+
+#define INIT_XR_FUNC_V(openxr_api, name) \
+ do { \
+ XrResult get_instance_proc_addr_result; \
+ get_instance_proc_addr_result = openxr_api->get_instance_proc_addr(#name, (PFN_xrVoidFunction *)&name##_ptr); \
+ ERR_FAIL_COND_V(XR_FAILED(get_instance_proc_addr_result), false); \
+ } while (0)
+
+#define EXT_INIT_XR_FUNC_V(name) INIT_XR_FUNC_V(openxr_api, name)
+#define OPENXR_API_INIT_XR_FUNC_V(name) INIT_XR_FUNC_V(this, name)
+
+#define INIT_XR_FUNC(openxr_api, name) \
+ do { \
+ XrResult get_instance_proc_addr_result; \
+ get_instance_proc_addr_result = openxr_api->get_instance_proc_addr(#name, (PFN_xrVoidFunction *)&name##_ptr); \
+ ERR_FAIL_COND(XR_FAILED(get_instance_proc_addr_result)); \
+ } while (0)
+
+#define EXT_INIT_XR_FUNC(name) INIT_XR_FUNC(openxr_api, name)
+#define OPENXR_API_INIT_XR_FUNC(name) INIT_XR_FUNC(this, name)
+
+#define EXT_PROTO_XRRESULT_FUNC1(func_name, arg1_type, arg1) \
+ PFN_##func_name func_name##_ptr = nullptr; \
+ XRAPI_ATTR XrResult XRAPI_CALL func_name(UNPACK arg1_type arg1) const { \
+ if (!func_name##_ptr) { \
+ return XR_ERROR_HANDLE_INVALID; \
+ } \
+ return (*func_name##_ptr)(arg1); \
+ }
+
+#define EXT_PROTO_XRRESULT_FUNC2(func_name, arg1_type, arg1, arg2_type, arg2) \
+ PFN_##func_name func_name##_ptr = nullptr; \
+ XRAPI_ATTR XrResult XRAPI_CALL func_name(UNPACK arg1_type arg1, UNPACK arg2_type arg2) const { \
+ if (!func_name##_ptr) { \
+ return XR_ERROR_HANDLE_INVALID; \
+ } \
+ return (*func_name##_ptr)(arg1, arg2); \
+ }
+
+#define EXT_PROTO_XRRESULT_FUNC3(func_name, arg1_type, arg1, arg2_type, arg2, arg3_type, arg3) \
+ PFN_##func_name func_name##_ptr = nullptr; \
+ XRAPI_ATTR XrResult XRAPI_CALL func_name(UNPACK arg1_type arg1, UNPACK arg2_type arg2, UNPACK arg3_type arg3) const { \
+ if (!func_name##_ptr) { \
+ return XR_ERROR_HANDLE_INVALID; \
+ } \
+ return (*func_name##_ptr)(arg1, arg2, arg3); \
+ }
+
+#define EXT_PROTO_XRRESULT_FUNC4(func_name, arg1_type, arg1, arg2_type, arg2, arg3_type, arg3, arg4_type, arg4) \
+ PFN_##func_name func_name##_ptr = nullptr; \
+ XRAPI_ATTR XrResult XRAPI_CALL func_name(UNPACK arg1_type arg1, UNPACK arg2_type arg2, UNPACK arg3_type arg3, UNPACK arg4_type arg4) const { \
+ if (!func_name##_ptr) { \
+ return XR_ERROR_HANDLE_INVALID; \
+ } \
+ return (*func_name##_ptr)(arg1, arg2, arg3, arg4); \
+ }
+
+#define EXT_PROTO_XRRESULT_FUNC5(func_name, arg1_type, arg1, arg2_type, arg2, arg3_type, arg3, arg4_type, arg4, arg5_type, arg5) \
+ PFN_##func_name func_name##_ptr = nullptr; \
+ XRAPI_ATTR XrResult XRAPI_CALL func_name(UNPACK arg1_type arg1, UNPACK arg2_type arg2, UNPACK arg3_type arg3, UNPACK arg4_type arg4, UNPACK arg5_type arg5) const { \
+ if (!func_name##_ptr) { \
+ return XR_ERROR_HANDLE_INVALID; \
+ } \
+ return (*func_name##_ptr)(arg1, arg2, arg3, arg4, arg5); \
+ }
+
+#define EXT_PROTO_XRRESULT_FUNC6(func_name, arg1_type, arg1, arg2_type, arg2, arg3_type, arg3, arg4_type, arg4, arg5_type, arg5, arg6_type, arg6) \
+ PFN_##func_name func_name##_ptr = nullptr; \
+ XRAPI_ATTR XrResult XRAPI_CALL func_name(UNPACK arg1_type arg1, UNPACK arg2_type arg2, UNPACK arg3_type arg3, UNPACK arg4_type arg4, UNPACK arg5_type arg5, UNPACK arg6_type arg6) const { \
+ if (!func_name##_ptr) { \
+ return XR_ERROR_HANDLE_INVALID; \
+ } \
+ return (*func_name##_ptr)(arg1, arg2, arg3, arg4, arg5, arg6); \
+ }
+
+#endif // UTIL_H
diff --git a/modules/raycast/SCsub b/modules/raycast/SCsub
index 074795759a..20b05816e1 100644
--- a/modules/raycast/SCsub
+++ b/modules/raycast/SCsub
@@ -63,7 +63,8 @@ if env["builtin_embree"]:
thirdparty_sources = [thirdparty_dir + file for file in embree_src]
env_raycast.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "include"])
- env_raycast.Append(CPPDEFINES=["EMBREE_TARGET_SSE2", "EMBREE_LOWEST_ISA", "TASKING_INTERNAL", "NDEBUG"])
+ env_raycast.Append(CPPDEFINES=["EMBREE_TARGET_SSE2", "EMBREE_LOWEST_ISA", "TASKING_INTERNAL"])
+ env_raycast.AppendUnique(CPPDEFINES=["NDEBUG"]) # No assert() even in debug builds.
if not env.msvc:
if env["arch"] == "x86_64":
@@ -78,6 +79,9 @@ if env["builtin_embree"]:
else:
env.Append(LIBS=["psapi"])
+ if env.msvc: # Disable bogus warning about intentional struct padding.
+ env_raycast.Append(CCFLAGS=["/wd4324"])
+
env_thirdparty = env_raycast.Clone()
env_thirdparty.force_optimization_on_debug()
env_thirdparty.disable_warnings()
diff --git a/modules/raycast/lightmap_raycaster.cpp b/modules/raycast/lightmap_raycaster_embree.cpp
index 9b35b5616e..e6a579bd3a 100644
--- a/modules/raycast/lightmap_raycaster.cpp
+++ b/modules/raycast/lightmap_raycaster_embree.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* lightmap_raycaster.cpp */
+/* lightmap_raycaster_embree.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -30,7 +30,7 @@
#ifdef TOOLS_ENABLED
-#include "lightmap_raycaster.h"
+#include "lightmap_raycaster_embree.h"
#ifdef __SSE2__
#include <pmmintrin.h>
@@ -193,4 +193,4 @@ LightmapRaycasterEmbree::~LightmapRaycasterEmbree() {
}
}
-#endif
+#endif // TOOLS_ENABLED
diff --git a/modules/raycast/lightmap_raycaster.h b/modules/raycast/lightmap_raycaster_embree.h
index 2e9f59dda4..0c3371f07c 100644
--- a/modules/raycast/lightmap_raycaster.h
+++ b/modules/raycast/lightmap_raycaster_embree.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* lightmap_raycaster.h */
+/* lightmap_raycaster_embree.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,6 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef LIGHTMAP_RAYCASTER_EMBREE_H
+#define LIGHTMAP_RAYCASTER_EMBREE_H
+
#ifdef TOOLS_ENABLED
#include "core/io/image.h"
@@ -74,4 +77,6 @@ public:
~LightmapRaycasterEmbree();
};
-#endif // LIGHTMAP_RAYCASTER_H
+#endif // TOOLS_ENABLED
+
+#endif // LIGHTMAP_RAYCASTER_EMBREE_H
diff --git a/modules/raycast/register_types.cpp b/modules/raycast/register_types.cpp
index 42de1d971d..a8380b00ba 100644
--- a/modules/raycast/register_types.cpp
+++ b/modules/raycast/register_types.cpp
@@ -30,9 +30,9 @@
#include "register_types.h"
-#include "lightmap_raycaster.h"
+#include "lightmap_raycaster_embree.h"
#include "raycast_occlusion_cull.h"
-#include "static_raycaster.h"
+#include "static_raycaster_embree.h"
RaycastOcclusionCull *raycast_occlusion_cull = nullptr;
diff --git a/modules/raycast/register_types.h b/modules/raycast/register_types.h
index a917285390..25a6c346b9 100644
--- a/modules/raycast/register_types.h
+++ b/modules/raycast/register_types.h
@@ -28,7 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef RAYCAST_REGISTER_TYPES_H
+#define RAYCAST_REGISTER_TYPES_H
+
#include "modules/register_module_types.h"
void initialize_raycast_module(ModuleInitializationLevel p_level);
void uninitialize_raycast_module(ModuleInitializationLevel p_level);
+
+#endif // RAYCAST_REGISTER_TYPES_H
diff --git a/modules/raycast/static_raycaster.cpp b/modules/raycast/static_raycaster_embree.cpp
index 7659eea27f..b5a4ab42d4 100644
--- a/modules/raycast/static_raycaster.cpp
+++ b/modules/raycast/static_raycaster_embree.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* static_raycaster.cpp */
+/* static_raycaster_embree.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -30,7 +30,7 @@
#ifdef TOOLS_ENABLED
-#include "static_raycaster.h"
+#include "static_raycaster_embree.h"
#ifdef __SSE2__
#include <pmmintrin.h>
@@ -134,4 +134,4 @@ StaticRaycasterEmbree::~StaticRaycasterEmbree() {
}
}
-#endif
+#endif // TOOLS_ENABLED
diff --git a/modules/raycast/static_raycaster.h b/modules/raycast/static_raycaster_embree.h
index 607a392683..4d631e3ca0 100644
--- a/modules/raycast/static_raycaster.h
+++ b/modules/raycast/static_raycaster_embree.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* static_raycaster.h */
+/* static_raycaster_embree.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,6 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef STATIC_RAYCASTER_EMBREE_H
+#define STATIC_RAYCASTER_EMBREE_H
+
#ifdef TOOLS_ENABLED
#include "core/math/static_raycaster.h"
@@ -61,4 +64,6 @@ public:
~StaticRaycasterEmbree();
};
-#endif // STATIC_RAYCASTER_H
+#endif // TOOLS_ENABLED
+
+#endif // STATIC_RAYCASTER_EMBREE_H
diff --git a/modules/regex/SCsub b/modules/regex/SCsub
index deb9db7591..6fd7cd47f3 100644
--- a/modules/regex/SCsub
+++ b/modules/regex/SCsub
@@ -58,10 +58,10 @@ if env["builtin_pcre2"]:
env_pcre2["OBJSUFFIX"] = "_" + width + env_pcre2["OBJSUFFIX"]
env_pcre2.Append(CPPDEFINES=[("PCRE2_CODE_UNIT_WIDTH", width)])
env_pcre2.add_source_files(thirdparty_obj, thirdparty_sources)
- env.modules_sources += thirdparty_obj
pcre2_builtin("16")
pcre2_builtin("32")
+ env.modules_sources += thirdparty_obj
# Godot source files
diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp
index cd6081f91b..f43f2784c7 100644
--- a/modules/svg/image_loader_svg.cpp
+++ b/modules/svg/image_loader_svg.cpp
@@ -142,7 +142,7 @@ void ImageLoaderSVG::get_recognized_extensions(List<String> *p_extensions) const
p_extensions->push_back("svg");
}
-Error ImageLoaderSVG::load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, uint32_t p_flags, float p_scale) {
+Error ImageLoaderSVG::load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale) {
String svg = p_fileaccess->get_as_utf8_string();
if (p_flags & FLAG_CONVERT_COLORS) {
diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h
index e6f73ab18f..b0b0963c15 100644
--- a/modules/svg/image_loader_svg.h
+++ b/modules/svg/image_loader_svg.h
@@ -43,7 +43,7 @@ public:
void create_image_from_string(Ref<Image> p_image, String p_string, float p_scale, bool p_upsample, const HashMap<Color, Color> &p_color_map);
- virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, uint32_t p_flags, float p_scale) override;
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale) override;
virtual void get_recognized_extensions(List<String> *p_extensions) const override;
};
diff --git a/modules/svg/register_types.cpp b/modules/svg/register_types.cpp
index 5b4d1d31ca..323b1d652a 100644
--- a/modules/svg/register_types.cpp
+++ b/modules/svg/register_types.cpp
@@ -34,7 +34,7 @@
#include <thorvg.h>
-static ImageLoaderSVG *image_loader_svg = nullptr;
+static Ref<ImageLoaderSVG> image_loader_svg;
void initialize_svg_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
@@ -45,7 +45,8 @@ void initialize_svg_module(ModuleInitializationLevel p_level) {
if (tvg::Initializer::init(tvgEngine, 1) != tvg::Result::Success) {
return;
}
- image_loader_svg = memnew(ImageLoaderSVG);
+
+ image_loader_svg.instantiate();
ImageLoader::add_image_format_loader(image_loader_svg);
}
@@ -54,9 +55,12 @@ void uninitialize_svg_module(ModuleInitializationLevel p_level) {
return;
}
- if (!image_loader_svg) {
+ if (image_loader_svg.is_null()) {
+ // It failed to initialize so it was not added.
return;
}
- memdelete(image_loader_svg);
+
+ ImageLoader::remove_image_format_loader(image_loader_svg);
+ image_loader_svg.unref();
tvg::Initializer::term(tvg::CanvasEngine::Sw);
}
diff --git a/modules/text_server_adv/SCsub b/modules/text_server_adv/SCsub
index 8d0245f0f6..2261342467 100644
--- a/modules/text_server_adv/SCsub
+++ b/modules/text_server_adv/SCsub
@@ -215,6 +215,9 @@ if env["builtin_graphite"] and freetype_enabled and env["graphite"]:
]
)
+ if env.msvc: # Not our business to fix.
+ env_graphite.Append(CCFLAGS=["-D_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS"])
+
lib = env_graphite.add_library("graphite_builtin", thirdparty_sources)
thirdparty_obj += lib
@@ -445,7 +448,7 @@ if env["builtin_icu"]:
icu_data_name = "icudt71l.dat"
- if env_icu["tools"]:
+ if env.editor_build:
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.Prepend(CPPPATH=["#thirdparty/icu4c/"])
@@ -479,7 +482,7 @@ if env["builtin_icu"]:
"-DICU_DATA_NAME=" + icu_data_name,
]
)
- if env_text_server_adv["tools"]:
+ if env.editor_build:
env_text_server_adv.Append(CXXFLAGS=["-DICU_STATIC_DATA"])
env_text_server_adv.Prepend(CPPPATH=["#thirdparty/icu4c/common/", "#thirdparty/icu4c/i18n/"])
diff --git a/modules/text_server_adv/gdextension_build/SConstruct b/modules/text_server_adv/gdextension_build/SConstruct
index 0170c007ae..7ca8859ee6 100644
--- a/modules/text_server_adv/gdextension_build/SConstruct
+++ b/modules/text_server_adv/gdextension_build/SConstruct
@@ -19,6 +19,7 @@ env = SConscript("./godot-cpp/SConstruct")
env.__class__.disable_warnings = methods.disable_warnings
opts = Variables([], ARGUMENTS)
+opts.Add(BoolVariable("brotli_enabled", "Use Brotli library", True))
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))
@@ -162,6 +163,25 @@ if env["freetype_enabled"]:
]
thirdparty_freetype_sources += [thirdparty_zlib_dir + file for file in thirdparty_zlib_sources]
+ if env["brotli_enabled"]:
+ thirdparty_brotli_dir = "../../../thirdparty/brotli/"
+ thirdparty_brotli_sources = [
+ "common/constants.c",
+ "common/context.c",
+ "common/dictionary.c",
+ "common/platform.c",
+ "common/shared_dictionary.c",
+ "common/transform.c",
+ "dec/bit_reader.c",
+ "dec/decode.c",
+ "dec/huffman.c",
+ "dec/state.c",
+ ]
+ thirdparty_freetype_sources += [thirdparty_brotli_dir + file for file in thirdparty_brotli_sources]
+ env_freetype.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"])
+ env_freetype.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"])
+ env.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"])
+
env_freetype.Append(CPPPATH=[thirdparty_freetype_dir + "/include", thirdparty_zlib_dir, thirdparty_png_dir])
env.Append(CPPPATH=[thirdparty_freetype_dir + "/include"])
@@ -173,7 +193,7 @@ if env["freetype_enabled"]:
"FT_CONFIG_OPTION_SYSTEM_ZLIB",
]
)
- if env["target"] == "debug":
+ if env.dev_build:
env_freetype.Append(CPPDEFINES=["ZLIB_DEBUG"])
env.Append(CPPDEFINES=["MODULE_FREETYPE_ENABLED"])
@@ -265,6 +285,7 @@ env_harfbuzz.Append(
CPPPATH=[
"../../../thirdparty/harfbuzz/src",
"../../../thirdparty/icu4c/common/",
+ "../../../thirdparty/icu4c/i18n/",
]
)
@@ -569,6 +590,10 @@ thirdparty_icu_sources = [
"common/uvectr32.cpp",
"common/uvectr64.cpp",
"common/wintz.cpp",
+ "i18n/scriptset.cpp",
+ "i18n/ucln_in.cpp",
+ "i18n/uspoof.cpp",
+ "i18n/uspoof_impl.cpp",
]
thirdparty_icu_sources = [thirdparty_icu_dir + file for file in thirdparty_icu_sources]
@@ -584,7 +609,7 @@ if env["static_icu_data"]:
else:
thirdparty_sources += ["../icu_data/icudata_stub.cpp"]
-env_icu.Append(CPPPATH=["../../../thirdparty/icu4c/common/"])
+env_icu.Append(CPPPATH=["../../../thirdparty/icu4c/common/", "../../../thirdparty/icu4c/i18n/"])
env_icu.Append(
CXXFLAGS=[
"-DU_STATIC_IMPLEMENTATION",
@@ -610,7 +635,7 @@ env.Append(
"-DICU_DATA_NAME=" + icu_data_name,
]
)
-env.Append(CPPPATH=["../../../thirdparty/icu4c/common/"])
+env.Append(CPPPATH=["../../../thirdparty/icu4c/common/", "../../../thirdparty/icu4c/i18n/"])
if env["platform"] == "windows":
env.Append(LIBS=["advapi32"])
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index 7aebeafe70..d0301eeae3 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -33,7 +33,7 @@
#ifdef GDEXTENSION
// Headers for building as GDExtension plug-in.
-#include <godot_cpp/classes/file.hpp>
+#include <godot_cpp/classes/file_access.hpp>
#include <godot_cpp/classes/project_settings.hpp>
#include <godot_cpp/classes/rendering_server.hpp>
#include <godot_cpp/classes/translation_server.hpp>
@@ -45,7 +45,6 @@ using namespace godot;
// Headers for building as built-in module.
#include "core/config/project_settings.h"
-#include "core/core_bind.h"
#include "core/error/error_macros.h"
#include "core/object/worker_thread_pool.h"
#include "core/string/print_string.h"
@@ -53,8 +52,6 @@ using namespace godot;
#include "modules/modules_enabled.gen.h" // For freetype, msdfgen.
-using namespace core_bind;
-
#endif
// Built-in ICU data.
@@ -330,7 +327,7 @@ _FORCE_INLINE_ bool is_connected_to_prev(char32_t p_chr, char32_t p_pchr) {
/*************************************************************************/
-bool TextServerAdvanced::has_feature(Feature p_feature) const {
+bool TextServerAdvanced::_has_feature(Feature p_feature) const {
switch (p_feature) {
case FEATURE_SIMPLE_LAYOUT:
case FEATURE_BIDI_LAYOUT:
@@ -357,7 +354,7 @@ bool TextServerAdvanced::has_feature(Feature p_feature) const {
return false;
}
-String TextServerAdvanced::get_name() const {
+String TextServerAdvanced::_get_name() const {
#ifdef GDEXTENSION
return "ICU / HarfBuzz / Graphite (GDExtension)";
#else
@@ -365,7 +362,7 @@ String TextServerAdvanced::get_name() const {
#endif
}
-int64_t TextServerAdvanced::get_features() const {
+int64_t TextServerAdvanced::_get_features() const {
int64_t interface_features = FEATURE_SIMPLE_LAYOUT | FEATURE_BIDI_LAYOUT | FEATURE_VERTICAL_LAYOUT | FEATURE_SHAPING | FEATURE_KASHIDA_JUSTIFICATION | FEATURE_BREAK_ITERATORS | FEATURE_FONT_BITMAP | FEATURE_FONT_VARIABLE | FEATURE_CONTEXT_SENSITIVE_CASE_CONVERSION | FEATURE_USE_SUPPORT_DATA;
#ifdef MODULE_FREETYPE_ENABLED
interface_features |= FEATURE_FONT_DYNAMIC;
@@ -377,7 +374,7 @@ int64_t TextServerAdvanced::get_features() const {
return interface_features;
}
-void TextServerAdvanced::free_rid(const RID &p_rid) {
+void TextServerAdvanced::_free_rid(const RID &p_rid) {
_THREAD_SAFE_METHOD_
if (font_owner.owns(p_rid)) {
FontAdvanced *fd = font_owner.get_or_null(p_rid);
@@ -390,12 +387,12 @@ void TextServerAdvanced::free_rid(const RID &p_rid) {
}
}
-bool TextServerAdvanced::has(const RID &p_rid) {
+bool TextServerAdvanced::_has(const RID &p_rid) {
_THREAD_SAFE_METHOD_
return font_owner.owns(p_rid) || shaped_owner.owns(p_rid);
}
-bool TextServerAdvanced::load_support_data(const String &p_filename) {
+bool TextServerAdvanced::_load_support_data(const String &p_filename) {
_THREAD_SAFE_METHOD_
#ifdef ICU_STATIC_DATA
@@ -408,13 +405,16 @@ bool TextServerAdvanced::load_support_data(const String &p_filename) {
if (!icu_data_loaded) {
String filename = (p_filename.is_empty()) ? String("res://") + _MKSTR(ICU_DATA_NAME) : p_filename;
- Ref<File> f;
- f.instantiate();
- if (f->open(filename, File::READ) != OK) {
+ Ref<FileAccess> f = FileAccess::open(filename, FileAccess::READ);
+ if (f.is_null()) {
return false;
}
uint64_t len = f->get_length();
+#ifdef GDEXTENSION
PackedByteArray icu_data = f->get_buffer(len);
+#else
+ PackedByteArray icu_data = f->_get_buffer(len);
+#endif
UErrorCode err = U_ZERO_ERROR;
udata_setCommonData(icu_data.ptr(), &err);
@@ -433,7 +433,7 @@ bool TextServerAdvanced::load_support_data(const String &p_filename) {
return true;
}
-String TextServerAdvanced::get_support_data_filename() const {
+String TextServerAdvanced::_get_support_data_filename() const {
#ifdef ICU_STATIC_DATA
return _MKSTR(ICU_DATA_NAME);
#else
@@ -441,7 +441,7 @@ String TextServerAdvanced::get_support_data_filename() const {
#endif
}
-String TextServerAdvanced::get_support_data_info() const {
+String TextServerAdvanced::_get_support_data_info() const {
#ifdef ICU_STATIC_DATA
return String("ICU break iteration data (") + _MKSTR(ICU_DATA_NAME) + String(").");
#else
@@ -449,22 +449,25 @@ String TextServerAdvanced::get_support_data_info() const {
#endif
}
-bool TextServerAdvanced::save_support_data(const String &p_filename) const {
+bool TextServerAdvanced::_save_support_data(const String &p_filename) const {
_THREAD_SAFE_METHOD_
#ifdef ICU_STATIC_DATA
// Store data to the res file if it's available.
- Ref<File> f;
- f.instantiate();
- if (f->open(p_filename, File::WRITE) != OK) {
+ Ref<FileAccess> f = FileAccess::open(p_filename, FileAccess::WRITE);
+ if (f.is_null()) {
return false;
}
PackedByteArray icu_data;
icu_data.resize(U_ICUDATA_SIZE);
memcpy(icu_data.ptrw(), U_ICUDATA_ENTRY_POINT, U_ICUDATA_SIZE);
+#ifdef GDEXTENSION
f->store_buffer(icu_data);
+#else
+ f->_store_buffer(icu_data);
+#endif
return true;
#else
@@ -472,7 +475,7 @@ bool TextServerAdvanced::save_support_data(const String &p_filename) const {
#endif
}
-bool TextServerAdvanced::is_locale_right_to_left(const String &p_locale) const {
+bool TextServerAdvanced::_is_locale_right_to_left(const String &p_locale) const {
String l = p_locale.get_slicec('_', 0);
if ((l == "ar") || (l == "dv") || (l == "he") || (l == "fa") || (l == "ff") || (l == "ku") || (l == "ur")) {
return true;
@@ -744,7 +747,7 @@ void TextServerAdvanced::_insert_feature_sets() {
_insert_feature("weight", HB_TAG('w', 'g', 'h', 't'), Variant::Type::INT, false);
}
-int64_t TextServerAdvanced::name_to_tag(const String &p_name) const {
+int64_t TextServerAdvanced::_name_to_tag(const String &p_name) const {
if (feature_sets.has(p_name)) {
return feature_sets[p_name];
}
@@ -767,7 +770,7 @@ bool TextServerAdvanced::_get_tag_hidden(int64_t p_tag) const {
return false;
}
-String TextServerAdvanced::tag_to_name(int64_t p_tag) const {
+String TextServerAdvanced::_tag_to_name(int64_t p_tag) const {
if (feature_sets_inv.has(p_tag)) {
return feature_sets_inv[p_tag].name;
}
@@ -1048,8 +1051,14 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf(
td.projection = &projection;
td.distancePixelConversion = &distancePixelConversion;
+#ifdef GDEXTENSION
+ for (int i = 0; i < h; i++) {
+ _generateMTSDF_threaded(i, &td);
+ }
+#else
WorkerThreadPool::GroupID group_task = WorkerThreadPool::get_singleton()->add_template_group_task(this, &TextServerAdvanced::_generateMTSDF_threaded, &td, h, -1, true, SNAME("FontServerRasterizeMSDF"));
WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_task);
+#endif
msdfgen::msdfErrorCorrection(image, shape, projection, p_pixel_range, config);
@@ -1420,7 +1429,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f
fd->oversampling = 1.0;
fd->size.x = p_font_data->msdf_source_size;
} else if (p_font_data->oversampling <= 0.0) {
- fd->oversampling = font_get_global_oversampling();
+ fd->oversampling = _font_get_global_oversampling();
} else {
fd->oversampling = p_font_data->oversampling;
}
@@ -1813,8 +1822,8 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f
coords.write[i] = CLAMP(var.value * 65536.0, amaster->axis[i].minimum, amaster->axis[i].maximum);
}
- if (p_font_data->variation_coordinates.has(tag_to_name(var.tag))) {
- var.value = p_font_data->variation_coordinates[tag_to_name(var.tag)];
+ if (p_font_data->variation_coordinates.has(_tag_to_name(var.tag))) {
+ var.value = p_font_data->variation_coordinates[_tag_to_name(var.tag)];
coords.write[i] = CLAMP(var.value * 65536.0, amaster->axis[i].minimum, amaster->axis[i].maximum);
}
@@ -1859,7 +1868,7 @@ hb_font_t *TextServerAdvanced::_font_get_hb_handle(const RID &p_font_rid, int64_
return fd->cache[size]->hb_handle;
}
-RID TextServerAdvanced::create_font() {
+RID TextServerAdvanced::_create_font() {
_THREAD_SAFE_METHOD_
FontAdvanced *fd = memnew(FontAdvanced);
@@ -1867,7 +1876,7 @@ RID TextServerAdvanced::create_font() {
return font_owner.make_rid(fd);
}
-void TextServerAdvanced::font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) {
+void TextServerAdvanced::_font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1878,7 +1887,7 @@ void TextServerAdvanced::font_set_data(const RID &p_font_rid, const PackedByteAr
fd->data_size = fd->data.size();
}
-void TextServerAdvanced::font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) {
+void TextServerAdvanced::_font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1889,7 +1898,7 @@ void TextServerAdvanced::font_set_data_ptr(const RID &p_font_rid, const uint8_t
fd->data_size = p_data_size;
}
-void TextServerAdvanced::font_set_face_index(const RID &p_font_rid, int64_t p_face_index) {
+void TextServerAdvanced::_font_set_face_index(const RID &p_font_rid, int64_t p_face_index) {
ERR_FAIL_COND(p_face_index < 0);
ERR_FAIL_COND(p_face_index >= 0x7FFF);
@@ -1903,7 +1912,7 @@ void TextServerAdvanced::font_set_face_index(const RID &p_font_rid, int64_t p_fa
}
}
-int64_t TextServerAdvanced::font_get_face_index(const RID &p_font_rid) const {
+int64_t TextServerAdvanced::_font_get_face_index(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
@@ -1911,7 +1920,7 @@ int64_t TextServerAdvanced::font_get_face_index(const RID &p_font_rid) const {
return fd->face_index;
}
-int64_t TextServerAdvanced::font_get_face_count(const RID &p_font_rid) const {
+int64_t TextServerAdvanced::_font_get_face_count(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
@@ -1940,19 +1949,19 @@ int64_t TextServerAdvanced::font_get_face_count(const RID &p_font_rid) const {
fargs.flags = FT_OPEN_MEMORY;
fargs.stream = &stream;
- FT_Face tmp_face;
+ FT_Face tmp_face = nullptr;
error = FT_Open_Face(ft_library, &fargs, -1, &tmp_face);
if (error == 0) {
face_count = tmp_face->num_faces;
+ FT_Done_Face(tmp_face);
}
- FT_Done_Face(tmp_face);
#endif
}
return face_count;
}
-void TextServerAdvanced::font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) {
+void TextServerAdvanced::_font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1962,7 +1971,7 @@ void TextServerAdvanced::font_set_style(const RID &p_font_rid, BitField<FontStyl
fd->style_flags = p_style;
}
-BitField<TextServer::FontStyle> TextServerAdvanced::font_get_style(const RID &p_font_rid) const {
+BitField<TextServer::FontStyle> TextServerAdvanced::_font_get_style(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
@@ -1972,7 +1981,7 @@ BitField<TextServer::FontStyle> TextServerAdvanced::font_get_style(const RID &p_
return fd->style_flags;
}
-void TextServerAdvanced::font_set_style_name(const RID &p_font_rid, const String &p_name) {
+void TextServerAdvanced::_font_set_style_name(const RID &p_font_rid, const String &p_name) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1982,7 +1991,7 @@ void TextServerAdvanced::font_set_style_name(const RID &p_font_rid, const String
fd->style_name = p_name;
}
-String TextServerAdvanced::font_get_style_name(const RID &p_font_rid) const {
+String TextServerAdvanced::_font_get_style_name(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
@@ -1992,7 +2001,7 @@ String TextServerAdvanced::font_get_style_name(const RID &p_font_rid) const {
return fd->style_name;
}
-void TextServerAdvanced::font_set_name(const RID &p_font_rid, const String &p_name) {
+void TextServerAdvanced::_font_set_name(const RID &p_font_rid, const String &p_name) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2002,7 +2011,7 @@ void TextServerAdvanced::font_set_name(const RID &p_font_rid, const String &p_na
fd->font_name = p_name;
}
-String TextServerAdvanced::font_get_name(const RID &p_font_rid) const {
+String TextServerAdvanced::_font_get_name(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
@@ -2012,7 +2021,7 @@ String TextServerAdvanced::font_get_name(const RID &p_font_rid) const {
return fd->font_name;
}
-void TextServerAdvanced::font_set_antialiasing(RID p_font_rid, TextServer::FontAntialiasing p_antialiasing) {
+void TextServerAdvanced::_font_set_antialiasing(const RID &p_font_rid, TextServer::FontAntialiasing p_antialiasing) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2023,7 +2032,7 @@ void TextServerAdvanced::font_set_antialiasing(RID p_font_rid, TextServer::FontA
}
}
-TextServer::FontAntialiasing TextServerAdvanced::font_get_antialiasing(RID p_font_rid) const {
+TextServer::FontAntialiasing TextServerAdvanced::_font_get_antialiasing(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, TextServer::FONT_ANTIALIASING_NONE);
@@ -2031,7 +2040,7 @@ TextServer::FontAntialiasing TextServerAdvanced::font_get_antialiasing(RID p_fon
return fd->antialiasing;
}
-void TextServerAdvanced::font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) {
+void TextServerAdvanced::_font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2040,13 +2049,14 @@ void TextServerAdvanced::font_set_generate_mipmaps(const RID &p_font_rid, bool p
for (KeyValue<Vector2i, FontForSizeAdvanced *> &E : fd->cache) {
for (int i = 0; i < E.value->textures.size(); i++) {
E.value->textures.write[i].dirty = true;
+ E.value->textures.write[i].texture = Ref<ImageTexture>();
}
}
fd->mipmaps = p_generate_mipmaps;
}
}
-bool TextServerAdvanced::font_get_generate_mipmaps(const RID &p_font_rid) const {
+bool TextServerAdvanced::_font_get_generate_mipmaps(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2054,7 +2064,7 @@ bool TextServerAdvanced::font_get_generate_mipmaps(const RID &p_font_rid) const
return fd->mipmaps;
}
-void TextServerAdvanced::font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) {
+void TextServerAdvanced::_font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2065,7 +2075,7 @@ void TextServerAdvanced::font_set_multichannel_signed_distance_field(const RID &
}
}
-bool TextServerAdvanced::font_is_multichannel_signed_distance_field(const RID &p_font_rid) const {
+bool TextServerAdvanced::_font_is_multichannel_signed_distance_field(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2073,7 +2083,7 @@ bool TextServerAdvanced::font_is_multichannel_signed_distance_field(const RID &p
return fd->msdf;
}
-void TextServerAdvanced::font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) {
+void TextServerAdvanced::_font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2084,7 +2094,7 @@ void TextServerAdvanced::font_set_msdf_pixel_range(const RID &p_font_rid, int64_
}
}
-int64_t TextServerAdvanced::font_get_msdf_pixel_range(const RID &p_font_rid) const {
+int64_t TextServerAdvanced::_font_get_msdf_pixel_range(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2092,7 +2102,7 @@ int64_t TextServerAdvanced::font_get_msdf_pixel_range(const RID &p_font_rid) con
return fd->msdf_range;
}
-void TextServerAdvanced::font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) {
+void TextServerAdvanced::_font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2103,7 +2113,7 @@ void TextServerAdvanced::font_set_msdf_size(const RID &p_font_rid, int64_t p_msd
}
}
-int64_t TextServerAdvanced::font_get_msdf_size(const RID &p_font_rid) const {
+int64_t TextServerAdvanced::_font_get_msdf_size(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2111,7 +2121,7 @@ int64_t TextServerAdvanced::font_get_msdf_size(const RID &p_font_rid) const {
return fd->msdf_source_size;
}
-void TextServerAdvanced::font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) {
+void TextServerAdvanced::_font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2119,7 +2129,7 @@ void TextServerAdvanced::font_set_fixed_size(const RID &p_font_rid, int64_t p_fi
fd->fixed_size = p_fixed_size;
}
-int64_t TextServerAdvanced::font_get_fixed_size(const RID &p_font_rid) const {
+int64_t TextServerAdvanced::_font_get_fixed_size(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2127,7 +2137,7 @@ int64_t TextServerAdvanced::font_get_fixed_size(const RID &p_font_rid) const {
return fd->fixed_size;
}
-void TextServerAdvanced::font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) {
+void TextServerAdvanced::_font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2138,7 +2148,7 @@ void TextServerAdvanced::font_set_force_autohinter(const RID &p_font_rid, bool p
}
}
-bool TextServerAdvanced::font_is_force_autohinter(const RID &p_font_rid) const {
+bool TextServerAdvanced::_font_is_force_autohinter(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2146,7 +2156,7 @@ bool TextServerAdvanced::font_is_force_autohinter(const RID &p_font_rid) const {
return fd->force_autohinter;
}
-void TextServerAdvanced::font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) {
+void TextServerAdvanced::_font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2157,7 +2167,7 @@ void TextServerAdvanced::font_set_hinting(const RID &p_font_rid, TextServer::Hin
}
}
-TextServer::Hinting TextServerAdvanced::font_get_hinting(const RID &p_font_rid) const {
+TextServer::Hinting TextServerAdvanced::_font_get_hinting(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, HINTING_NONE);
@@ -2165,7 +2175,7 @@ TextServer::Hinting TextServerAdvanced::font_get_hinting(const RID &p_font_rid)
return fd->hinting;
}
-void TextServerAdvanced::font_set_subpixel_positioning(const RID &p_font_rid, TextServer::SubpixelPositioning p_subpixel) {
+void TextServerAdvanced::_font_set_subpixel_positioning(const RID &p_font_rid, TextServer::SubpixelPositioning p_subpixel) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2173,7 +2183,7 @@ void TextServerAdvanced::font_set_subpixel_positioning(const RID &p_font_rid, Te
fd->subpixel_positioning = p_subpixel;
}
-TextServer::SubpixelPositioning TextServerAdvanced::font_get_subpixel_positioning(const RID &p_font_rid) const {
+TextServer::SubpixelPositioning TextServerAdvanced::_font_get_subpixel_positioning(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, SUBPIXEL_POSITIONING_DISABLED);
@@ -2181,7 +2191,7 @@ TextServer::SubpixelPositioning TextServerAdvanced::font_get_subpixel_positionin
return fd->subpixel_positioning;
}
-void TextServerAdvanced::font_set_embolden(const RID &p_font_rid, double p_strength) {
+void TextServerAdvanced::_font_set_embolden(const RID &p_font_rid, double p_strength) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2192,7 +2202,7 @@ void TextServerAdvanced::font_set_embolden(const RID &p_font_rid, double p_stren
}
}
-double TextServerAdvanced::font_get_embolden(const RID &p_font_rid) const {
+double TextServerAdvanced::_font_get_embolden(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -2200,7 +2210,7 @@ double TextServerAdvanced::font_get_embolden(const RID &p_font_rid) const {
return fd->embolden;
}
-void TextServerAdvanced::font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) {
+void TextServerAdvanced::_font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2211,7 +2221,7 @@ void TextServerAdvanced::font_set_transform(const RID &p_font_rid, const Transfo
}
}
-Transform2D TextServerAdvanced::font_get_transform(const RID &p_font_rid) const {
+Transform2D TextServerAdvanced::_font_get_transform(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Transform2D());
@@ -2219,7 +2229,7 @@ Transform2D TextServerAdvanced::font_get_transform(const RID &p_font_rid) const
return fd->transform;
}
-void TextServerAdvanced::font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) {
+void TextServerAdvanced::_font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2230,7 +2240,7 @@ void TextServerAdvanced::font_set_variation_coordinates(const RID &p_font_rid, c
}
}
-Dictionary TextServerAdvanced::font_get_variation_coordinates(const RID &p_font_rid) const {
+Dictionary TextServerAdvanced::_font_get_variation_coordinates(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -2238,7 +2248,7 @@ Dictionary TextServerAdvanced::font_get_variation_coordinates(const RID &p_font_
return fd->variation_coordinates;
}
-void TextServerAdvanced::font_set_oversampling(const RID &p_font_rid, double p_oversampling) {
+void TextServerAdvanced::_font_set_oversampling(const RID &p_font_rid, double p_oversampling) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2249,7 +2259,7 @@ void TextServerAdvanced::font_set_oversampling(const RID &p_font_rid, double p_o
}
}
-double TextServerAdvanced::font_get_oversampling(const RID &p_font_rid) const {
+double TextServerAdvanced::_font_get_oversampling(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -2257,7 +2267,7 @@ double TextServerAdvanced::font_get_oversampling(const RID &p_font_rid) const {
return fd->oversampling;
}
-TypedArray<Vector2i> TextServerAdvanced::font_get_size_cache_list(const RID &p_font_rid) const {
+TypedArray<Vector2i> TextServerAdvanced::_font_get_size_cache_list(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, TypedArray<Vector2i>());
@@ -2269,7 +2279,7 @@ TypedArray<Vector2i> TextServerAdvanced::font_get_size_cache_list(const RID &p_f
return ret;
}
-void TextServerAdvanced::font_clear_size_cache(const RID &p_font_rid) {
+void TextServerAdvanced::_font_clear_size_cache(const RID &p_font_rid) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2280,7 +2290,7 @@ void TextServerAdvanced::font_clear_size_cache(const RID &p_font_rid) {
fd->cache.clear();
}
-void TextServerAdvanced::font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) {
+void TextServerAdvanced::_font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2291,7 +2301,7 @@ void TextServerAdvanced::font_remove_size_cache(const RID &p_font_rid, const Vec
}
}
-void TextServerAdvanced::font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) {
+void TextServerAdvanced::_font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2302,7 +2312,7 @@ void TextServerAdvanced::font_set_ascent(const RID &p_font_rid, int64_t p_size,
fd->cache[size]->ascent = p_ascent;
}
-double TextServerAdvanced::font_get_ascent(const RID &p_font_rid, int64_t p_size) const {
+double TextServerAdvanced::_font_get_ascent(const RID &p_font_rid, int64_t p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -2318,7 +2328,7 @@ double TextServerAdvanced::font_get_ascent(const RID &p_font_rid, int64_t p_size
}
}
-void TextServerAdvanced::font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) {
+void TextServerAdvanced::_font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2328,7 +2338,7 @@ void TextServerAdvanced::font_set_descent(const RID &p_font_rid, int64_t p_size,
fd->cache[size]->descent = p_descent;
}
-double TextServerAdvanced::font_get_descent(const RID &p_font_rid, int64_t p_size) const {
+double TextServerAdvanced::_font_get_descent(const RID &p_font_rid, int64_t p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -2344,7 +2354,7 @@ double TextServerAdvanced::font_get_descent(const RID &p_font_rid, int64_t p_siz
}
}
-void TextServerAdvanced::font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) {
+void TextServerAdvanced::_font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2355,7 +2365,7 @@ void TextServerAdvanced::font_set_underline_position(const RID &p_font_rid, int6
fd->cache[size]->underline_position = p_underline_position;
}
-double TextServerAdvanced::font_get_underline_position(const RID &p_font_rid, int64_t p_size) const {
+double TextServerAdvanced::_font_get_underline_position(const RID &p_font_rid, int64_t p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -2371,7 +2381,7 @@ double TextServerAdvanced::font_get_underline_position(const RID &p_font_rid, in
}
}
-void TextServerAdvanced::font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) {
+void TextServerAdvanced::_font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2382,7 +2392,7 @@ void TextServerAdvanced::font_set_underline_thickness(const RID &p_font_rid, int
fd->cache[size]->underline_thickness = p_underline_thickness;
}
-double TextServerAdvanced::font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const {
+double TextServerAdvanced::_font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -2398,7 +2408,7 @@ double TextServerAdvanced::font_get_underline_thickness(const RID &p_font_rid, i
}
}
-void TextServerAdvanced::font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) {
+void TextServerAdvanced::_font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2414,7 +2424,7 @@ void TextServerAdvanced::font_set_scale(const RID &p_font_rid, int64_t p_size, d
fd->cache[size]->scale = p_scale;
}
-double TextServerAdvanced::font_get_scale(const RID &p_font_rid, int64_t p_size) const {
+double TextServerAdvanced::_font_get_scale(const RID &p_font_rid, int64_t p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -2430,7 +2440,7 @@ double TextServerAdvanced::font_get_scale(const RID &p_font_rid, int64_t p_size)
}
}
-int64_t TextServerAdvanced::font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const {
+int64_t TextServerAdvanced::_font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
@@ -2442,7 +2452,7 @@ int64_t TextServerAdvanced::font_get_texture_count(const RID &p_font_rid, const
return fd->cache[size]->textures.size();
}
-void TextServerAdvanced::font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) {
+void TextServerAdvanced::_font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -2452,7 +2462,7 @@ void TextServerAdvanced::font_clear_textures(const RID &p_font_rid, const Vector
fd->cache[size]->textures.clear();
}
-void TextServerAdvanced::font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) {
+void TextServerAdvanced::_font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2464,7 +2474,7 @@ void TextServerAdvanced::font_remove_texture(const RID &p_font_rid, const Vector
fd->cache[size]->textures.remove_at(p_texture_index);
}
-void TextServerAdvanced::font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) {
+void TextServerAdvanced::_font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
ERR_FAIL_COND(p_image.is_null());
@@ -2495,7 +2505,7 @@ void TextServerAdvanced::font_set_texture_image(const RID &p_font_rid, const Vec
tex.dirty = false;
}
-Ref<Image> TextServerAdvanced::font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
+Ref<Image> TextServerAdvanced::_font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Ref<Image>());
@@ -2512,7 +2522,7 @@ Ref<Image> TextServerAdvanced::font_get_texture_image(const RID &p_font_rid, con
return img;
}
-void TextServerAdvanced::font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) {
+void TextServerAdvanced::_font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2528,7 +2538,7 @@ void TextServerAdvanced::font_set_texture_offsets(const RID &p_font_rid, const V
tex.offsets = p_offset;
}
-PackedInt32Array TextServerAdvanced::font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
+PackedInt32Array TextServerAdvanced::_font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedInt32Array());
@@ -2541,7 +2551,7 @@ PackedInt32Array TextServerAdvanced::font_get_texture_offsets(const RID &p_font_
return tex.offsets;
}
-PackedInt32Array TextServerAdvanced::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const {
+PackedInt32Array TextServerAdvanced::_font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedInt32Array());
@@ -2557,7 +2567,7 @@ PackedInt32Array TextServerAdvanced::font_get_glyph_list(const RID &p_font_rid,
return ret;
}
-void TextServerAdvanced::font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) {
+void TextServerAdvanced::_font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2568,7 +2578,7 @@ void TextServerAdvanced::font_clear_glyphs(const RID &p_font_rid, const Vector2i
fd->cache[size]->glyph_map.clear();
}
-void TextServerAdvanced::font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) {
+void TextServerAdvanced::_font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2593,7 +2603,7 @@ double TextServerAdvanced::_get_extra_advance(RID p_font_rid, int p_font_size) c
}
}
-Vector2 TextServerAdvanced::font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const {
+Vector2 TextServerAdvanced::_font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
@@ -2604,7 +2614,7 @@ Vector2 TextServerAdvanced::font_get_glyph_advance(const RID &p_font_rid, int64_
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -2630,7 +2640,7 @@ Vector2 TextServerAdvanced::font_get_glyph_advance(const RID &p_font_rid, int64_
}
}
-void TextServerAdvanced::font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) {
+void TextServerAdvanced::_font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2645,7 +2655,7 @@ void TextServerAdvanced::font_set_glyph_advance(const RID &p_font_rid, int64_t p
gl[p_glyph].found = true;
}
-Vector2 TextServerAdvanced::font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+Vector2 TextServerAdvanced::_font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
@@ -2656,7 +2666,7 @@ Vector2 TextServerAdvanced::font_get_glyph_offset(const RID &p_font_rid, const V
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -2675,7 +2685,7 @@ Vector2 TextServerAdvanced::font_get_glyph_offset(const RID &p_font_rid, const V
}
}
-void TextServerAdvanced::font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) {
+void TextServerAdvanced::_font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2690,7 +2700,7 @@ void TextServerAdvanced::font_set_glyph_offset(const RID &p_font_rid, const Vect
gl[p_glyph].found = true;
}
-Vector2 TextServerAdvanced::font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+Vector2 TextServerAdvanced::_font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
@@ -2701,7 +2711,7 @@ Vector2 TextServerAdvanced::font_get_glyph_size(const RID &p_font_rid, const Vec
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -2720,7 +2730,7 @@ Vector2 TextServerAdvanced::font_get_glyph_size(const RID &p_font_rid, const Vec
}
}
-void TextServerAdvanced::font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) {
+void TextServerAdvanced::_font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2735,7 +2745,7 @@ void TextServerAdvanced::font_set_glyph_size(const RID &p_font_rid, const Vector
gl[p_glyph].found = true;
}
-Rect2 TextServerAdvanced::font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+Rect2 TextServerAdvanced::_font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Rect2());
@@ -2746,7 +2756,7 @@ Rect2 TextServerAdvanced::font_get_glyph_uv_rect(const RID &p_font_rid, const Ve
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -2760,7 +2770,7 @@ Rect2 TextServerAdvanced::font_get_glyph_uv_rect(const RID &p_font_rid, const Ve
return gl[p_glyph | mod].uv_rect;
}
-void TextServerAdvanced::font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) {
+void TextServerAdvanced::_font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2775,7 +2785,7 @@ void TextServerAdvanced::font_set_glyph_uv_rect(const RID &p_font_rid, const Vec
gl[p_glyph].found = true;
}
-int64_t TextServerAdvanced::font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+int64_t TextServerAdvanced::_font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, -1);
@@ -2786,7 +2796,7 @@ int64_t TextServerAdvanced::font_get_glyph_texture_idx(const RID &p_font_rid, co
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -2800,7 +2810,7 @@ int64_t TextServerAdvanced::font_get_glyph_texture_idx(const RID &p_font_rid, co
return gl[p_glyph | mod].texture_idx;
}
-void TextServerAdvanced::font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) {
+void TextServerAdvanced::_font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2815,7 +2825,7 @@ void TextServerAdvanced::font_set_glyph_texture_idx(const RID &p_font_rid, const
gl[p_glyph].found = true;
}
-RID TextServerAdvanced::font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+RID TextServerAdvanced::_font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, RID());
@@ -2826,7 +2836,7 @@ RID TextServerAdvanced::font_get_glyph_texture_rid(const RID &p_font_rid, const
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -2863,7 +2873,7 @@ RID TextServerAdvanced::font_get_glyph_texture_rid(const RID &p_font_rid, const
return RID();
}
-Size2 TextServerAdvanced::font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+Size2 TextServerAdvanced::_font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Size2());
@@ -2874,7 +2884,7 @@ Size2 TextServerAdvanced::font_get_glyph_texture_size(const RID &p_font_rid, con
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -2911,7 +2921,7 @@ Size2 TextServerAdvanced::font_get_glyph_texture_size(const RID &p_font_rid, con
return Size2();
}
-Dictionary TextServerAdvanced::font_get_glyph_contours(const RID &p_font_rid, int64_t p_size, int64_t p_index) const {
+Dictionary TextServerAdvanced::_font_get_glyph_contours(const RID &p_font_rid, int64_t p_size, int64_t p_index) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -2961,7 +2971,7 @@ Dictionary TextServerAdvanced::font_get_glyph_contours(const RID &p_font_rid, in
#endif
}
-TypedArray<Vector2i> TextServerAdvanced::font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const {
+TypedArray<Vector2i> TextServerAdvanced::_font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, TypedArray<Vector2i>());
@@ -2977,7 +2987,7 @@ TypedArray<Vector2i> TextServerAdvanced::font_get_kerning_list(const RID &p_font
return ret;
}
-void TextServerAdvanced::font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) {
+void TextServerAdvanced::_font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2988,7 +2998,7 @@ void TextServerAdvanced::font_clear_kerning_map(const RID &p_font_rid, int64_t p
fd->cache[size]->kerning_map.clear();
}
-void TextServerAdvanced::font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) {
+void TextServerAdvanced::_font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2999,7 +3009,7 @@ void TextServerAdvanced::font_remove_kerning(const RID &p_font_rid, int64_t p_si
fd->cache[size]->kerning_map.erase(p_glyph_pair);
}
-void TextServerAdvanced::font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) {
+void TextServerAdvanced::_font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3010,7 +3020,7 @@ void TextServerAdvanced::font_set_kerning(const RID &p_font_rid, int64_t p_size,
fd->cache[size]->kerning_map[p_glyph_pair] = p_kerning;
}
-Vector2 TextServerAdvanced::font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const {
+Vector2 TextServerAdvanced::_font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
@@ -3043,7 +3053,7 @@ Vector2 TextServerAdvanced::font_get_kerning(const RID &p_font_rid, int64_t p_si
return Vector2();
}
-int64_t TextServerAdvanced::font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector) const {
+int64_t TextServerAdvanced::_font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
ERR_FAIL_COND_V_MSG((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff), 0, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_char, 16) + ".");
@@ -3068,10 +3078,12 @@ int64_t TextServerAdvanced::font_get_glyph_index(const RID &p_font_rid, int64_t
#endif
}
-bool TextServerAdvanced::font_has_char(const RID &p_font_rid, int64_t p_char) const {
+bool TextServerAdvanced::_font_has_char(const RID &p_font_rid, int64_t p_char) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
- ERR_FAIL_COND_V(!fd, false);
ERR_FAIL_COND_V_MSG((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff), false, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_char, 16) + ".");
+ if (!fd) {
+ return false;
+ }
MutexLock lock(fd->mutex);
if (fd->cache.is_empty()) {
@@ -3087,7 +3099,7 @@ bool TextServerAdvanced::font_has_char(const RID &p_font_rid, int64_t p_char) co
return (at_size) ? at_size->glyph_map.has((int32_t)p_char) : false;
}
-String TextServerAdvanced::font_get_supported_chars(const RID &p_font_rid) const {
+String TextServerAdvanced::_font_get_supported_chars(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
@@ -3120,7 +3132,7 @@ String TextServerAdvanced::font_get_supported_chars(const RID &p_font_rid) const
return chars;
}
-void TextServerAdvanced::font_render_range(const RID &p_font_rid, const Vector2i &p_size, int64_t p_start, int64_t p_end) {
+void TextServerAdvanced::_font_render_range(const RID &p_font_rid, const Vector2i &p_size, int64_t p_start, int64_t p_end) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
ERR_FAIL_COND_MSG((p_start >= 0xd800 && p_start <= 0xdfff) || (p_start > 0x10ffff), "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_start, 16) + ".");
@@ -3155,7 +3167,7 @@ void TextServerAdvanced::font_render_range(const RID &p_font_rid, const Vector2i
}
}
-void TextServerAdvanced::font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) {
+void TextServerAdvanced::_font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3186,7 +3198,7 @@ void TextServerAdvanced::font_render_glyph(const RID &p_font_rid, const Vector2i
#endif
}
-void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
+void TextServerAdvanced::_font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3201,7 +3213,7 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can
if (!fd->msdf && fd->cache[size]->face) {
// LCD layout, bits 24, 25, 26
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
lcd_aa = true;
index = index | (layout << 24);
@@ -3278,7 +3290,7 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can
}
}
-void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, 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) const {
+void TextServerAdvanced::_font_draw_glyph_outline(const RID &p_font_rid, 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) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3293,7 +3305,7 @@ void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RI
if (!fd->msdf && fd->cache[size]->face) {
// LCD layout, bits 24, 25, 26
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
lcd_aa = true;
index = index | (layout << 24);
@@ -3370,7 +3382,7 @@ void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RI
}
}
-bool TextServerAdvanced::font_is_language_supported(const RID &p_font_rid, const String &p_language) const {
+bool TextServerAdvanced::_font_is_language_supported(const RID &p_font_rid, const String &p_language) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -3382,7 +3394,7 @@ bool TextServerAdvanced::font_is_language_supported(const RID &p_font_rid, const
}
}
-void TextServerAdvanced::font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) {
+void TextServerAdvanced::_font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3390,7 +3402,7 @@ void TextServerAdvanced::font_set_language_support_override(const RID &p_font_ri
fd->language_support_overrides[p_language] = p_supported;
}
-bool TextServerAdvanced::font_get_language_support_override(const RID &p_font_rid, const String &p_language) {
+bool TextServerAdvanced::_font_get_language_support_override(const RID &p_font_rid, const String &p_language) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -3398,7 +3410,7 @@ bool TextServerAdvanced::font_get_language_support_override(const RID &p_font_ri
return fd->language_support_overrides[p_language];
}
-void TextServerAdvanced::font_remove_language_support_override(const RID &p_font_rid, const String &p_language) {
+void TextServerAdvanced::_font_remove_language_support_override(const RID &p_font_rid, const String &p_language) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3406,7 +3418,7 @@ void TextServerAdvanced::font_remove_language_support_override(const RID &p_font
fd->language_support_overrides.erase(p_language);
}
-PackedStringArray TextServerAdvanced::font_get_language_support_overrides(const RID &p_font_rid) {
+PackedStringArray TextServerAdvanced::_font_get_language_support_overrides(const RID &p_font_rid) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedStringArray());
@@ -3418,7 +3430,7 @@ PackedStringArray TextServerAdvanced::font_get_language_support_overrides(const
return out;
}
-bool TextServerAdvanced::font_is_script_supported(const RID &p_font_rid, const String &p_script) const {
+bool TextServerAdvanced::_font_is_script_supported(const RID &p_font_rid, const String &p_script) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -3432,7 +3444,7 @@ bool TextServerAdvanced::font_is_script_supported(const RID &p_font_rid, const S
}
}
-void TextServerAdvanced::font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) {
+void TextServerAdvanced::_font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3440,7 +3452,7 @@ void TextServerAdvanced::font_set_script_support_override(const RID &p_font_rid,
fd->script_support_overrides[p_script] = p_supported;
}
-bool TextServerAdvanced::font_get_script_support_override(const RID &p_font_rid, const String &p_script) {
+bool TextServerAdvanced::_font_get_script_support_override(const RID &p_font_rid, const String &p_script) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -3448,7 +3460,7 @@ bool TextServerAdvanced::font_get_script_support_override(const RID &p_font_rid,
return fd->script_support_overrides[p_script];
}
-void TextServerAdvanced::font_remove_script_support_override(const RID &p_font_rid, const String &p_script) {
+void TextServerAdvanced::_font_remove_script_support_override(const RID &p_font_rid, const String &p_script) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3456,7 +3468,7 @@ void TextServerAdvanced::font_remove_script_support_override(const RID &p_font_r
fd->script_support_overrides.erase(p_script);
}
-PackedStringArray TextServerAdvanced::font_get_script_support_overrides(const RID &p_font_rid) {
+PackedStringArray TextServerAdvanced::_font_get_script_support_overrides(const RID &p_font_rid) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedStringArray());
@@ -3468,7 +3480,7 @@ PackedStringArray TextServerAdvanced::font_get_script_support_overrides(const RI
return out;
}
-void TextServerAdvanced::font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) {
+void TextServerAdvanced::_font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -3478,7 +3490,7 @@ void TextServerAdvanced::font_set_opentype_feature_overrides(const RID &p_font_r
fd->feature_overrides = p_overrides;
}
-Dictionary TextServerAdvanced::font_get_opentype_feature_overrides(const RID &p_font_rid) const {
+Dictionary TextServerAdvanced::_font_get_opentype_feature_overrides(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -3486,7 +3498,7 @@ Dictionary TextServerAdvanced::font_get_opentype_feature_overrides(const RID &p_
return fd->feature_overrides;
}
-Dictionary TextServerAdvanced::font_supported_feature_list(const RID &p_font_rid) const {
+Dictionary TextServerAdvanced::_font_supported_feature_list(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -3496,7 +3508,7 @@ Dictionary TextServerAdvanced::font_supported_feature_list(const RID &p_font_rid
return fd->supported_features;
}
-Dictionary TextServerAdvanced::font_supported_variation_list(const RID &p_font_rid) const {
+Dictionary TextServerAdvanced::_font_supported_variation_list(const RID &p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -3506,11 +3518,11 @@ Dictionary TextServerAdvanced::font_supported_variation_list(const RID &p_font_r
return fd->supported_varaitions;
}
-double TextServerAdvanced::font_get_global_oversampling() const {
+double TextServerAdvanced::_font_get_global_oversampling() const {
return oversampling;
}
-void TextServerAdvanced::font_set_global_oversampling(double p_oversampling) {
+void TextServerAdvanced::_font_set_global_oversampling(double p_oversampling) {
_THREAD_SAFE_METHOD_
if (oversampling != p_oversampling) {
oversampling = p_oversampling;
@@ -3518,8 +3530,8 @@ void TextServerAdvanced::font_set_global_oversampling(double p_oversampling) {
font_owner.get_owned_list(&fonts);
bool font_cleared = false;
for (const RID &E : fonts) {
- if (!font_is_multichannel_signed_distance_field(E) && font_get_oversampling(E) <= 0) {
- font_clear_size_cache(E);
+ if (!_font_is_multichannel_signed_distance_field(E) && _font_get_oversampling(E) <= 0) {
+ _font_clear_size_cache(E);
font_cleared = true;
}
}
@@ -3628,7 +3640,7 @@ void TextServerAdvanced::full_copy(ShapedTextDataAdvanced *p_shaped) {
p_shaped->parent = RID();
}
-RID TextServerAdvanced::create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
+RID TextServerAdvanced::_create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
_THREAD_SAFE_METHOD_
ShapedTextDataAdvanced *sd = memnew(ShapedTextDataAdvanced);
@@ -3638,7 +3650,7 @@ RID TextServerAdvanced::create_shaped_text(TextServer::Direction p_direction, Te
return shaped_owner.make_rid(sd);
}
-void TextServerAdvanced::shaped_text_clear(const RID &p_shaped) {
+void TextServerAdvanced::_shaped_text_clear(const RID &p_shaped) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3653,7 +3665,7 @@ void TextServerAdvanced::shaped_text_clear(const RID &p_shaped) {
invalidate(sd, true);
}
-void TextServerAdvanced::shaped_text_set_direction(const RID &p_shaped, TextServer::Direction p_direction) {
+void TextServerAdvanced::_shaped_text_set_direction(const RID &p_shaped, TextServer::Direction p_direction) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3667,7 +3679,7 @@ void TextServerAdvanced::shaped_text_set_direction(const RID &p_shaped, TextServ
}
}
-TextServer::Direction TextServerAdvanced::shaped_text_get_direction(const RID &p_shaped) const {
+TextServer::Direction TextServerAdvanced::_shaped_text_get_direction(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, TextServer::DIRECTION_LTR);
@@ -3675,7 +3687,7 @@ TextServer::Direction TextServerAdvanced::shaped_text_get_direction(const RID &p
return sd->direction;
}
-TextServer::Direction TextServerAdvanced::shaped_text_get_inferred_direction(const RID &p_shaped) const {
+TextServer::Direction TextServerAdvanced::_shaped_text_get_inferred_direction(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, TextServer::DIRECTION_LTR);
@@ -3683,7 +3695,7 @@ TextServer::Direction TextServerAdvanced::shaped_text_get_inferred_direction(con
return sd->para_direction;
}
-void TextServerAdvanced::shaped_text_set_custom_punctuation(const RID &p_shaped, const String &p_punct) {
+void TextServerAdvanced::_shaped_text_set_custom_punctuation(const RID &p_shaped, const String &p_punct) {
_THREAD_SAFE_METHOD_
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3697,14 +3709,14 @@ void TextServerAdvanced::shaped_text_set_custom_punctuation(const RID &p_shaped,
}
}
-String TextServerAdvanced::shaped_text_get_custom_punctuation(const RID &p_shaped) const {
+String TextServerAdvanced::_shaped_text_get_custom_punctuation(const RID &p_shaped) const {
_THREAD_SAFE_METHOD_
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, String());
return sd->custom_punct;
}
-void TextServerAdvanced::shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) {
+void TextServerAdvanced::_shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3721,7 +3733,7 @@ void TextServerAdvanced::shaped_text_set_bidi_override(const RID &p_shaped, cons
invalidate(sd, false);
}
-void TextServerAdvanced::shaped_text_set_orientation(const RID &p_shaped, TextServer::Orientation p_orientation) {
+void TextServerAdvanced::_shaped_text_set_orientation(const RID &p_shaped, TextServer::Orientation p_orientation) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3735,7 +3747,7 @@ void TextServerAdvanced::shaped_text_set_orientation(const RID &p_shaped, TextSe
}
}
-void TextServerAdvanced::shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) {
+void TextServerAdvanced::_shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3747,7 +3759,7 @@ void TextServerAdvanced::shaped_text_set_preserve_invalid(const RID &p_shaped, b
}
}
-bool TextServerAdvanced::shaped_text_get_preserve_invalid(const RID &p_shaped) const {
+bool TextServerAdvanced::_shaped_text_get_preserve_invalid(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -3755,7 +3767,7 @@ bool TextServerAdvanced::shaped_text_get_preserve_invalid(const RID &p_shaped) c
return sd->preserve_invalid;
}
-void TextServerAdvanced::shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) {
+void TextServerAdvanced::_shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3769,7 +3781,7 @@ void TextServerAdvanced::shaped_text_set_preserve_control(const RID &p_shaped, b
}
}
-bool TextServerAdvanced::shaped_text_get_preserve_control(const RID &p_shaped) const {
+bool TextServerAdvanced::_shaped_text_get_preserve_control(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -3777,7 +3789,7 @@ bool TextServerAdvanced::shaped_text_get_preserve_control(const RID &p_shaped) c
return sd->preserve_control;
}
-void TextServerAdvanced::shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) {
+void TextServerAdvanced::_shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) {
ERR_FAIL_INDEX((int)p_spacing, 4);
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -3792,7 +3804,7 @@ void TextServerAdvanced::shaped_text_set_spacing(const RID &p_shaped, SpacingTyp
}
}
-int64_t TextServerAdvanced::shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const {
+int64_t TextServerAdvanced::_shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const {
ERR_FAIL_INDEX_V((int)p_spacing, 4, 0);
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
@@ -3802,7 +3814,7 @@ int64_t TextServerAdvanced::shaped_text_get_spacing(const RID &p_shaped, Spacing
return sd->extra_spacing[p_spacing];
}
-TextServer::Orientation TextServerAdvanced::shaped_text_get_orientation(const RID &p_shaped) const {
+TextServer::Orientation TextServerAdvanced::_shaped_text_get_orientation(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, TextServer::ORIENTATION_HORIZONTAL);
@@ -3810,41 +3822,33 @@ TextServer::Orientation TextServerAdvanced::shaped_text_get_orientation(const RI
return sd->orientation;
}
-int64_t TextServerAdvanced::shaped_get_span_count(const RID &p_shaped) const {
+int64_t TextServerAdvanced::_shaped_get_span_count(const RID &p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0);
return sd->spans.size();
}
-Variant TextServerAdvanced::shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const {
+Variant TextServerAdvanced::_shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Variant());
ERR_FAIL_INDEX_V(p_index, sd->spans.size(), Variant());
return sd->spans[p_index].meta;
}
-void TextServerAdvanced::shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) {
+void TextServerAdvanced::_shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
ERR_FAIL_INDEX(p_index, sd->spans.size());
ShapedTextDataAdvanced::Span &span = sd->spans.ptrw()[p_index];
- bool changed = (span.font_size != p_size) || (span.features != p_opentype_features) || (p_fonts.size() != span.fonts.size());
- if (!changed) {
- for (int i = 0; i < p_fonts.size(); i++) {
- changed = changed || (span.fonts[i] != p_fonts[i]);
- }
- }
- if (changed) {
- span.fonts = p_fonts;
- span.font_size = p_size;
- span.features = p_opentype_features;
+ span.fonts = p_fonts;
+ span.font_size = p_size;
+ span.features = p_opentype_features;
- invalidate(sd, false);
- }
+ invalidate(sd, false);
}
-bool TextServerAdvanced::shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
+bool TextServerAdvanced::_shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
ERR_FAIL_COND_V(p_size <= 0, false);
@@ -3879,7 +3883,7 @@ bool TextServerAdvanced::shaped_text_add_string(const RID &p_shaped, const Strin
return true;
}
-bool TextServerAdvanced::shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, int64_t p_length) {
+bool TextServerAdvanced::_shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, int64_t p_length) {
_THREAD_SAFE_METHOD_
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -3909,7 +3913,7 @@ bool TextServerAdvanced::shaped_text_add_object(const RID &p_shaped, const Varia
return true;
}
-bool TextServerAdvanced::shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
+bool TextServerAdvanced::_shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -3950,14 +3954,14 @@ bool TextServerAdvanced::shaped_text_resize_object(const RID &p_shaped, const Va
} else {
if (gl.font_rid.is_valid()) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- sd->ascent = MAX(sd->ascent, MAX(font_get_ascent(gl.font_rid, gl.font_size), -gl.y_off));
- sd->descent = MAX(sd->descent, MAX(font_get_descent(gl.font_rid, gl.font_size), gl.y_off));
+ sd->ascent = MAX(sd->ascent, MAX(_font_get_ascent(gl.font_rid, gl.font_size), -gl.y_off));
+ sd->descent = MAX(sd->descent, MAX(_font_get_descent(gl.font_rid, gl.font_size), gl.y_off));
} else {
- sd->ascent = MAX(sd->ascent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
- sd->descent = MAX(sd->descent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
+ sd->ascent = MAX(sd->ascent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
+ sd->descent = MAX(sd->descent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
}
- sd->upos = MAX(sd->upos, font_get_underline_position(gl.font_rid, gl.font_size));
- sd->uthk = MAX(sd->uthk, font_get_underline_thickness(gl.font_rid, gl.font_size));
+ sd->upos = MAX(sd->upos, _font_get_underline_position(gl.font_rid, gl.font_size));
+ sd->uthk = MAX(sd->uthk, _font_get_underline_thickness(gl.font_rid, gl.font_size));
} else if (sd->preserve_invalid || (sd->preserve_control && is_control(gl.index))) {
// Glyph not found, replace with hex code box.
if (sd->orientation == ORIENTATION_HORIZONTAL) {
@@ -4044,7 +4048,7 @@ void TextServerAdvanced::_realign(ShapedTextDataAdvanced *p_sd) const {
p_sd->descent = full_descent;
}
-RID TextServerAdvanced::shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const {
+RID TextServerAdvanced::_shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const {
_THREAD_SAFE_METHOD_
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
@@ -4052,10 +4056,10 @@ RID TextServerAdvanced::shaped_text_substr(const RID &p_shaped, int64_t p_start,
MutexLock lock(sd->mutex);
if (sd->parent != RID()) {
- return shaped_text_substr(sd->parent, p_start, p_length);
+ return _shaped_text_substr(sd->parent, p_start, p_length);
}
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
ERR_FAIL_COND_V(p_start < 0 || p_length < 0, RID());
ERR_FAIL_COND_V(sd->start > p_start || sd->end < p_start, RID());
@@ -4159,11 +4163,11 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S
} else {
if (gl.font_rid.is_valid()) {
if (p_new_sd->orientation == ORIENTATION_HORIZONTAL) {
- p_new_sd->ascent = MAX(p_new_sd->ascent, MAX(font_get_ascent(gl.font_rid, gl.font_size), -gl.y_off));
- p_new_sd->descent = MAX(p_new_sd->descent, MAX(font_get_descent(gl.font_rid, gl.font_size), gl.y_off));
+ p_new_sd->ascent = MAX(p_new_sd->ascent, MAX(_font_get_ascent(gl.font_rid, gl.font_size), -gl.y_off));
+ p_new_sd->descent = MAX(p_new_sd->descent, MAX(_font_get_descent(gl.font_rid, gl.font_size), gl.y_off));
} else {
- p_new_sd->ascent = MAX(p_new_sd->ascent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
- p_new_sd->descent = MAX(p_new_sd->descent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
+ p_new_sd->ascent = MAX(p_new_sd->ascent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
+ p_new_sd->descent = MAX(p_new_sd->descent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
}
} else if (p_new_sd->preserve_invalid || (p_new_sd->preserve_control && is_control(gl.index))) {
// Glyph not found, replace with hex code box.
@@ -4189,7 +4193,7 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S
return true;
}
-RID TextServerAdvanced::shaped_text_get_parent(const RID &p_shaped) const {
+RID TextServerAdvanced::_shaped_text_get_parent(const RID &p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, RID());
@@ -4197,16 +4201,16 @@ RID TextServerAdvanced::shaped_text_get_parent(const RID &p_shaped) const {
return sd->parent;
}
-double TextServerAdvanced::shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::JustificationFlag> p_jst_flags) {
+double TextServerAdvanced::_shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::JustificationFlag> p_jst_flags) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (!sd->justification_ops_valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_update_justification_ops(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_update_justification_ops(p_shaped);
}
sd->fit_width_minimum_reached = false;
@@ -4354,16 +4358,16 @@ double TextServerAdvanced::shaped_text_fit_to_width(const RID &p_shaped, double
return Math::ceil(justification_width);
}
-double TextServerAdvanced::shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) {
+double TextServerAdvanced::_shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (!sd->line_breaks_valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_update_breaks(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_update_breaks(p_shaped);
}
for (int i = 0; i < p_tab_stops.size(); i++) {
@@ -4410,13 +4414,13 @@ double TextServerAdvanced::shaped_text_tab_align(const RID &p_shaped, const Pack
return 0.0;
}
-void TextServerAdvanced::shaped_text_overrun_trim_to_width(const RID &p_shaped_line, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) {
+void TextServerAdvanced::_shaped_text_overrun_trim_to_width(const RID &p_shaped_line, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped_line);
ERR_FAIL_COND_MSG(!sd, "ShapedTextDataAdvanced invalid.");
MutexLock lock(sd->mutex);
if (!sd->valid) {
- shaped_text_shape(p_shaped_line);
+ _shaped_text_shape(p_shaped_line);
}
sd->text_trimmed = false;
@@ -4455,30 +4459,30 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(const RID &p_shaped_l
// Find usable fonts, if fonts from the last glyph do not have required chars.
RID dot_gl_font_rid = sd_glyphs[sd_size - 1].font_rid;
- if (!font_has_char(dot_gl_font_rid, '.')) {
+ if (!_font_has_char(dot_gl_font_rid, '.')) {
const Array &fonts = spans[spans.size() - 1].fonts;
for (int i = 0; i < fonts.size(); i++) {
- if (font_has_char(fonts[i], '.')) {
+ if (_font_has_char(fonts[i], '.')) {
dot_gl_font_rid = fonts[i];
break;
}
}
}
RID whitespace_gl_font_rid = sd_glyphs[sd_size - 1].font_rid;
- if (!font_has_char(whitespace_gl_font_rid, '.')) {
+ if (!_font_has_char(whitespace_gl_font_rid, '.')) {
const Array &fonts = spans[spans.size() - 1].fonts;
for (int i = 0; i < fonts.size(); i++) {
- if (font_has_char(fonts[i], ' ')) {
+ if (_font_has_char(fonts[i], ' ')) {
whitespace_gl_font_rid = fonts[i];
break;
}
}
}
- int32_t dot_gl_idx = dot_gl_font_rid.is_valid() ? font_get_glyph_index(dot_gl_font_rid, last_gl_font_size, '.') : -10;
- Vector2 dot_adv = dot_gl_font_rid.is_valid() ? font_get_glyph_advance(dot_gl_font_rid, last_gl_font_size, dot_gl_idx) : Vector2();
- int32_t whitespace_gl_idx = whitespace_gl_font_rid.is_valid() ? font_get_glyph_index(whitespace_gl_font_rid, last_gl_font_size, ' ') : -10;
- Vector2 whitespace_adv = whitespace_gl_font_rid.is_valid() ? font_get_glyph_advance(whitespace_gl_font_rid, last_gl_font_size, whitespace_gl_idx) : Vector2();
+ int32_t dot_gl_idx = dot_gl_font_rid.is_valid() ? _font_get_glyph_index(dot_gl_font_rid, last_gl_font_size, '.', 0) : -10;
+ Vector2 dot_adv = dot_gl_font_rid.is_valid() ? _font_get_glyph_advance(dot_gl_font_rid, last_gl_font_size, dot_gl_idx) : Vector2();
+ int32_t whitespace_gl_idx = whitespace_gl_font_rid.is_valid() ? _font_get_glyph_index(whitespace_gl_font_rid, last_gl_font_size, ' ', 0) : -10;
+ Vector2 whitespace_adv = whitespace_gl_font_rid.is_valid() ? _font_get_glyph_advance(whitespace_gl_font_rid, last_gl_font_size, whitespace_gl_idx) : Vector2();
int ellipsis_width = 0;
if (add_ellipsis && whitespace_gl_font_rid.is_valid()) {
@@ -4500,35 +4504,40 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(const RID &p_shaped_l
int glyphs_to = (is_rtl) ? sd_size - 1 : -1;
int glyphs_delta = (is_rtl) ? +1 : -1;
- for (int i = glyphs_from; i != glyphs_to; i += glyphs_delta) {
- if (!is_rtl) {
- width -= sd_glyphs[i].advance * sd_glyphs[i].repeat;
- }
- if (sd_glyphs[i].count > 0) {
- bool above_min_char_threshold = ((is_rtl) ? sd_size - 1 - i : i) >= ell_min_characters;
+ if (enforce_ellipsis && (width + ellipsis_width <= p_width)) {
+ trim_pos = -1;
+ ellipsis_pos = (is_rtl) ? 0 : sd_size;
+ } else {
+ for (int i = glyphs_from; i != glyphs_to; i += glyphs_delta) {
+ if (!is_rtl) {
+ width -= sd_glyphs[i].advance * sd_glyphs[i].repeat;
+ }
+ if (sd_glyphs[i].count > 0) {
+ bool above_min_char_threshold = ((is_rtl) ? sd_size - 1 - i : i) >= ell_min_characters;
- if (width + (((above_min_char_threshold && add_ellipsis) || enforce_ellipsis) ? ellipsis_width : 0) <= p_width) {
- if (cut_per_word && above_min_char_threshold) {
- if ((sd_glyphs[i].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT) {
+ if (width + (((above_min_char_threshold && add_ellipsis) || enforce_ellipsis) ? ellipsis_width : 0) <= p_width) {
+ if (cut_per_word && above_min_char_threshold) {
+ if ((sd_glyphs[i].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT) {
+ last_valid_cut = i;
+ found = true;
+ }
+ } else {
last_valid_cut = i;
found = true;
}
- } else {
- last_valid_cut = i;
- found = true;
- }
- if (found) {
- trim_pos = last_valid_cut;
+ if (found) {
+ trim_pos = last_valid_cut;
- if (add_ellipsis && (above_min_char_threshold || enforce_ellipsis) && width - ellipsis_width <= p_width) {
- ellipsis_pos = trim_pos;
+ if (add_ellipsis && (above_min_char_threshold || enforce_ellipsis) && width - ellipsis_width <= p_width) {
+ ellipsis_pos = trim_pos;
+ }
+ break;
}
- break;
}
}
- }
- if (is_rtl) {
- width -= sd_glyphs[i].advance * sd_glyphs[i].repeat;
+ if (is_rtl) {
+ width -= sd_glyphs[i].advance * sd_glyphs[i].repeat;
+ }
}
}
@@ -4572,7 +4581,7 @@ void TextServerAdvanced::shaped_text_overrun_trim_to_width(const RID &p_shaped_l
}
}
-int64_t TextServerAdvanced::shaped_text_get_trim_pos(const RID &p_shaped) const {
+int64_t TextServerAdvanced::_shaped_text_get_trim_pos(const RID &p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextDataAdvanced invalid.");
@@ -4580,7 +4589,7 @@ int64_t TextServerAdvanced::shaped_text_get_trim_pos(const RID &p_shaped) const
return sd->overrun_trim_data.trim_pos;
}
-int64_t TextServerAdvanced::shaped_text_get_ellipsis_pos(const RID &p_shaped) const {
+int64_t TextServerAdvanced::_shaped_text_get_ellipsis_pos(const RID &p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextDataAdvanced invalid.");
@@ -4588,7 +4597,7 @@ int64_t TextServerAdvanced::shaped_text_get_ellipsis_pos(const RID &p_shaped) co
return sd->overrun_trim_data.ellipsis_pos;
}
-const Glyph *TextServerAdvanced::shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const {
+const Glyph *TextServerAdvanced::_shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, nullptr, "ShapedTextDataAdvanced invalid.");
@@ -4596,7 +4605,7 @@ const Glyph *TextServerAdvanced::shaped_text_get_ellipsis_glyphs(const RID &p_sh
return sd->overrun_trim_data.ellipsis_glyph_buf.ptr();
}
-int64_t TextServerAdvanced::shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const {
+int64_t TextServerAdvanced::_shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, 0, "ShapedTextDataAdvanced invalid.");
@@ -4604,13 +4613,13 @@ int64_t TextServerAdvanced::shaped_text_get_ellipsis_glyph_count(const RID &p_sh
return sd->overrun_trim_data.ellipsis_glyph_buf.size();
}
-bool TextServerAdvanced::shaped_text_update_breaks(const RID &p_shaped) {
+bool TextServerAdvanced::_shaped_text_update_breaks(const RID &p_shaped) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- shaped_text_shape(p_shaped);
+ _shaped_text_shape(p_shaped);
}
if (sd->line_breaks_valid) {
@@ -4821,16 +4830,16 @@ _FORCE_INLINE_ int64_t _generate_kashida_justification_opportunies(const String
return kashida_pos;
}
-bool TextServerAdvanced::shaped_text_update_justification_ops(const RID &p_shaped) {
+bool TextServerAdvanced::_shaped_text_update_justification_ops(const RID &p_shaped) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- shaped_text_shape(p_shaped);
+ _shaped_text_shape(p_shaped);
}
if (!sd->line_breaks_valid) {
- shaped_text_update_breaks(p_shaped);
+ _shaped_text_update_breaks(p_shaped);
}
if (sd->justification_ops_valid) {
@@ -4975,7 +4984,7 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(const RID &p_shape
Glyph TextServerAdvanced::_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) {
hb_font_t *hb_font = _font_get_hb_handle(p_font, p_font_size);
- bool subpos = (font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_ONE_HALF) || (font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_AUTO && p_font_size <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE);
+ bool subpos = (_font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_ONE_HALF) || (_font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (_font_get_subpixel_positioning(p_font) == SUBPIXEL_POSITIONING_AUTO && p_font_size <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE);
ERR_FAIL_COND_V(hb_font == nullptr, Glyph());
hb_buffer_clear_contents(p_sd->hb_buffer);
@@ -5001,7 +5010,7 @@ Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced *p_sd, char
gl.font_size = p_font_size;
if (glyph_count > 0) {
- double scale = font_get_scale(p_font, p_font_size);
+ double scale = _font_get_scale(p_font, p_font_size);
if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
if (subpos) {
gl.advance = glyph_pos[0].x_advance / (64.0 / scale) + _get_extra_advance(p_font, p_font_size);
@@ -5036,7 +5045,7 @@ _FORCE_INLINE_ void TextServerAdvanced::_add_featuers(const Dictionary &p_source
if (value >= 0) {
hb_feature_t feature;
if (keys[i].get_type() == Variant::STRING) {
- feature.tag = name_to_tag(keys[i]);
+ feature.tag = _name_to_tag(keys[i]);
} else {
feature.tag = keys[i];
}
@@ -5087,12 +5096,12 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
Vector2i fss = _get_size(fd, fs);
hb_font_t *hb_font = _font_get_hb_handle(f, fs);
- double scale = font_get_scale(f, fs);
+ double scale = _font_get_scale(f, fs);
double sp_sp = p_sd->extra_spacing[SPACING_SPACE];
double sp_gl = p_sd->extra_spacing[SPACING_GLYPH];
bool last_run = (p_sd->end == p_end);
double ea = _get_extra_advance(f, fs);
- bool subpos = (font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_HALF) || (font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_AUTO && fs <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE);
+ bool subpos = (_font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_HALF) || (_font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (_font_get_subpixel_positioning(f) == SUBPIXEL_POSITIONING_AUTO && fs <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE);
ERR_FAIL_COND(hb_font == nullptr);
hb_buffer_clear_contents(p_sd->hb_buffer);
@@ -5120,7 +5129,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
hb_buffer_add_utf32(p_sd->hb_buffer, (const uint32_t *)p_sd->text.ptr(), p_sd->text.length(), p_start, p_end - p_start);
Vector<hb_feature_t> ftrs;
- _add_featuers(font_get_opentype_feature_overrides(f), ftrs);
+ _add_featuers(_font_get_opentype_feature_overrides(f), ftrs);
_add_featuers(p_sd->spans[p_span].features, ftrs);
hb_shape(hb_font, p_sd->hb_buffer, ftrs.is_empty() ? nullptr : &ftrs[0], ftrs.size());
@@ -5131,7 +5140,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -5251,7 +5260,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
p_sd->ascent = MAX(p_sd->ascent, -w[i + j].y_off);
p_sd->descent = MAX(p_sd->descent, w[i + j].y_off);
} else {
- double gla = Math::round(font_get_glyph_advance(f, fs, w[i + j].index).x * 0.5);
+ double gla = Math::round(_font_get_glyph_advance(f, fs, w[i + j].index).x * 0.5);
p_sd->ascent = MAX(p_sd->ascent, gla);
p_sd->descent = MAX(p_sd->descent, gla);
}
@@ -5274,14 +5283,14 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
if (failed_subrun_start != p_end + 1) {
_shape_run(p_sd, failed_subrun_start, failed_subrun_end, p_script, p_direction, p_fonts, p_span, p_fb_index + 1);
}
- p_sd->ascent = MAX(p_sd->ascent, font_get_ascent(f, fs));
- p_sd->descent = MAX(p_sd->descent, font_get_descent(f, fs));
- p_sd->upos = MAX(p_sd->upos, font_get_underline_position(f, fs));
- p_sd->uthk = MAX(p_sd->uthk, font_get_underline_thickness(f, fs));
+ p_sd->ascent = MAX(p_sd->ascent, _font_get_ascent(f, fs));
+ p_sd->descent = MAX(p_sd->descent, _font_get_descent(f, fs));
+ p_sd->upos = MAX(p_sd->upos, _font_get_underline_position(f, fs));
+ p_sd->uthk = MAX(p_sd->uthk, _font_get_underline_thickness(f, fs));
}
}
-bool TextServerAdvanced::shaped_text_shape(const RID &p_shaped) {
+bool TextServerAdvanced::_shaped_text_shape(const RID &p_shaped) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -5292,7 +5301,7 @@ bool TextServerAdvanced::shaped_text_shape(const RID &p_shaped) {
invalidate(sd, false);
if (sd->parent != RID()) {
- shaped_text_shape(sd->parent);
+ _shaped_text_shape(sd->parent);
ShapedTextDataAdvanced *parent_sd = shaped_owner.get_or_null(sd->parent);
ERR_FAIL_COND_V(!parent_sd->valid, false);
ERR_FAIL_COND_V(!_shape_substr(sd, parent_sd, sd->start, sd->end - sd->start), false);
@@ -5428,9 +5437,12 @@ bool TextServerAdvanced::shaped_text_shape(const RID &p_shaped) {
Array fonts_scr_only;
Array fonts_no_match;
int font_count = span.fonts.size();
- for (int l = 0; l < font_count; l++) {
- if (font_is_script_supported(span.fonts[l], script)) {
- if (font_is_language_supported(span.fonts[l], span.language)) {
+ if (font_count > 0) {
+ fonts.push_back(sd->spans[k].fonts[0]);
+ }
+ for (int l = 1; l < font_count; l++) {
+ if (_font_is_script_supported(span.fonts[l], script)) {
+ if (_font_is_language_supported(span.fonts[l], span.language)) {
fonts.push_back(sd->spans[k].fonts[l]);
} else {
fonts_scr_only.push_back(sd->spans[k].fonts[l]);
@@ -5454,7 +5466,7 @@ bool TextServerAdvanced::shaped_text_shape(const RID &p_shaped) {
return sd->valid;
}
-bool TextServerAdvanced::shaped_text_is_ready(const RID &p_shaped) const {
+bool TextServerAdvanced::_shaped_text_is_ready(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -5462,35 +5474,35 @@ bool TextServerAdvanced::shaped_text_is_ready(const RID &p_shaped) const {
return sd->valid;
}
-const Glyph *TextServerAdvanced::shaped_text_get_glyphs(const RID &p_shaped) const {
+const Glyph *TextServerAdvanced::_shaped_text_get_glyphs(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, nullptr);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return sd->glyphs.ptr();
}
-int64_t TextServerAdvanced::shaped_text_get_glyph_count(const RID &p_shaped) const {
+int64_t TextServerAdvanced::_shaped_text_get_glyph_count(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return sd->glyphs.size();
}
-const Glyph *TextServerAdvanced::shaped_text_sort_logical(const RID &p_shaped) {
+const Glyph *TextServerAdvanced::_shaped_text_sort_logical(const RID &p_shaped) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, nullptr);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (!sd->sort_valid) {
@@ -5502,7 +5514,7 @@ const Glyph *TextServerAdvanced::shaped_text_sort_logical(const RID &p_shaped) {
return sd->glyphs_logical.ptr();
}
-Vector2i TextServerAdvanced::shaped_text_get_range(const RID &p_shaped) const {
+Vector2i TextServerAdvanced::_shaped_text_get_range(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Vector2i());
@@ -5510,7 +5522,7 @@ Vector2i TextServerAdvanced::shaped_text_get_range(const RID &p_shaped) const {
return Vector2(sd->start, sd->end);
}
-Array TextServerAdvanced::shaped_text_get_objects(const RID &p_shaped) const {
+Array TextServerAdvanced::_shaped_text_get_objects(const RID &p_shaped) const {
Array ret;
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, ret);
@@ -5523,25 +5535,25 @@ Array TextServerAdvanced::shaped_text_get_objects(const RID &p_shaped) const {
return ret;
}
-Rect2 TextServerAdvanced::shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const {
+Rect2 TextServerAdvanced::_shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Rect2());
MutexLock lock(sd->mutex);
ERR_FAIL_COND_V(!sd->objects.has(p_key), Rect2());
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return sd->objects[p_key].rect;
}
-Size2 TextServerAdvanced::shaped_text_get_size(const RID &p_shaped) const {
+Size2 TextServerAdvanced::_shaped_text_get_size(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Size2());
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
if (sd->orientation == TextServer::ORIENTATION_HORIZONTAL) {
return Size2((sd->text_trimmed ? sd->width_trimmed : sd->width), sd->ascent + sd->descent + sd->extra_spacing[SPACING_TOP] + sd->extra_spacing[SPACING_BOTTOM]).ceil();
@@ -5550,58 +5562,58 @@ Size2 TextServerAdvanced::shaped_text_get_size(const RID &p_shaped) const {
}
}
-double TextServerAdvanced::shaped_text_get_ascent(const RID &p_shaped) const {
+double TextServerAdvanced::_shaped_text_get_ascent(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return sd->ascent + sd->extra_spacing[SPACING_TOP];
}
-double TextServerAdvanced::shaped_text_get_descent(const RID &p_shaped) const {
+double TextServerAdvanced::_shaped_text_get_descent(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return sd->descent + sd->extra_spacing[SPACING_BOTTOM];
}
-double TextServerAdvanced::shaped_text_get_width(const RID &p_shaped) const {
+double TextServerAdvanced::_shaped_text_get_width(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return Math::ceil(sd->text_trimmed ? sd->width_trimmed : sd->width);
}
-double TextServerAdvanced::shaped_text_get_underline_position(const RID &p_shaped) const {
+double TextServerAdvanced::_shaped_text_get_underline_position(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return sd->upos;
}
-double TextServerAdvanced::shaped_text_get_underline_thickness(const RID &p_shaped) const {
+double TextServerAdvanced::_shaped_text_get_underline_thickness(const RID &p_shaped) const {
const ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerAdvanced *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerAdvanced *>(this)->_shaped_text_shape(p_shaped);
}
return sd->uthk;
@@ -5782,7 +5794,7 @@ void TextServerAdvanced::_insert_num_systems_lang() {
}
}
-String TextServerAdvanced::format_number(const String &p_string, const String &p_language) const {
+String TextServerAdvanced::_format_number(const String &p_string, const String &p_language) const {
const StringName lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
String res = p_string;
@@ -5807,7 +5819,7 @@ String TextServerAdvanced::format_number(const String &p_string, const String &p
return res;
}
-String TextServerAdvanced::parse_number(const String &p_string, const String &p_language) const {
+String TextServerAdvanced::_parse_number(const String &p_string, const String &p_language) const {
const StringName lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
String res = p_string;
@@ -5835,7 +5847,7 @@ String TextServerAdvanced::parse_number(const String &p_string, const String &p_
return res;
}
-String TextServerAdvanced::percent_sign(const String &p_language) const {
+String TextServerAdvanced::_percent_sign(const String &p_language) const {
const StringName lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
for (int i = 0; i < num_systems.size(); i++) {
@@ -5849,9 +5861,9 @@ String TextServerAdvanced::percent_sign(const String &p_language) const {
return "%";
}
-int TextServerAdvanced::is_confusable(const String &p_string, const PackedStringArray &p_dict) const {
+int64_t TextServerAdvanced::_is_confusable(const String &p_string, const PackedStringArray &p_dict) const {
UErrorCode status = U_ZERO_ERROR;
- int match_index = -1;
+ int64_t match_index = -1;
Char16String utf16 = p_string.utf16();
Vector<UChar *> skeletons;
@@ -5889,7 +5901,7 @@ int TextServerAdvanced::is_confusable(const String &p_string, const PackedString
return match_index;
}
-bool TextServerAdvanced::spoof_check(const String &p_string) const {
+bool TextServerAdvanced::_spoof_check(const String &p_string) const {
UErrorCode status = U_ZERO_ERROR;
Char16String utf16 = p_string.utf16();
@@ -5911,7 +5923,7 @@ bool TextServerAdvanced::spoof_check(const String &p_string) const {
return (bitmask != 0);
}
-String TextServerAdvanced::strip_diacritics(const String &p_string) const {
+String TextServerAdvanced::_strip_diacritics(const String &p_string) const {
UErrorCode err = U_ZERO_ERROR;
// Get NFKD normalizer singleton.
@@ -5944,7 +5956,7 @@ String TextServerAdvanced::strip_diacritics(const String &p_string) const {
return result;
}
-String TextServerAdvanced::string_to_upper(const String &p_string, const String &p_language) const {
+String TextServerAdvanced::_string_to_upper(const String &p_string, const String &p_language) const {
const String lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
// Convert to UTF-16.
@@ -5963,7 +5975,7 @@ String TextServerAdvanced::string_to_upper(const String &p_string, const String
return String::utf16(upper.ptr(), len);
}
-String TextServerAdvanced::string_to_lower(const String &p_string, const String &p_language) const {
+String TextServerAdvanced::_string_to_lower(const String &p_string, const String &p_language) const {
const String lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
// Convert to UTF-16.
Char16String utf16 = p_string.utf16();
@@ -5981,7 +5993,7 @@ String TextServerAdvanced::string_to_lower(const String &p_string, const String
return String::utf16(lower.ptr(), len);
}
-PackedInt32Array TextServerAdvanced::string_get_word_breaks(const String &p_string, const String &p_language) const {
+PackedInt32Array TextServerAdvanced::_string_get_word_breaks(const String &p_string, const String &p_language) const {
const String lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language;
// Convert to UTF-16.
Char16String utf16 = p_string.utf16();
@@ -6029,7 +6041,7 @@ PackedInt32Array TextServerAdvanced::string_get_word_breaks(const String &p_stri
return ret;
}
-bool TextServerAdvanced::is_valid_identifier(const String &p_string) const {
+bool TextServerAdvanced::_is_valid_identifier(const String &p_string) const {
enum UAX31SequenceStatus {
SEQ_NOT_STARTED,
SEQ_STARTED,
@@ -6050,7 +6062,7 @@ bool TextServerAdvanced::is_valid_identifier(const String &p_string) const {
if (U_FAILURE(err)) {
return false; // Failed to load normalizer.
}
- bool isnurom = unorm2_isNormalized(norm_c, utf16.ptr(), utf16.length(), &err);
+ bool isnurom = unorm2_isNormalized(norm_c, utf16.get_data(), utf16.length(), &err);
if (U_FAILURE(err) || !isnurom) {
return false; // Do not conform to Normalization Form C.
}
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index 1db95d153b..fb5075e835 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -42,6 +42,7 @@
#include <godot_cpp/godot.hpp>
#include <godot_cpp/core/class_db.hpp>
+#include <godot_cpp/core/ext_wrappers.gen.inc>
#include <godot_cpp/core/mutex_lock.hpp>
#include <godot_cpp/variant/array.hpp>
@@ -52,6 +53,7 @@
#include <godot_cpp/variant/rect2.hpp>
#include <godot_cpp/variant/rid.hpp>
#include <godot_cpp/variant/string.hpp>
+#include <godot_cpp/variant/typed_array.hpp>
#include <godot_cpp/variant/vector2.hpp>
#include <godot_cpp/variant/vector2i.hpp>
@@ -78,11 +80,13 @@ using namespace godot;
#else
// Headers for building as built-in module.
+#include "servers/text/text_server_extension.h"
+
+#include "core/extension/ext_wrappers.gen.inc"
#include "core/object/worker_thread_pool.h"
#include "core/templates/hash_map.h"
#include "core/templates/rid_owner.h"
#include "scene/resources/texture.h"
-#include "servers/text/text_server_extension.h"
#include "modules/modules_enabled.gen.h" // For freetype, msdfgen.
@@ -461,258 +465,259 @@ protected:
void invalidate(ShapedTextDataAdvanced *p_shaped, bool p_text = false);
public:
- virtual bool has_feature(Feature p_feature) const override;
- virtual String get_name() const override;
- virtual int64_t get_features() const override;
+ MODBIND1RC(bool, has_feature, Feature);
+ MODBIND0RC(String, get_name);
+ MODBIND0RC(int64_t, get_features);
- 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;
+ MODBIND1(free_rid, const RID &);
+ MODBIND1R(bool, has, const RID &);
+ MODBIND1R(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;
+ MODBIND0RC(String, get_support_data_filename);
+ MODBIND0RC(String, get_support_data_info);
+ MODBIND1RC(bool, save_support_data, const String &);
- virtual bool is_locale_right_to_left(const String &p_locale) const override;
+ MODBIND1RC(bool, is_locale_right_to_left, const String &);
- virtual int64_t name_to_tag(const String &p_name) const override;
- virtual String tag_to_name(int64_t p_tag) const override;
+ MODBIND1RC(int64_t, name_to_tag, const String &);
+ MODBIND1RC(String, tag_to_name, int64_t);
/* Font interface */
- virtual RID create_font() 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;
+ MODBIND0R(RID, create_font);
+
+ MODBIND2(font_set_data, const RID &, const PackedByteArray &);
+ MODBIND3(font_set_data_ptr, const RID &, const uint8_t *, int64_t);
- virtual void font_set_face_index(const RID &p_font_rid, int64_t p_index) override;
- virtual int64_t font_get_face_index(const RID &p_font_rid) const override;
+ MODBIND2(font_set_face_index, const RID &, int64_t);
+ MODBIND1RC(int64_t, font_get_face_index, const RID &);
- virtual int64_t font_get_face_count(const RID &p_font_rid) const override;
+ MODBIND1RC(int64_t, font_get_face_count, const RID &);
- virtual void font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) override;
- virtual BitField<FontStyle> font_get_style(const RID &p_font_rid) const override;
+ MODBIND2(font_set_style, const RID &, BitField<FontStyle>);
+ MODBIND1RC(BitField<FontStyle>, font_get_style, const 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;
+ MODBIND2(font_set_style_name, const RID &, const String &);
+ MODBIND1RC(String, font_get_style_name, const 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;
+ MODBIND2(font_set_name, const RID &, const String &);
+ MODBIND1RC(String, font_get_name, const RID &);
- virtual void font_set_antialiasing(RID p_font_rid, TextServer::FontAntialiasing p_antialiasing) override;
- virtual TextServer::FontAntialiasing font_get_antialiasing(RID p_font_rid) const override;
+ MODBIND2(font_set_antialiasing, const RID &, TextServer::FontAntialiasing);
+ MODBIND1RC(TextServer::FontAntialiasing, font_get_antialiasing, const RID &);
- virtual void font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) override;
- virtual bool font_get_generate_mipmaps(const RID &p_font_rid) const override;
+ MODBIND2(font_set_generate_mipmaps, const RID &, bool);
+ MODBIND1RC(bool, font_get_generate_mipmaps, const 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;
+ MODBIND2(font_set_multichannel_signed_distance_field, const RID &, bool);
+ MODBIND1RC(bool, font_is_multichannel_signed_distance_field, const 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;
+ MODBIND2(font_set_msdf_pixel_range, const RID &, int64_t);
+ MODBIND1RC(int64_t, font_get_msdf_pixel_range, const 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;
+ MODBIND2(font_set_msdf_size, const RID &, int64_t);
+ MODBIND1RC(int64_t, font_get_msdf_size, const 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;
+ MODBIND2(font_set_fixed_size, const RID &, int64_t);
+ MODBIND1RC(int64_t, font_get_fixed_size, const 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;
+ MODBIND2(font_set_force_autohinter, const RID &, bool);
+ MODBIND1RC(bool, font_is_force_autohinter, const 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;
+ MODBIND2(font_set_subpixel_positioning, const RID &, SubpixelPositioning);
+ MODBIND1RC(SubpixelPositioning, font_get_subpixel_positioning, const 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;
+ MODBIND2(font_set_embolden, const RID &, double);
+ MODBIND1RC(double, font_get_embolden, const 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;
+ MODBIND2(font_set_transform, const RID &, const Transform2D &);
+ MODBIND1RC(Transform2D, font_get_transform, const 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;
+ MODBIND2(font_set_variation_coordinates, const RID &, const Dictionary &);
+ MODBIND1RC(Dictionary, font_get_variation_coordinates, const RID &);
- 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;
+ MODBIND2(font_set_hinting, const RID &, TextServer::Hinting);
+ MODBIND1RC(TextServer::Hinting, font_get_hinting, const 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;
+ MODBIND2(font_set_oversampling, const RID &, double);
+ MODBIND1RC(double, font_get_oversampling, const RID &);
- virtual TypedArray<Vector2i> 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;
+ MODBIND1RC(TypedArray<Vector2i>, font_get_size_cache_list, const RID &);
+ MODBIND1(font_clear_size_cache, const RID &);
+ MODBIND2(font_remove_size_cache, const 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;
+ MODBIND3(font_set_ascent, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_ascent, const 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;
+ MODBIND3(font_set_descent, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_descent, const 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;
+ MODBIND3(font_set_underline_position, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_underline_position, const 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;
+ MODBIND3(font_set_underline_thickness, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_underline_thickness, const 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;
+ MODBIND3(font_set_scale, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_scale, const RID &, int64_t);
- 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;
+ MODBIND2RC(int64_t, font_get_texture_count, const RID &, const Vector2i &);
+ MODBIND2(font_clear_textures, const RID &, const Vector2i &);
+ MODBIND3(font_remove_texture, const 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;
+ MODBIND4(font_set_texture_image, const RID &, const Vector2i &, int64_t, const Ref<Image> &);
+ MODBIND3RC(Ref<Image>, font_get_texture_image, const 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;
+ MODBIND4(font_set_texture_offsets, const RID &, const Vector2i &, int64_t, const PackedInt32Array &);
+ MODBIND3RC(PackedInt32Array, font_get_texture_offsets, const RID &, const Vector2i &, int64_t);
- virtual PackedInt32Array 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;
+ MODBIND2RC(PackedInt32Array, font_get_glyph_list, const RID &, const Vector2i &);
+ MODBIND2(font_clear_glyphs, const RID &, const Vector2i &);
+ MODBIND3(font_remove_glyph, const 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;
+ MODBIND3RC(Vector2, font_get_glyph_advance, const RID &, int64_t, int64_t);
+ MODBIND4(font_set_glyph_advance, const 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;
+ MODBIND3RC(Vector2, font_get_glyph_offset, const RID &, const Vector2i &, int64_t);
+ MODBIND4(font_set_glyph_offset, const 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;
+ MODBIND3RC(Vector2, font_get_glyph_size, const RID &, const Vector2i &, int64_t);
+ MODBIND4(font_set_glyph_size, const 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;
+ MODBIND3RC(Rect2, font_get_glyph_uv_rect, const RID &, const Vector2i &, int64_t);
+ MODBIND4(font_set_glyph_uv_rect, const 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;
+ MODBIND3RC(int64_t, font_get_glyph_texture_idx, const RID &, const Vector2i &, int64_t);
+ MODBIND4(font_set_glyph_texture_idx, const RID &, const Vector2i &, int64_t, int64_t);
- virtual RID font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
- virtual Size2 font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+ MODBIND3RC(RID, font_get_glyph_texture_rid, const RID &, const Vector2i &, int64_t);
+ MODBIND3RC(Size2, font_get_glyph_texture_size, const RID &, const Vector2i &, int64_t);
- virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override;
+ MODBIND3RC(Dictionary, font_get_glyph_contours, const RID &, int64_t, int64_t);
- virtual TypedArray<Vector2i> 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;
+ MODBIND2RC(TypedArray<Vector2i>, font_get_kerning_list, const RID &, int64_t);
+ MODBIND2(font_clear_kerning_map, const RID &, int64_t);
+ MODBIND3(font_remove_kerning, const 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;
+ MODBIND4(font_set_kerning, const RID &, int64_t, const Vector2i &, const Vector2 &);
+ MODBIND3RC(Vector2, font_get_kerning, const 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;
+ MODBIND4RC(int64_t, font_get_glyph_index, const 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;
+ MODBIND2RC(bool, font_has_char, const RID &, int64_t);
+ MODBIND1RC(String, font_get_supported_chars, const 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;
+ MODBIND4(font_render_range, const RID &, const Vector2i &, int64_t, int64_t);
+ MODBIND3(font_render_glyph, const 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;
+ MODBIND6C(font_draw_glyph, const RID &, const RID &, int64_t, const Vector2 &, int64_t, const Color &);
+ MODBIND7C(font_draw_glyph_outline, const RID &, const 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;
+ MODBIND2RC(bool, font_is_language_supported, const RID &, const String &);
+ MODBIND3(font_set_language_support_override, const RID &, const String &, bool);
+ MODBIND2R(bool, font_get_language_support_override, const RID &, const String &);
+ MODBIND2(font_remove_language_support_override, const RID &, const String &);
+ MODBIND1R(PackedStringArray, font_get_language_support_overrides, const 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;
+ MODBIND2RC(bool, font_is_script_supported, const RID &, const String &);
+ MODBIND3(font_set_script_support_override, const RID &, const String &, bool);
+ MODBIND2R(bool, font_get_script_support_override, const RID &, const String &);
+ MODBIND2(font_remove_script_support_override, const RID &, const String &);
+ MODBIND1R(PackedStringArray, font_get_script_support_overrides, const 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;
+ MODBIND2(font_set_opentype_feature_overrides, const RID &, const Dictionary &);
+ MODBIND1RC(Dictionary, font_get_opentype_feature_overrides, const 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;
+ MODBIND1RC(Dictionary, font_supported_feature_list, const RID &);
+ MODBIND1RC(Dictionary, font_supported_variation_list, const RID &);
- virtual double font_get_global_oversampling() const override;
- virtual void font_set_global_oversampling(double p_oversampling) override;
+ MODBIND0RC(double, font_get_global_oversampling);
+ MODBIND1(font_set_global_oversampling, double);
/* Shaped text buffer interface */
- virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
+ MODBIND2R(RID, create_shaped_text, Direction, Orientation);
- virtual void shaped_text_clear(const RID &p_shaped) override;
+ MODBIND1(shaped_text_clear, const 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;
+ MODBIND2(shaped_text_set_direction, const RID &, Direction);
+ MODBIND1RC(Direction, shaped_text_get_direction, const RID &);
+ MODBIND1RC(Direction, shaped_text_get_inferred_direction, const RID &);
- virtual void shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) override;
+ MODBIND2(shaped_text_set_bidi_override, const 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;
+ MODBIND2(shaped_text_set_custom_punctuation, const RID &, const String &);
+ MODBIND1RC(String, shaped_text_get_custom_punctuation, const 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;
+ MODBIND2(shaped_text_set_orientation, const RID &, Orientation);
+ MODBIND1RC(Orientation, shaped_text_get_orientation, const 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;
+ MODBIND2(shaped_text_set_preserve_invalid, const RID &, bool);
+ MODBIND1RC(bool, shaped_text_get_preserve_invalid, const 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;
+ MODBIND2(shaped_text_set_preserve_control, const RID &, bool);
+ MODBIND1RC(bool, shaped_text_get_preserve_control, const RID &);
- virtual void shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) override;
- virtual int64_t shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const override;
+ MODBIND3(shaped_text_set_spacing, const RID &, SpacingType, int64_t);
+ MODBIND2RC(int64_t, shaped_text_get_spacing, const RID &, SpacingType);
- virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &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;
+ MODBIND7R(bool, shaped_text_add_string, const RID &, const String &, const TypedArray<RID> &, int64_t, const Dictionary &, const String &, const Variant &);
+ MODBIND5R(bool, shaped_text_add_object, const RID &, const Variant &, const Size2 &, InlineAlignment, int64_t);
+ MODBIND4R(bool, shaped_text_resize_object, const 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 TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override;
+ MODBIND1RC(int64_t, shaped_get_span_count, const RID &);
+ MODBIND2RC(Variant, shaped_get_span_meta, const RID &, int64_t);
+ MODBIND5(shaped_set_span_update_font, const RID &, int64_t, const TypedArray<RID> &, 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;
+ MODBIND3RC(RID, shaped_text_substr, const RID &, int64_t, int64_t);
+ MODBIND1RC(RID, shaped_text_get_parent, const RID &);
- virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::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;
+ MODBIND3R(double, shaped_text_fit_to_width, const RID &, double, BitField<TextServer::JustificationFlag>);
+ MODBIND2R(double, shaped_text_tab_align, const 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;
+ MODBIND1R(bool, shaped_text_shape, const RID &);
+ MODBIND1R(bool, shaped_text_update_breaks, const RID &);
+ MODBIND1R(bool, shaped_text_update_justification_ops, const RID &);
- 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;
+ MODBIND1RC(int64_t, shaped_text_get_trim_pos, const RID &);
+ MODBIND1RC(int64_t, shaped_text_get_ellipsis_pos, const RID &);
+ MODBIND1RC(const Glyph *, shaped_text_get_ellipsis_glyphs, const RID &);
+ MODBIND1RC(int64_t, shaped_text_get_ellipsis_glyph_count, const RID &);
- virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) override;
+ MODBIND3(shaped_text_overrun_trim_to_width, const RID &, double, BitField<TextServer::TextOverrunFlag>);
- virtual bool shaped_text_is_ready(const RID &p_shaped) const override;
+ MODBIND1RC(bool, shaped_text_is_ready, const 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;
+ MODBIND1RC(const Glyph *, shaped_text_get_glyphs, const RID &);
+ MODBIND1R(const Glyph *, shaped_text_sort_logical, const RID &);
+ MODBIND1RC(int64_t, shaped_text_get_glyph_count, const RID &);
- virtual Vector2i shaped_text_get_range(const RID &p_shaped) const override;
+ MODBIND1RC(Vector2i, shaped_text_get_range, const RID &);
- 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;
+ MODBIND1RC(Array, shaped_text_get_objects, const RID &);
+ MODBIND2RC(Rect2, shaped_text_get_object_rect, const 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;
+ MODBIND1RC(Size2, shaped_text_get_size, const RID &);
+ MODBIND1RC(double, shaped_text_get_ascent, const RID &);
+ MODBIND1RC(double, shaped_text_get_descent, const RID &);
+ MODBIND1RC(double, shaped_text_get_width, const RID &);
+ MODBIND1RC(double, shaped_text_get_underline_position, const RID &);
+ MODBIND1RC(double, shaped_text_get_underline_thickness, const RID &);
- 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;
+ MODBIND2RC(String, format_number, const String &, const String &);
+ MODBIND2RC(String, parse_number, const String &, const String &);
+ MODBIND1RC(String, percent_sign, const String &);
- virtual PackedInt32Array string_get_word_breaks(const String &p_string, const String &p_language = "") const override;
+ MODBIND2RC(PackedInt32Array, string_get_word_breaks, const String &, const String &);
- virtual int is_confusable(const String &p_string, const PackedStringArray &p_dict) const override;
- virtual bool spoof_check(const String &p_string) const override;
+ MODBIND2RC(int64_t, is_confusable, const String &, const PackedStringArray &);
+ MODBIND1RC(bool, spoof_check, const String &);
- virtual String strip_diacritics(const String &p_string) const override;
- virtual bool is_valid_identifier(const String &p_string) const override;
+ MODBIND1RC(String, strip_diacritics, const String &);
+ MODBIND1RC(bool, is_valid_identifier, 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;
+ MODBIND2RC(String, string_to_upper, const String &, const String &);
+ MODBIND2RC(String, string_to_lower, const String &, const String &);
TextServerAdvanced();
~TextServerAdvanced();
diff --git a/modules/text_server_fb/gdextension_build/SConstruct b/modules/text_server_fb/gdextension_build/SConstruct
index de0a549900..eae8e031bf 100644
--- a/modules/text_server_fb/gdextension_build/SConstruct
+++ b/modules/text_server_fb/gdextension_build/SConstruct
@@ -19,6 +19,7 @@ env = SConscript("./godot-cpp/SConstruct")
env.__class__.disable_warnings = methods.disable_warnings
opts = Variables([], ARGUMENTS)
+opts.Add(BoolVariable("brotli_enabled", "Use Brotli library", True))
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))
@@ -157,6 +158,25 @@ if env["freetype_enabled"]:
]
thirdparty_freetype_sources += [thirdparty_zlib_dir + file for file in thirdparty_zlib_sources]
+ if env["brotli_enabled"]:
+ thirdparty_brotli_dir = "../../../thirdparty/brotli/"
+ thirdparty_brotli_sources = [
+ "common/constants.c",
+ "common/context.c",
+ "common/dictionary.c",
+ "common/platform.c",
+ "common/shared_dictionary.c",
+ "common/transform.c",
+ "dec/bit_reader.c",
+ "dec/decode.c",
+ "dec/huffman.c",
+ "dec/state.c",
+ ]
+ thirdparty_freetype_sources += [thirdparty_brotli_dir + file for file in thirdparty_brotli_sources]
+ env_freetype.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"])
+ env_freetype.Prepend(CPPPATH=[thirdparty_brotli_dir + "include"])
+ env.Append(CPPDEFINES=["FT_CONFIG_OPTION_USE_BROTLI"])
+
env_freetype.Append(CPPPATH=[thirdparty_freetype_dir + "/include", thirdparty_zlib_dir, thirdparty_png_dir])
env.Append(CPPPATH=[thirdparty_freetype_dir + "/include"])
@@ -168,7 +188,7 @@ if env["freetype_enabled"]:
"FT_CONFIG_OPTION_SYSTEM_ZLIB",
]
)
- if env["target"] == "debug":
+ if env.dev_build:
env_freetype.Append(CPPDEFINES=["ZLIB_DEBUG"])
env.Append(CPPDEFINES=["MODULE_FREETYPE_ENABLED"])
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp
index 4d599dbcb5..518c877baa 100644
--- a/modules/text_server_fb/text_server_fb.cpp
+++ b/modules/text_server_fb/text_server_fb.cpp
@@ -33,7 +33,7 @@
#ifdef GDEXTENSION
// Headers for building as GDExtension plug-in.
-#include <godot_cpp/classes/file.hpp>
+#include <godot_cpp/classes/file_access.hpp>
#include <godot_cpp/classes/project_settings.hpp>
#include <godot_cpp/classes/rendering_server.hpp>
#include <godot_cpp/classes/translation_server.hpp>
@@ -66,7 +66,7 @@ using namespace godot;
#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)))
-bool TextServerFallback::has_feature(Feature p_feature) const {
+bool TextServerFallback::_has_feature(Feature p_feature) const {
switch (p_feature) {
case FEATURE_SIMPLE_LAYOUT:
case FEATURE_FONT_BITMAP:
@@ -83,7 +83,7 @@ bool TextServerFallback::has_feature(Feature p_feature) const {
return false;
}
-String TextServerFallback::get_name() const {
+String TextServerFallback::_get_name() const {
#ifdef GDEXTENSION
return "Fallback (GDExtension)";
#else
@@ -91,7 +91,7 @@ String TextServerFallback::get_name() const {
#endif
}
-int64_t TextServerFallback::get_features() const {
+int64_t TextServerFallback::_get_features() const {
int64_t interface_features = FEATURE_SIMPLE_LAYOUT | FEATURE_FONT_BITMAP;
#ifdef MODULE_FREETYPE_ENABLED
interface_features |= FEATURE_FONT_DYNAMIC;
@@ -103,7 +103,7 @@ int64_t TextServerFallback::get_features() const {
return interface_features;
}
-void TextServerFallback::free_rid(const RID &p_rid) {
+void TextServerFallback::_free_rid(const RID &p_rid) {
_THREAD_SAFE_METHOD_
if (font_owner.owns(p_rid)) {
FontFallback *fd = font_owner.get_or_null(p_rid);
@@ -116,20 +116,28 @@ void TextServerFallback::free_rid(const RID &p_rid) {
}
}
-bool TextServerFallback::has(const RID &p_rid) {
+bool TextServerFallback::_has(const RID &p_rid) {
_THREAD_SAFE_METHOD_
return font_owner.owns(p_rid) || shaped_owner.owns(p_rid);
}
-bool TextServerFallback::load_support_data(const String &p_filename) {
+String TextServerFallback::_get_support_data_filename() const {
+ return "";
+};
+
+String TextServerFallback::_get_support_data_info() const {
+ return "Not supported";
+};
+
+bool TextServerFallback::_load_support_data(const String &p_filename) {
return false; // No extra data used.
}
-bool TextServerFallback::save_support_data(const String &p_filename) const {
+bool TextServerFallback::_save_support_data(const String &p_filename) const {
return false; // No extra data used.
}
-bool TextServerFallback::is_locale_right_to_left(const String &p_locale) const {
+bool TextServerFallback::_is_locale_right_to_left(const String &p_locale) const {
return false; // No RTL support.
}
@@ -169,7 +177,7 @@ _FORCE_INLINE_ int32_t ot_tag_from_string(const char *p_str, int p_len) {
return OT_TAG(tag[0], tag[1], tag[2], tag[3]);
}
-int64_t TextServerFallback::name_to_tag(const String &p_name) const {
+int64_t TextServerFallback::_name_to_tag(const String &p_name) const {
if (feature_sets.has(p_name)) {
return feature_sets[p_name];
}
@@ -185,7 +193,7 @@ _FORCE_INLINE_ void ot_tag_to_string(int32_t p_tag, char *p_buf) {
p_buf[3] = (char)(uint8_t)(p_tag >> 0);
}
-String TextServerFallback::tag_to_name(int64_t p_tag) const {
+String TextServerFallback::_tag_to_name(int64_t p_tag) const {
if (feature_sets_inv.has(p_tag)) {
return feature_sets_inv[p_tag];
}
@@ -467,8 +475,14 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf(
td.projection = &projection;
td.distancePixelConversion = &distancePixelConversion;
+#ifdef GDEXTENSION
+ for (int i = 0; i < h; i++) {
+ _generateMTSDF_threaded(i, &td);
+ }
+#else
WorkerThreadPool::GroupID group_id = WorkerThreadPool::get_singleton()->add_template_group_task(this, &TextServerFallback::_generateMTSDF_threaded, &td, h, -1, true, SNAME("TextServerFBRenderMSDF"));
WorkerThreadPool::get_singleton()->wait_for_group_task_completion(group_id);
+#endif
msdfgen::msdfErrorCorrection(image, shape, projection, p_pixel_range, config);
@@ -840,7 +854,7 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_f
fd->oversampling = 1.0;
fd->size.x = p_font_data->msdf_source_size;
} else if (p_font_data->oversampling <= 0.0) {
- fd->oversampling = font_get_global_oversampling();
+ fd->oversampling = _font_get_global_oversampling();
} else {
fd->oversampling = p_font_data->oversampling;
}
@@ -921,8 +935,8 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_f
coords.write[i] = CLAMP(var_value * 65536.0, amaster->axis[i].minimum, amaster->axis[i].maximum);
}
- if (p_font_data->variation_coordinates.has(tag_to_name(var_tag))) {
- var_value = p_font_data->variation_coordinates[tag_to_name(var_tag)];
+ if (p_font_data->variation_coordinates.has(_tag_to_name(var_tag))) {
+ var_value = p_font_data->variation_coordinates[_tag_to_name(var_tag)];
coords.write[i] = CLAMP(var_value * 65536.0, amaster->axis[i].minimum, amaster->axis[i].maximum);
}
}
@@ -948,7 +962,7 @@ _FORCE_INLINE_ void TextServerFallback::_font_clear_cache(FontFallback *p_font_d
p_font_data->supported_varaitions.clear();
}
-RID TextServerFallback::create_font() {
+RID TextServerFallback::_create_font() {
_THREAD_SAFE_METHOD_
FontFallback *fd = memnew(FontFallback);
@@ -956,7 +970,7 @@ RID TextServerFallback::create_font() {
return font_owner.make_rid(fd);
}
-void TextServerFallback::font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) {
+void TextServerFallback::_font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -967,7 +981,7 @@ void TextServerFallback::font_set_data(const RID &p_font_rid, const PackedByteAr
fd->data_size = fd->data.size();
}
-void TextServerFallback::font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) {
+void TextServerFallback::_font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -978,7 +992,7 @@ void TextServerFallback::font_set_data_ptr(const RID &p_font_rid, const uint8_t
fd->data_size = p_data_size;
}
-void TextServerFallback::font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) {
+void TextServerFallback::_font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -988,7 +1002,7 @@ void TextServerFallback::font_set_style(const RID &p_font_rid, BitField<FontStyl
fd->style_flags = p_style;
}
-void TextServerFallback::font_set_face_index(const RID &p_font_rid, int64_t p_face_index) {
+void TextServerFallback::_font_set_face_index(const RID &p_font_rid, int64_t p_face_index) {
ERR_FAIL_COND(p_face_index < 0);
ERR_FAIL_COND(p_face_index >= 0x7FFF);
@@ -1002,7 +1016,7 @@ void TextServerFallback::font_set_face_index(const RID &p_font_rid, int64_t p_fa
}
}
-int64_t TextServerFallback::font_get_face_index(const RID &p_font_rid) const {
+int64_t TextServerFallback::_font_get_face_index(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
@@ -1010,7 +1024,7 @@ int64_t TextServerFallback::font_get_face_index(const RID &p_font_rid) const {
return fd->face_index;
}
-int64_t TextServerFallback::font_get_face_count(const RID &p_font_rid) const {
+int64_t TextServerFallback::_font_get_face_count(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
@@ -1039,19 +1053,19 @@ int64_t TextServerFallback::font_get_face_count(const RID &p_font_rid) const {
fargs.flags = FT_OPEN_MEMORY;
fargs.stream = &stream;
- FT_Face tmp_face;
+ FT_Face tmp_face = nullptr;
error = FT_Open_Face(ft_library, &fargs, -1, &tmp_face);
if (error == 0) {
face_count = tmp_face->num_faces;
+ FT_Done_Face(tmp_face);
}
- FT_Done_Face(tmp_face);
#endif
}
return face_count;
}
-BitField<TextServer::FontStyle> TextServerFallback::font_get_style(const RID &p_font_rid) const {
+BitField<TextServer::FontStyle> TextServerFallback::_font_get_style(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
@@ -1061,7 +1075,7 @@ BitField<TextServer::FontStyle> TextServerFallback::font_get_style(const RID &p_
return fd->style_flags;
}
-void TextServerFallback::font_set_style_name(const RID &p_font_rid, const String &p_name) {
+void TextServerFallback::_font_set_style_name(const RID &p_font_rid, const String &p_name) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1071,7 +1085,7 @@ void TextServerFallback::font_set_style_name(const RID &p_font_rid, const String
fd->style_name = p_name;
}
-String TextServerFallback::font_get_style_name(const RID &p_font_rid) const {
+String TextServerFallback::_font_get_style_name(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
@@ -1081,7 +1095,7 @@ String TextServerFallback::font_get_style_name(const RID &p_font_rid) const {
return fd->style_name;
}
-void TextServerFallback::font_set_name(const RID &p_font_rid, const String &p_name) {
+void TextServerFallback::_font_set_name(const RID &p_font_rid, const String &p_name) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1091,7 +1105,7 @@ void TextServerFallback::font_set_name(const RID &p_font_rid, const String &p_na
fd->font_name = p_name;
}
-String TextServerFallback::font_get_name(const RID &p_font_rid) const {
+String TextServerFallback::_font_get_name(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
@@ -1101,7 +1115,7 @@ String TextServerFallback::font_get_name(const RID &p_font_rid) const {
return fd->font_name;
}
-void TextServerFallback::font_set_antialiasing(RID p_font_rid, TextServer::FontAntialiasing p_antialiasing) {
+void TextServerFallback::_font_set_antialiasing(const RID &p_font_rid, TextServer::FontAntialiasing p_antialiasing) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1112,7 +1126,7 @@ void TextServerFallback::font_set_antialiasing(RID p_font_rid, TextServer::FontA
}
}
-TextServer::FontAntialiasing TextServerFallback::font_get_antialiasing(RID p_font_rid) const {
+TextServer::FontAntialiasing TextServerFallback::_font_get_antialiasing(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, TextServer::FONT_ANTIALIASING_NONE);
@@ -1120,7 +1134,7 @@ TextServer::FontAntialiasing TextServerFallback::font_get_antialiasing(RID p_fon
return fd->antialiasing;
}
-void TextServerFallback::font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) {
+void TextServerFallback::_font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1129,13 +1143,14 @@ void TextServerFallback::font_set_generate_mipmaps(const RID &p_font_rid, bool p
for (KeyValue<Vector2i, FontForSizeFallback *> &E : fd->cache) {
for (int i = 0; i < E.value->textures.size(); i++) {
E.value->textures.write[i].dirty = true;
+ E.value->textures.write[i].texture = Ref<ImageTexture>();
}
}
fd->mipmaps = p_generate_mipmaps;
}
}
-bool TextServerFallback::font_get_generate_mipmaps(const RID &p_font_rid) const {
+bool TextServerFallback::_font_get_generate_mipmaps(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -1143,7 +1158,7 @@ bool TextServerFallback::font_get_generate_mipmaps(const RID &p_font_rid) const
return fd->mipmaps;
}
-void TextServerFallback::font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) {
+void TextServerFallback::_font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1154,7 +1169,7 @@ void TextServerFallback::font_set_multichannel_signed_distance_field(const RID &
}
}
-bool TextServerFallback::font_is_multichannel_signed_distance_field(const RID &p_font_rid) const {
+bool TextServerFallback::_font_is_multichannel_signed_distance_field(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -1162,7 +1177,7 @@ bool TextServerFallback::font_is_multichannel_signed_distance_field(const RID &p
return fd->msdf;
}
-void TextServerFallback::font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) {
+void TextServerFallback::_font_set_msdf_pixel_range(const RID &p_font_rid, int64_t p_msdf_pixel_range) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1173,7 +1188,7 @@ void TextServerFallback::font_set_msdf_pixel_range(const RID &p_font_rid, int64_
}
}
-int64_t TextServerFallback::font_get_msdf_pixel_range(const RID &p_font_rid) const {
+int64_t TextServerFallback::_font_get_msdf_pixel_range(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -1181,7 +1196,7 @@ int64_t TextServerFallback::font_get_msdf_pixel_range(const RID &p_font_rid) con
return fd->msdf_range;
}
-void TextServerFallback::font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) {
+void TextServerFallback::_font_set_msdf_size(const RID &p_font_rid, int64_t p_msdf_size) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1192,7 +1207,7 @@ void TextServerFallback::font_set_msdf_size(const RID &p_font_rid, int64_t p_msd
}
}
-int64_t TextServerFallback::font_get_msdf_size(const RID &p_font_rid) const {
+int64_t TextServerFallback::_font_get_msdf_size(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -1200,7 +1215,7 @@ int64_t TextServerFallback::font_get_msdf_size(const RID &p_font_rid) const {
return fd->msdf_source_size;
}
-void TextServerFallback::font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) {
+void TextServerFallback::_font_set_fixed_size(const RID &p_font_rid, int64_t p_fixed_size) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1208,7 +1223,7 @@ void TextServerFallback::font_set_fixed_size(const RID &p_font_rid, int64_t p_fi
fd->fixed_size = p_fixed_size;
}
-int64_t TextServerFallback::font_get_fixed_size(const RID &p_font_rid) const {
+int64_t TextServerFallback::_font_get_fixed_size(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -1216,7 +1231,7 @@ int64_t TextServerFallback::font_get_fixed_size(const RID &p_font_rid) const {
return fd->fixed_size;
}
-void TextServerFallback::font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) {
+void TextServerFallback::_font_set_force_autohinter(const RID &p_font_rid, bool p_force_autohinter) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1227,7 +1242,7 @@ void TextServerFallback::font_set_force_autohinter(const RID &p_font_rid, bool p
}
}
-bool TextServerFallback::font_is_force_autohinter(const RID &p_font_rid) const {
+bool TextServerFallback::_font_is_force_autohinter(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -1235,7 +1250,7 @@ bool TextServerFallback::font_is_force_autohinter(const RID &p_font_rid) const {
return fd->force_autohinter;
}
-void TextServerFallback::font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) {
+void TextServerFallback::_font_set_hinting(const RID &p_font_rid, TextServer::Hinting p_hinting) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1246,7 +1261,7 @@ void TextServerFallback::font_set_hinting(const RID &p_font_rid, TextServer::Hin
}
}
-TextServer::Hinting TextServerFallback::font_get_hinting(const RID &p_font_rid) const {
+TextServer::Hinting TextServerFallback::_font_get_hinting(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, HINTING_NONE);
@@ -1254,7 +1269,7 @@ TextServer::Hinting TextServerFallback::font_get_hinting(const RID &p_font_rid)
return fd->hinting;
}
-void TextServerFallback::font_set_subpixel_positioning(const RID &p_font_rid, TextServer::SubpixelPositioning p_subpixel) {
+void TextServerFallback::_font_set_subpixel_positioning(const RID &p_font_rid, TextServer::SubpixelPositioning p_subpixel) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1262,7 +1277,7 @@ void TextServerFallback::font_set_subpixel_positioning(const RID &p_font_rid, Te
fd->subpixel_positioning = p_subpixel;
}
-TextServer::SubpixelPositioning TextServerFallback::font_get_subpixel_positioning(const RID &p_font_rid) const {
+TextServer::SubpixelPositioning TextServerFallback::_font_get_subpixel_positioning(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, SUBPIXEL_POSITIONING_DISABLED);
@@ -1270,7 +1285,7 @@ TextServer::SubpixelPositioning TextServerFallback::font_get_subpixel_positionin
return fd->subpixel_positioning;
}
-void TextServerFallback::font_set_embolden(const RID &p_font_rid, double p_strength) {
+void TextServerFallback::_font_set_embolden(const RID &p_font_rid, double p_strength) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1281,7 +1296,7 @@ void TextServerFallback::font_set_embolden(const RID &p_font_rid, double p_stren
}
}
-double TextServerFallback::font_get_embolden(const RID &p_font_rid) const {
+double TextServerFallback::_font_get_embolden(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -1289,7 +1304,7 @@ double TextServerFallback::font_get_embolden(const RID &p_font_rid) const {
return fd->embolden;
}
-void TextServerFallback::font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) {
+void TextServerFallback::_font_set_transform(const RID &p_font_rid, const Transform2D &p_transform) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1300,7 +1315,7 @@ void TextServerFallback::font_set_transform(const RID &p_font_rid, const Transfo
}
}
-Transform2D TextServerFallback::font_get_transform(const RID &p_font_rid) const {
+Transform2D TextServerFallback::_font_get_transform(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Transform2D());
@@ -1308,7 +1323,7 @@ Transform2D TextServerFallback::font_get_transform(const RID &p_font_rid) const
return fd->transform;
}
-void TextServerFallback::font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) {
+void TextServerFallback::_font_set_variation_coordinates(const RID &p_font_rid, const Dictionary &p_variation_coordinates) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1319,7 +1334,7 @@ void TextServerFallback::font_set_variation_coordinates(const RID &p_font_rid, c
}
}
-Dictionary TextServerFallback::font_get_variation_coordinates(const RID &p_font_rid) const {
+Dictionary TextServerFallback::_font_get_variation_coordinates(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -1327,7 +1342,7 @@ Dictionary TextServerFallback::font_get_variation_coordinates(const RID &p_font_
return fd->variation_coordinates;
}
-void TextServerFallback::font_set_oversampling(const RID &p_font_rid, double p_oversampling) {
+void TextServerFallback::_font_set_oversampling(const RID &p_font_rid, double p_oversampling) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1338,7 +1353,7 @@ void TextServerFallback::font_set_oversampling(const RID &p_font_rid, double p_o
}
}
-double TextServerFallback::font_get_oversampling(const RID &p_font_rid) const {
+double TextServerFallback::_font_get_oversampling(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -1346,7 +1361,7 @@ double TextServerFallback::font_get_oversampling(const RID &p_font_rid) const {
return fd->oversampling;
}
-TypedArray<Vector2i> TextServerFallback::font_get_size_cache_list(const RID &p_font_rid) const {
+TypedArray<Vector2i> TextServerFallback::_font_get_size_cache_list(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, TypedArray<Vector2i>());
@@ -1358,7 +1373,7 @@ TypedArray<Vector2i> TextServerFallback::font_get_size_cache_list(const RID &p_f
return ret;
}
-void TextServerFallback::font_clear_size_cache(const RID &p_font_rid) {
+void TextServerFallback::_font_clear_size_cache(const RID &p_font_rid) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1369,7 +1384,7 @@ void TextServerFallback::font_clear_size_cache(const RID &p_font_rid) {
fd->cache.clear();
}
-void TextServerFallback::font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) {
+void TextServerFallback::_font_remove_size_cache(const RID &p_font_rid, const Vector2i &p_size) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1380,7 +1395,7 @@ void TextServerFallback::font_remove_size_cache(const RID &p_font_rid, const Vec
}
}
-void TextServerFallback::font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) {
+void TextServerFallback::_font_set_ascent(const RID &p_font_rid, int64_t p_size, double p_ascent) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1391,7 +1406,7 @@ void TextServerFallback::font_set_ascent(const RID &p_font_rid, int64_t p_size,
fd->cache[size]->ascent = p_ascent;
}
-double TextServerFallback::font_get_ascent(const RID &p_font_rid, int64_t p_size) const {
+double TextServerFallback::_font_get_ascent(const RID &p_font_rid, int64_t p_size) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -1407,7 +1422,7 @@ double TextServerFallback::font_get_ascent(const RID &p_font_rid, int64_t p_size
}
}
-void TextServerFallback::font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) {
+void TextServerFallback::_font_set_descent(const RID &p_font_rid, int64_t p_size, double p_descent) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1417,7 +1432,7 @@ void TextServerFallback::font_set_descent(const RID &p_font_rid, int64_t p_size,
fd->cache[size]->descent = p_descent;
}
-double TextServerFallback::font_get_descent(const RID &p_font_rid, int64_t p_size) const {
+double TextServerFallback::_font_get_descent(const RID &p_font_rid, int64_t p_size) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -1433,7 +1448,7 @@ double TextServerFallback::font_get_descent(const RID &p_font_rid, int64_t p_siz
}
}
-void TextServerFallback::font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) {
+void TextServerFallback::_font_set_underline_position(const RID &p_font_rid, int64_t p_size, double p_underline_position) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1444,7 +1459,7 @@ void TextServerFallback::font_set_underline_position(const RID &p_font_rid, int6
fd->cache[size]->underline_position = p_underline_position;
}
-double TextServerFallback::font_get_underline_position(const RID &p_font_rid, int64_t p_size) const {
+double TextServerFallback::_font_get_underline_position(const RID &p_font_rid, int64_t p_size) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -1460,7 +1475,7 @@ double TextServerFallback::font_get_underline_position(const RID &p_font_rid, in
}
}
-void TextServerFallback::font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) {
+void TextServerFallback::_font_set_underline_thickness(const RID &p_font_rid, int64_t p_size, double p_underline_thickness) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1471,7 +1486,7 @@ void TextServerFallback::font_set_underline_thickness(const RID &p_font_rid, int
fd->cache[size]->underline_thickness = p_underline_thickness;
}
-double TextServerFallback::font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const {
+double TextServerFallback::_font_get_underline_thickness(const RID &p_font_rid, int64_t p_size) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -1487,7 +1502,7 @@ double TextServerFallback::font_get_underline_thickness(const RID &p_font_rid, i
}
}
-void TextServerFallback::font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) {
+void TextServerFallback::_font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1503,7 +1518,7 @@ void TextServerFallback::font_set_scale(const RID &p_font_rid, int64_t p_size, d
fd->cache[size]->scale = p_scale;
}
-double TextServerFallback::font_get_scale(const RID &p_font_rid, int64_t p_size) const {
+double TextServerFallback::_font_get_scale(const RID &p_font_rid, int64_t p_size) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0.0);
@@ -1519,7 +1534,7 @@ double TextServerFallback::font_get_scale(const RID &p_font_rid, int64_t p_size)
}
}
-int64_t TextServerFallback::font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const {
+int64_t TextServerFallback::_font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, 0);
@@ -1531,7 +1546,7 @@ int64_t TextServerFallback::font_get_texture_count(const RID &p_font_rid, const
return fd->cache[size]->textures.size();
}
-void TextServerFallback::font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) {
+void TextServerFallback::_font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
@@ -1541,7 +1556,7 @@ void TextServerFallback::font_clear_textures(const RID &p_font_rid, const Vector
fd->cache[size]->textures.clear();
}
-void TextServerFallback::font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) {
+void TextServerFallback::_font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1553,7 +1568,7 @@ void TextServerFallback::font_remove_texture(const RID &p_font_rid, const Vector
fd->cache[size]->textures.remove_at(p_texture_index);
}
-void TextServerFallback::font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) {
+void TextServerFallback::_font_set_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const Ref<Image> &p_image) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
ERR_FAIL_COND(p_image.is_null());
@@ -1584,7 +1599,7 @@ void TextServerFallback::font_set_texture_image(const RID &p_font_rid, const Vec
tex.dirty = false;
}
-Ref<Image> TextServerFallback::font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
+Ref<Image> TextServerFallback::_font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Ref<Image>());
@@ -1601,7 +1616,7 @@ Ref<Image> TextServerFallback::font_get_texture_image(const RID &p_font_rid, con
return img;
}
-void TextServerFallback::font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) {
+void TextServerFallback::_font_set_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index, const PackedInt32Array &p_offset) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1617,7 +1632,7 @@ void TextServerFallback::font_set_texture_offsets(const RID &p_font_rid, const V
tex.offsets = p_offset;
}
-PackedInt32Array TextServerFallback::font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
+PackedInt32Array TextServerFallback::_font_get_texture_offsets(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedInt32Array());
@@ -1630,7 +1645,7 @@ PackedInt32Array TextServerFallback::font_get_texture_offsets(const RID &p_font_
return tex.offsets;
}
-PackedInt32Array TextServerFallback::font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const {
+PackedInt32Array TextServerFallback::_font_get_glyph_list(const RID &p_font_rid, const Vector2i &p_size) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedInt32Array());
@@ -1646,7 +1661,7 @@ PackedInt32Array TextServerFallback::font_get_glyph_list(const RID &p_font_rid,
return ret;
}
-void TextServerFallback::font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) {
+void TextServerFallback::_font_clear_glyphs(const RID &p_font_rid, const Vector2i &p_size) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1657,7 +1672,7 @@ void TextServerFallback::font_clear_glyphs(const RID &p_font_rid, const Vector2i
fd->cache[size]->glyph_map.clear();
}
-void TextServerFallback::font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) {
+void TextServerFallback::_font_remove_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1668,7 +1683,7 @@ void TextServerFallback::font_remove_glyph(const RID &p_font_rid, const Vector2i
fd->cache[size]->glyph_map.erase(p_glyph);
}
-Vector2 TextServerFallback::font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const {
+Vector2 TextServerFallback::_font_get_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
@@ -1679,7 +1694,7 @@ Vector2 TextServerFallback::font_get_glyph_advance(const RID &p_font_rid, int64_
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -1705,7 +1720,7 @@ Vector2 TextServerFallback::font_get_glyph_advance(const RID &p_font_rid, int64_
}
}
-void TextServerFallback::font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) {
+void TextServerFallback::_font_set_glyph_advance(const RID &p_font_rid, int64_t p_size, int64_t p_glyph, const Vector2 &p_advance) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1720,7 +1735,7 @@ void TextServerFallback::font_set_glyph_advance(const RID &p_font_rid, int64_t p
gl[p_glyph].found = true;
}
-Vector2 TextServerFallback::font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+Vector2 TextServerFallback::_font_get_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
@@ -1731,7 +1746,7 @@ Vector2 TextServerFallback::font_get_glyph_offset(const RID &p_font_rid, const V
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -1750,7 +1765,7 @@ Vector2 TextServerFallback::font_get_glyph_offset(const RID &p_font_rid, const V
}
}
-void TextServerFallback::font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) {
+void TextServerFallback::_font_set_glyph_offset(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_offset) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1765,7 +1780,7 @@ void TextServerFallback::font_set_glyph_offset(const RID &p_font_rid, const Vect
gl[p_glyph].found = true;
}
-Vector2 TextServerFallback::font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+Vector2 TextServerFallback::_font_get_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
@@ -1776,7 +1791,7 @@ Vector2 TextServerFallback::font_get_glyph_size(const RID &p_font_rid, const Vec
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -1795,7 +1810,7 @@ Vector2 TextServerFallback::font_get_glyph_size(const RID &p_font_rid, const Vec
}
}
-void TextServerFallback::font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) {
+void TextServerFallback::_font_set_glyph_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Vector2 &p_gl_size) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1810,7 +1825,7 @@ void TextServerFallback::font_set_glyph_size(const RID &p_font_rid, const Vector
gl[p_glyph].found = true;
}
-Rect2 TextServerFallback::font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+Rect2 TextServerFallback::_font_get_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Rect2());
@@ -1821,7 +1836,7 @@ Rect2 TextServerFallback::font_get_glyph_uv_rect(const RID &p_font_rid, const Ve
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -1835,7 +1850,7 @@ Rect2 TextServerFallback::font_get_glyph_uv_rect(const RID &p_font_rid, const Ve
return gl[p_glyph | mod].uv_rect;
}
-void TextServerFallback::font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) {
+void TextServerFallback::_font_set_glyph_uv_rect(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, const Rect2 &p_uv_rect) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1850,7 +1865,7 @@ void TextServerFallback::font_set_glyph_uv_rect(const RID &p_font_rid, const Vec
gl[p_glyph].found = true;
}
-int64_t TextServerFallback::font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+int64_t TextServerFallback::_font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, -1);
@@ -1861,7 +1876,7 @@ int64_t TextServerFallback::font_get_glyph_texture_idx(const RID &p_font_rid, co
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -1875,7 +1890,7 @@ int64_t TextServerFallback::font_get_glyph_texture_idx(const RID &p_font_rid, co
return gl[p_glyph | mod].texture_idx;
}
-void TextServerFallback::font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) {
+void TextServerFallback::_font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -1890,7 +1905,7 @@ void TextServerFallback::font_set_glyph_texture_idx(const RID &p_font_rid, const
gl[p_glyph].found = true;
}
-RID TextServerFallback::font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+RID TextServerFallback::_font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, RID());
@@ -1901,7 +1916,7 @@ RID TextServerFallback::font_get_glyph_texture_rid(const RID &p_font_rid, const
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -1938,7 +1953,7 @@ RID TextServerFallback::font_get_glyph_texture_rid(const RID &p_font_rid, const
return RID();
}
-Size2 TextServerFallback::font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
+Size2 TextServerFallback::_font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Size2());
@@ -1949,7 +1964,7 @@ Size2 TextServerFallback::font_get_glyph_texture_size(const RID &p_font_rid, con
int mod = 0;
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
mod = (layout << 24);
}
@@ -1986,7 +2001,7 @@ Size2 TextServerFallback::font_get_glyph_texture_size(const RID &p_font_rid, con
return Size2();
}
-Dictionary TextServerFallback::font_get_glyph_contours(const RID &p_font_rid, int64_t p_size, int64_t p_index) const {
+Dictionary TextServerFallback::_font_get_glyph_contours(const RID &p_font_rid, int64_t p_size, int64_t p_index) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -2036,7 +2051,7 @@ Dictionary TextServerFallback::font_get_glyph_contours(const RID &p_font_rid, in
#endif
}
-TypedArray<Vector2i> TextServerFallback::font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const {
+TypedArray<Vector2i> TextServerFallback::_font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, TypedArray<Vector2i>());
@@ -2052,7 +2067,7 @@ TypedArray<Vector2i> TextServerFallback::font_get_kerning_list(const RID &p_font
return ret;
}
-void TextServerFallback::font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) {
+void TextServerFallback::_font_clear_kerning_map(const RID &p_font_rid, int64_t p_size) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2063,7 +2078,7 @@ void TextServerFallback::font_clear_kerning_map(const RID &p_font_rid, int64_t p
fd->cache[size]->kerning_map.clear();
}
-void TextServerFallback::font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) {
+void TextServerFallback::_font_remove_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2074,7 +2089,7 @@ void TextServerFallback::font_remove_kerning(const RID &p_font_rid, int64_t p_si
fd->cache[size]->kerning_map.erase(p_glyph_pair);
}
-void TextServerFallback::font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) {
+void TextServerFallback::_font_set_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair, const Vector2 &p_kerning) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2085,7 +2100,7 @@ void TextServerFallback::font_set_kerning(const RID &p_font_rid, int64_t p_size,
fd->cache[size]->kerning_map[p_glyph_pair] = p_kerning;
}
-Vector2 TextServerFallback::font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const {
+Vector2 TextServerFallback::_font_get_kerning(const RID &p_font_rid, int64_t p_size, const Vector2i &p_glyph_pair) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Vector2());
@@ -2120,15 +2135,17 @@ Vector2 TextServerFallback::font_get_kerning(const RID &p_font_rid, int64_t p_si
return Vector2();
}
-int64_t TextServerFallback::font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector) const {
+int64_t TextServerFallback::_font_get_glyph_index(const RID &p_font_rid, int64_t p_size, int64_t p_char, int64_t p_variation_selector) const {
ERR_FAIL_COND_V_MSG((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff), 0, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_char, 16) + ".");
return (int64_t)p_char;
}
-bool TextServerFallback::font_has_char(const RID &p_font_rid, int64_t p_char) const {
+bool TextServerFallback::_font_has_char(const RID &p_font_rid, int64_t p_char) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
- ERR_FAIL_COND_V(!fd, false);
ERR_FAIL_COND_V_MSG((p_char >= 0xd800 && p_char <= 0xdfff) || (p_char > 0x10ffff), false, "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_char, 16) + ".");
+ if (!fd) {
+ return false;
+ }
MutexLock lock(fd->mutex);
if (fd->cache.is_empty()) {
@@ -2144,7 +2161,7 @@ bool TextServerFallback::font_has_char(const RID &p_font_rid, int64_t p_char) co
return (at_size) ? at_size->glyph_map.has((int32_t)p_char) : false;
}
-String TextServerFallback::font_get_supported_chars(const RID &p_font_rid) const {
+String TextServerFallback::_font_get_supported_chars(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, String());
@@ -2177,7 +2194,7 @@ String TextServerFallback::font_get_supported_chars(const RID &p_font_rid) const
return chars;
}
-void TextServerFallback::font_render_range(const RID &p_font_rid, const Vector2i &p_size, int64_t p_start, int64_t p_end) {
+void TextServerFallback::_font_render_range(const RID &p_font_rid, const Vector2i &p_size, int64_t p_start, int64_t p_end) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
ERR_FAIL_COND_MSG((p_start >= 0xd800 && p_start <= 0xdfff) || (p_start > 0x10ffff), "Unicode parsing error: Invalid unicode codepoint " + String::num_int64(p_start, 16) + ".");
@@ -2212,7 +2229,7 @@ void TextServerFallback::font_render_range(const RID &p_font_rid, const Vector2i
}
}
-void TextServerFallback::font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) {
+void TextServerFallback::_font_render_glyph(const RID &p_font_rid, const Vector2i &p_size, int64_t p_index) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2243,7 +2260,7 @@ void TextServerFallback::font_render_glyph(const RID &p_font_rid, const Vector2i
#endif
}
-void TextServerFallback::font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
+void TextServerFallback::_font_draw_glyph(const RID &p_font_rid, const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, int64_t p_index, const Color &p_color) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2258,7 +2275,7 @@ void TextServerFallback::font_draw_glyph(const RID &p_font_rid, const RID &p_can
if (!fd->msdf && fd->cache[size]->face) {
// LCD layout, bits 24, 25, 26
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
lcd_aa = true;
index = index | (layout << 24);
@@ -2335,7 +2352,7 @@ void TextServerFallback::font_draw_glyph(const RID &p_font_rid, const RID &p_can
}
}
-void TextServerFallback::font_draw_glyph_outline(const RID &p_font_rid, 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) const {
+void TextServerFallback::_font_draw_glyph_outline(const RID &p_font_rid, 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) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2350,7 +2367,7 @@ void TextServerFallback::font_draw_glyph_outline(const RID &p_font_rid, const RI
if (!fd->msdf && fd->cache[size]->face) {
// LCD layout, bits 24, 25, 26
if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
- TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)ProjectSettings::get_singleton()->get("gui/theme/lcd_subpixel_layout");
if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
lcd_aa = true;
index = index | (layout << 24);
@@ -2427,7 +2444,7 @@ void TextServerFallback::font_draw_glyph_outline(const RID &p_font_rid, const RI
}
}
-bool TextServerFallback::font_is_language_supported(const RID &p_font_rid, const String &p_language) const {
+bool TextServerFallback::_font_is_language_supported(const RID &p_font_rid, const String &p_language) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2439,7 +2456,7 @@ bool TextServerFallback::font_is_language_supported(const RID &p_font_rid, const
}
}
-void TextServerFallback::font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) {
+void TextServerFallback::_font_set_language_support_override(const RID &p_font_rid, const String &p_language, bool p_supported) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2447,7 +2464,7 @@ void TextServerFallback::font_set_language_support_override(const RID &p_font_ri
fd->language_support_overrides[p_language] = p_supported;
}
-bool TextServerFallback::font_get_language_support_override(const RID &p_font_rid, const String &p_language) {
+bool TextServerFallback::_font_get_language_support_override(const RID &p_font_rid, const String &p_language) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2455,7 +2472,7 @@ bool TextServerFallback::font_get_language_support_override(const RID &p_font_ri
return fd->language_support_overrides[p_language];
}
-void TextServerFallback::font_remove_language_support_override(const RID &p_font_rid, const String &p_language) {
+void TextServerFallback::_font_remove_language_support_override(const RID &p_font_rid, const String &p_language) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2463,7 +2480,7 @@ void TextServerFallback::font_remove_language_support_override(const RID &p_font
fd->language_support_overrides.erase(p_language);
}
-PackedStringArray TextServerFallback::font_get_language_support_overrides(const RID &p_font_rid) {
+PackedStringArray TextServerFallback::_font_get_language_support_overrides(const RID &p_font_rid) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedStringArray());
@@ -2475,7 +2492,7 @@ PackedStringArray TextServerFallback::font_get_language_support_overrides(const
return out;
}
-bool TextServerFallback::font_is_script_supported(const RID &p_font_rid, const String &p_script) const {
+bool TextServerFallback::_font_is_script_supported(const RID &p_font_rid, const String &p_script) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2487,7 +2504,7 @@ bool TextServerFallback::font_is_script_supported(const RID &p_font_rid, const S
}
}
-void TextServerFallback::font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) {
+void TextServerFallback::_font_set_script_support_override(const RID &p_font_rid, const String &p_script, bool p_supported) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2495,7 +2512,7 @@ void TextServerFallback::font_set_script_support_override(const RID &p_font_rid,
fd->script_support_overrides[p_script] = p_supported;
}
-bool TextServerFallback::font_get_script_support_override(const RID &p_font_rid, const String &p_script) {
+bool TextServerFallback::_font_get_script_support_override(const RID &p_font_rid, const String &p_script) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, false);
@@ -2503,7 +2520,7 @@ bool TextServerFallback::font_get_script_support_override(const RID &p_font_rid,
return fd->script_support_overrides[p_script];
}
-void TextServerFallback::font_remove_script_support_override(const RID &p_font_rid, const String &p_script) {
+void TextServerFallback::_font_remove_script_support_override(const RID &p_font_rid, const String &p_script) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2513,7 +2530,7 @@ void TextServerFallback::font_remove_script_support_override(const RID &p_font_r
fd->script_support_overrides.erase(p_script);
}
-PackedStringArray TextServerFallback::font_get_script_support_overrides(const RID &p_font_rid) {
+PackedStringArray TextServerFallback::_font_get_script_support_overrides(const RID &p_font_rid) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, PackedStringArray());
@@ -2525,7 +2542,7 @@ PackedStringArray TextServerFallback::font_get_script_support_overrides(const RI
return out;
}
-void TextServerFallback::font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) {
+void TextServerFallback::_font_set_opentype_feature_overrides(const RID &p_font_rid, const Dictionary &p_overrides) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
@@ -2535,7 +2552,7 @@ void TextServerFallback::font_set_opentype_feature_overrides(const RID &p_font_r
fd->feature_overrides = p_overrides;
}
-Dictionary TextServerFallback::font_get_opentype_feature_overrides(const RID &p_font_rid) const {
+Dictionary TextServerFallback::_font_get_opentype_feature_overrides(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -2543,11 +2560,11 @@ Dictionary TextServerFallback::font_get_opentype_feature_overrides(const RID &p_
return fd->feature_overrides;
}
-Dictionary TextServerFallback::font_supported_feature_list(const RID &p_font_rid) const {
+Dictionary TextServerFallback::_font_supported_feature_list(const RID &p_font_rid) const {
return Dictionary();
}
-Dictionary TextServerFallback::font_supported_variation_list(const RID &p_font_rid) const {
+Dictionary TextServerFallback::_font_supported_variation_list(const RID &p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND_V(!fd, Dictionary());
@@ -2557,11 +2574,11 @@ Dictionary TextServerFallback::font_supported_variation_list(const RID &p_font_r
return fd->supported_varaitions;
}
-double TextServerFallback::font_get_global_oversampling() const {
+double TextServerFallback::_font_get_global_oversampling() const {
return oversampling;
}
-void TextServerFallback::font_set_global_oversampling(double p_oversampling) {
+void TextServerFallback::_font_set_global_oversampling(double p_oversampling) {
_THREAD_SAFE_METHOD_
if (oversampling != p_oversampling) {
oversampling = p_oversampling;
@@ -2569,8 +2586,8 @@ void TextServerFallback::font_set_global_oversampling(double p_oversampling) {
font_owner.get_owned_list(&fonts);
bool font_cleared = false;
for (const RID &E : fonts) {
- if (!font_is_multichannel_signed_distance_field(E) && font_get_oversampling(E) <= 0) {
- font_clear_size_cache(E);
+ if (!_font_is_multichannel_signed_distance_field(E) && _font_get_oversampling(E) <= 0) {
+ _font_clear_size_cache(E);
font_cleared = true;
}
}
@@ -2625,7 +2642,7 @@ void TextServerFallback::full_copy(ShapedTextDataFallback *p_shaped) {
p_shaped->parent = RID();
}
-RID TextServerFallback::create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
+RID TextServerFallback::_create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
_THREAD_SAFE_METHOD_
ShapedTextDataFallback *sd = memnew(ShapedTextDataFallback);
@@ -2635,7 +2652,7 @@ RID TextServerFallback::create_shaped_text(TextServer::Direction p_direction, Te
return shaped_owner.make_rid(sd);
}
-void TextServerFallback::shaped_text_clear(const RID &p_shaped) {
+void TextServerFallback::_shaped_text_clear(const RID &p_shaped) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -2649,21 +2666,21 @@ void TextServerFallback::shaped_text_clear(const RID &p_shaped) {
invalidate(sd);
}
-void TextServerFallback::shaped_text_set_direction(const RID &p_shaped, TextServer::Direction p_direction) {
+void TextServerFallback::_shaped_text_set_direction(const RID &p_shaped, TextServer::Direction p_direction) {
if (p_direction == DIRECTION_RTL) {
ERR_PRINT_ONCE("Right-to-left layout is not supported by this text server.");
}
}
-TextServer::Direction TextServerFallback::shaped_text_get_direction(const RID &p_shaped) const {
+TextServer::Direction TextServerFallback::_shaped_text_get_direction(const RID &p_shaped) const {
return TextServer::DIRECTION_LTR;
}
-TextServer::Direction TextServerFallback::shaped_text_get_inferred_direction(const RID &p_shaped) const {
+TextServer::Direction TextServerFallback::_shaped_text_get_inferred_direction(const RID &p_shaped) const {
return TextServer::DIRECTION_LTR;
}
-void TextServerFallback::shaped_text_set_custom_punctuation(const RID &p_shaped, const String &p_punct) {
+void TextServerFallback::_shaped_text_set_custom_punctuation(const RID &p_shaped, const String &p_punct) {
_THREAD_SAFE_METHOD_
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -2677,14 +2694,14 @@ void TextServerFallback::shaped_text_set_custom_punctuation(const RID &p_shaped,
}
}
-String TextServerFallback::shaped_text_get_custom_punctuation(const RID &p_shaped) const {
+String TextServerFallback::_shaped_text_get_custom_punctuation(const RID &p_shaped) const {
_THREAD_SAFE_METHOD_
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, String());
return sd->custom_punct;
}
-void TextServerFallback::shaped_text_set_orientation(const RID &p_shaped, TextServer::Orientation p_orientation) {
+void TextServerFallback::_shaped_text_set_orientation(const RID &p_shaped, TextServer::Orientation p_orientation) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -2698,11 +2715,11 @@ void TextServerFallback::shaped_text_set_orientation(const RID &p_shaped, TextSe
}
}
-void TextServerFallback::shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) {
+void TextServerFallback::_shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) {
// No BiDi support, ignore.
}
-TextServer::Orientation TextServerFallback::shaped_text_get_orientation(const RID &p_shaped) const {
+TextServer::Orientation TextServerFallback::_shaped_text_get_orientation(const RID &p_shaped) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, TextServer::ORIENTATION_HORIZONTAL);
@@ -2710,7 +2727,7 @@ TextServer::Orientation TextServerFallback::shaped_text_get_orientation(const RI
return sd->orientation;
}
-void TextServerFallback::shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) {
+void TextServerFallback::_shaped_text_set_preserve_invalid(const RID &p_shaped, bool p_enabled) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
MutexLock lock(sd->mutex);
@@ -2724,7 +2741,7 @@ void TextServerFallback::shaped_text_set_preserve_invalid(const RID &p_shaped, b
}
}
-bool TextServerFallback::shaped_text_get_preserve_invalid(const RID &p_shaped) const {
+bool TextServerFallback::_shaped_text_get_preserve_invalid(const RID &p_shaped) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -2732,7 +2749,7 @@ bool TextServerFallback::shaped_text_get_preserve_invalid(const RID &p_shaped) c
return sd->preserve_invalid;
}
-void TextServerFallback::shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) {
+void TextServerFallback::_shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -2746,7 +2763,7 @@ void TextServerFallback::shaped_text_set_preserve_control(const RID &p_shaped, b
}
}
-bool TextServerFallback::shaped_text_get_preserve_control(const RID &p_shaped) const {
+bool TextServerFallback::_shaped_text_get_preserve_control(const RID &p_shaped) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -2754,7 +2771,7 @@ bool TextServerFallback::shaped_text_get_preserve_control(const RID &p_shaped) c
return sd->preserve_control;
}
-void TextServerFallback::shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) {
+void TextServerFallback::_shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) {
ERR_FAIL_INDEX((int)p_spacing, 4);
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
@@ -2769,7 +2786,7 @@ void TextServerFallback::shaped_text_set_spacing(const RID &p_shaped, SpacingTyp
}
}
-int64_t TextServerFallback::shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const {
+int64_t TextServerFallback::_shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const {
ERR_FAIL_INDEX_V((int)p_spacing, 4, 0);
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
@@ -2779,20 +2796,20 @@ int64_t TextServerFallback::shaped_text_get_spacing(const RID &p_shaped, Spacing
return sd->extra_spacing[p_spacing];
}
-int64_t TextServerFallback::shaped_get_span_count(const RID &p_shaped) const {
+int64_t TextServerFallback::_shaped_get_span_count(const RID &p_shaped) const {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0);
return sd->spans.size();
}
-Variant TextServerFallback::shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const {
+Variant TextServerFallback::_shaped_get_span_meta(const RID &p_shaped, int64_t p_index) const {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Variant());
ERR_FAIL_INDEX_V(p_index, sd->spans.size(), Variant());
return sd->spans[p_index].meta;
}
-void TextServerFallback::shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) {
+void TextServerFallback::_shaped_set_span_update_font(const RID &p_shaped, int64_t p_index, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
ERR_FAIL_INDEX(p_index, sd->spans.size());
@@ -2803,7 +2820,7 @@ void TextServerFallback::shaped_set_span_update_font(const RID &p_shaped, int64_
Array fonts_no_match;
int font_count = p_fonts.size();
for (int i = 0; i < font_count; i++) {
- if (font_is_language_supported(p_fonts[i], span.language)) {
+ if (_font_is_language_supported(p_fonts[i], span.language)) {
span.fonts.push_back(p_fonts[i]);
} else {
fonts_no_match.push_back(p_fonts[i]);
@@ -2816,7 +2833,7 @@ void TextServerFallback::shaped_set_span_update_font(const RID &p_shaped, int64_
sd->valid = false;
}
-bool TextServerFallback::shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
+bool TextServerFallback::_shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -2842,8 +2859,11 @@ bool TextServerFallback::shaped_text_add_string(const RID &p_shaped, const Strin
// Pre-sort fonts, push fonts with the language support first.
Array fonts_no_match;
int font_count = p_fonts.size();
- for (int i = 0; i < font_count; i++) {
- if (font_is_language_supported(p_fonts[i], p_language)) {
+ if (font_count > 0) {
+ span.fonts.push_back(p_fonts[0]);
+ }
+ for (int i = 1; i < font_count; i++) {
+ if (_font_is_language_supported(p_fonts[i], p_language)) {
span.fonts.push_back(p_fonts[i]);
} else {
fonts_no_match.push_back(p_fonts[i]);
@@ -2864,7 +2884,7 @@ bool TextServerFallback::shaped_text_add_string(const RID &p_shaped, const Strin
return true;
}
-bool TextServerFallback::shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, int64_t p_length) {
+bool TextServerFallback::_shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align, int64_t p_length) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -2895,7 +2915,7 @@ bool TextServerFallback::shaped_text_add_object(const RID &p_shaped, const Varia
return true;
}
-bool TextServerFallback::shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
+bool TextServerFallback::_shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -2936,14 +2956,14 @@ bool TextServerFallback::shaped_text_resize_object(const RID &p_shaped, const Va
} else {
if (gl.font_rid.is_valid()) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- sd->ascent = MAX(sd->ascent, font_get_ascent(gl.font_rid, gl.font_size));
- sd->descent = MAX(sd->descent, font_get_descent(gl.font_rid, gl.font_size));
+ sd->ascent = MAX(sd->ascent, _font_get_ascent(gl.font_rid, gl.font_size));
+ sd->descent = MAX(sd->descent, _font_get_descent(gl.font_rid, gl.font_size));
} else {
- sd->ascent = MAX(sd->ascent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
- sd->descent = MAX(sd->descent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
+ sd->ascent = MAX(sd->ascent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
+ sd->descent = MAX(sd->descent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
}
- sd->upos = MAX(sd->upos, font_get_underline_position(gl.font_rid, gl.font_size));
- sd->uthk = MAX(sd->uthk, font_get_underline_thickness(gl.font_rid, gl.font_size));
+ sd->upos = MAX(sd->upos, _font_get_underline_position(gl.font_rid, gl.font_size));
+ sd->uthk = MAX(sd->uthk, _font_get_underline_thickness(gl.font_rid, gl.font_size));
} else if (sd->preserve_invalid || (sd->preserve_control && is_control(gl.index))) {
// Glyph not found, replace with hex code box.
if (sd->orientation == ORIENTATION_HORIZONTAL) {
@@ -3030,7 +3050,7 @@ void TextServerFallback::_realign(ShapedTextDataFallback *p_sd) const {
p_sd->descent = full_descent;
}
-RID TextServerFallback::shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const {
+RID TextServerFallback::_shaped_text_substr(const RID &p_shaped, int64_t p_start, int64_t p_length) const {
_THREAD_SAFE_METHOD_
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
@@ -3038,10 +3058,10 @@ RID TextServerFallback::shaped_text_substr(const RID &p_shaped, int64_t p_start,
MutexLock lock(sd->mutex);
if (sd->parent != RID()) {
- return shaped_text_substr(sd->parent, p_start, p_length);
+ return _shaped_text_substr(sd->parent, p_start, p_length);
}
if (!sd->valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_shape(p_shaped);
}
ERR_FAIL_COND_V(p_start < 0 || p_length < 0, RID());
ERR_FAIL_COND_V(sd->start > p_start || sd->end < p_start, RID());
@@ -3096,11 +3116,11 @@ RID TextServerFallback::shaped_text_substr(const RID &p_shaped, int64_t p_start,
} else {
if (gl.font_rid.is_valid()) {
if (new_sd->orientation == ORIENTATION_HORIZONTAL) {
- new_sd->ascent = MAX(new_sd->ascent, font_get_ascent(gl.font_rid, gl.font_size));
- new_sd->descent = MAX(new_sd->descent, font_get_descent(gl.font_rid, gl.font_size));
+ new_sd->ascent = MAX(new_sd->ascent, _font_get_ascent(gl.font_rid, gl.font_size));
+ new_sd->descent = MAX(new_sd->descent, _font_get_descent(gl.font_rid, gl.font_size));
} else {
- new_sd->ascent = MAX(new_sd->ascent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
- new_sd->descent = MAX(new_sd->descent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
+ new_sd->ascent = MAX(new_sd->ascent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
+ new_sd->descent = MAX(new_sd->descent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
}
} else if (new_sd->preserve_invalid || (new_sd->preserve_control && is_control(gl.index))) {
// Glyph not found, replace with hex code box.
@@ -3124,7 +3144,7 @@ RID TextServerFallback::shaped_text_substr(const RID &p_shaped, int64_t p_start,
return shaped_owner.make_rid(new_sd);
}
-RID TextServerFallback::shaped_text_get_parent(const RID &p_shaped) const {
+RID TextServerFallback::_shaped_text_get_parent(const RID &p_shaped) const {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, RID());
@@ -3132,16 +3152,16 @@ RID TextServerFallback::shaped_text_get_parent(const RID &p_shaped) const {
return sd->parent;
}
-double TextServerFallback::shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<JustificationFlag> p_jst_flags) {
+double TextServerFallback::_shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<JustificationFlag> p_jst_flags) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_shape(p_shaped);
}
if (!sd->justification_ops_valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_update_justification_ops(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_update_justification_ops(p_shaped);
}
int start_pos = 0;
@@ -3241,16 +3261,16 @@ double TextServerFallback::shaped_text_fit_to_width(const RID &p_shaped, double
return Math::ceil(justification_width);
}
-double TextServerFallback::shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) {
+double TextServerFallback::_shaped_text_tab_align(const RID &p_shaped, const PackedFloat32Array &p_tab_stops) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_shape(p_shaped);
}
if (!sd->line_breaks_valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_update_breaks(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_update_breaks(p_shaped);
}
for (int i = 0; i < p_tab_stops.size(); i++) {
@@ -3297,13 +3317,13 @@ double TextServerFallback::shaped_text_tab_align(const RID &p_shaped, const Pack
return 0.0;
}
-bool TextServerFallback::shaped_text_update_breaks(const RID &p_shaped) {
+bool TextServerFallback::_shaped_text_update_breaks(const RID &p_shaped) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- shaped_text_shape(p_shaped);
+ _shaped_text_shape(p_shaped);
}
if (sd->line_breaks_valid) {
@@ -3353,29 +3373,29 @@ bool TextServerFallback::shaped_text_update_breaks(const RID &p_shaped) {
return sd->line_breaks_valid;
}
-bool TextServerFallback::shaped_text_update_justification_ops(const RID &p_shaped) {
+bool TextServerFallback::_shaped_text_update_justification_ops(const RID &p_shaped) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- shaped_text_shape(p_shaped);
+ _shaped_text_shape(p_shaped);
}
if (!sd->line_breaks_valid) {
- shaped_text_update_breaks(p_shaped);
+ _shaped_text_update_breaks(p_shaped);
}
sd->justification_ops_valid = true; // Not supported by fallback server.
return true;
}
-void TextServerFallback::shaped_text_overrun_trim_to_width(const RID &p_shaped_line, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) {
+void TextServerFallback::_shaped_text_overrun_trim_to_width(const RID &p_shaped_line, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped_line);
ERR_FAIL_COND_MSG(!sd, "ShapedTextDataFallback invalid.");
MutexLock lock(sd->mutex);
if (!sd->valid) {
- shaped_text_shape(p_shaped_line);
+ _shaped_text_shape(p_shaped_line);
}
sd->text_trimmed = false;
@@ -3414,30 +3434,30 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(const RID &p_shaped_l
// Find usable fonts, if fonts from the last glyph do not have required chars.
RID dot_gl_font_rid = sd_glyphs[sd_size - 1].font_rid;
- if (!font_has_char(dot_gl_font_rid, '.')) {
+ if (!_font_has_char(dot_gl_font_rid, '.')) {
const Array &fonts = spans[spans.size() - 1].fonts;
for (int i = 0; i < fonts.size(); i++) {
- if (font_has_char(fonts[i], '.')) {
+ if (_font_has_char(fonts[i], '.')) {
dot_gl_font_rid = fonts[i];
break;
}
}
}
RID whitespace_gl_font_rid = sd_glyphs[sd_size - 1].font_rid;
- if (!font_has_char(whitespace_gl_font_rid, '.')) {
+ if (!_font_has_char(whitespace_gl_font_rid, '.')) {
const Array &fonts = spans[spans.size() - 1].fonts;
for (int i = 0; i < fonts.size(); i++) {
- if (font_has_char(fonts[i], ' ')) {
+ if (_font_has_char(fonts[i], ' ')) {
whitespace_gl_font_rid = fonts[i];
break;
}
}
}
- int32_t dot_gl_idx = dot_gl_font_rid.is_valid() ? font_get_glyph_index(dot_gl_font_rid, last_gl_font_size, '.') : -10;
- Vector2 dot_adv = dot_gl_font_rid.is_valid() ? font_get_glyph_advance(dot_gl_font_rid, last_gl_font_size, dot_gl_idx) : Vector2();
- int32_t whitespace_gl_idx = whitespace_gl_font_rid.is_valid() ? font_get_glyph_index(whitespace_gl_font_rid, last_gl_font_size, ' ') : -10;
- Vector2 whitespace_adv = whitespace_gl_font_rid.is_valid() ? font_get_glyph_advance(whitespace_gl_font_rid, last_gl_font_size, whitespace_gl_idx) : Vector2();
+ int32_t dot_gl_idx = dot_gl_font_rid.is_valid() ? _font_get_glyph_index(dot_gl_font_rid, last_gl_font_size, '.', 0) : -10;
+ Vector2 dot_adv = dot_gl_font_rid.is_valid() ? _font_get_glyph_advance(dot_gl_font_rid, last_gl_font_size, dot_gl_idx) : Vector2();
+ int32_t whitespace_gl_idx = whitespace_gl_font_rid.is_valid() ? _font_get_glyph_index(whitespace_gl_font_rid, last_gl_font_size, ' ', 0) : -10;
+ Vector2 whitespace_adv = whitespace_gl_font_rid.is_valid() ? _font_get_glyph_advance(whitespace_gl_font_rid, last_gl_font_size, whitespace_gl_idx) : Vector2();
int ellipsis_width = 0;
if (add_ellipsis && whitespace_gl_font_rid.is_valid()) {
@@ -3453,29 +3473,34 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(const RID &p_shaped_l
int last_valid_cut = 0;
bool found = false;
- for (int i = sd_size - 1; i != -1; i--) {
- width -= sd_glyphs[i].advance * sd_glyphs[i].repeat;
+ if (enforce_ellipsis && (width + ellipsis_width <= p_width)) {
+ trim_pos = -1;
+ ellipsis_pos = sd_size;
+ } else {
+ for (int i = sd_size - 1; i != -1; i--) {
+ width -= sd_glyphs[i].advance * sd_glyphs[i].repeat;
- if (sd_glyphs[i].count > 0) {
- bool above_min_char_threshold = (i >= ell_min_characters);
+ if (sd_glyphs[i].count > 0) {
+ bool above_min_char_threshold = (i >= ell_min_characters);
- if (width + (((above_min_char_threshold && add_ellipsis) || enforce_ellipsis) ? ellipsis_width : 0) <= p_width) {
- if (cut_per_word && above_min_char_threshold) {
- if ((sd_glyphs[i].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT) {
+ if (width + (((above_min_char_threshold && add_ellipsis) || enforce_ellipsis) ? ellipsis_width : 0) <= p_width) {
+ if (cut_per_word && above_min_char_threshold) {
+ if ((sd_glyphs[i].flags & GRAPHEME_IS_BREAK_SOFT) == GRAPHEME_IS_BREAK_SOFT) {
+ last_valid_cut = i;
+ found = true;
+ }
+ } else {
last_valid_cut = i;
found = true;
}
- } else {
- last_valid_cut = i;
- found = true;
- }
- if (found) {
- trim_pos = last_valid_cut;
+ if (found) {
+ trim_pos = last_valid_cut;
- if (add_ellipsis && (above_min_char_threshold || enforce_ellipsis) && width - ellipsis_width <= p_width) {
- ellipsis_pos = trim_pos;
+ if (add_ellipsis && (above_min_char_threshold || enforce_ellipsis) && width - ellipsis_width <= p_width) {
+ ellipsis_pos = trim_pos;
+ }
+ break;
}
- break;
}
}
}
@@ -3521,7 +3546,7 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(const RID &p_shaped_l
}
}
-int64_t TextServerFallback::shaped_text_get_trim_pos(const RID &p_shaped) const {
+int64_t TextServerFallback::_shaped_text_get_trim_pos(const RID &p_shaped) const {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextDataFallback invalid.");
@@ -3529,7 +3554,7 @@ int64_t TextServerFallback::shaped_text_get_trim_pos(const RID &p_shaped) const
return sd->overrun_trim_data.trim_pos;
}
-int64_t TextServerFallback::shaped_text_get_ellipsis_pos(const RID &p_shaped) const {
+int64_t TextServerFallback::_shaped_text_get_ellipsis_pos(const RID &p_shaped) const {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextDataFallback invalid.");
@@ -3537,7 +3562,7 @@ int64_t TextServerFallback::shaped_text_get_ellipsis_pos(const RID &p_shaped) co
return sd->overrun_trim_data.ellipsis_pos;
}
-const Glyph *TextServerFallback::shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const {
+const Glyph *TextServerFallback::_shaped_text_get_ellipsis_glyphs(const RID &p_shaped) const {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, nullptr, "ShapedTextDataFallback invalid.");
@@ -3545,7 +3570,7 @@ const Glyph *TextServerFallback::shaped_text_get_ellipsis_glyphs(const RID &p_sh
return sd->overrun_trim_data.ellipsis_glyph_buf.ptr();
}
-int64_t TextServerFallback::shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const {
+int64_t TextServerFallback::_shaped_text_get_ellipsis_glyph_count(const RID &p_shaped) const {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V_MSG(!sd, 0, "ShapedTextDataFallback invalid.");
@@ -3553,7 +3578,7 @@ int64_t TextServerFallback::shaped_text_get_ellipsis_glyph_count(const RID &p_sh
return sd->overrun_trim_data.ellipsis_glyph_buf.size();
}
-bool TextServerFallback::shaped_text_shape(const RID &p_shaped) {
+bool TextServerFallback::_shaped_text_shape(const RID &p_shaped) {
ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -3620,27 +3645,27 @@ bool TextServerFallback::shaped_text_shape(const RID &p_shaped) {
}
// Select first font which has character (font are already sorted by span language).
for (int k = 0; k < span.fonts.size(); k++) {
- if (font_has_char(span.fonts[k], gl.index)) {
+ if (_font_has_char(span.fonts[k], gl.index)) {
gl.font_rid = span.fonts[k];
break;
}
}
if (gl.font_rid.is_valid()) {
- bool subpos = (font_get_subpixel_positioning(gl.font_rid) == SUBPIXEL_POSITIONING_ONE_HALF) || (font_get_subpixel_positioning(gl.font_rid) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (font_get_subpixel_positioning(gl.font_rid) == SUBPIXEL_POSITIONING_AUTO && gl.font_size <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE);
+ bool subpos = (_font_get_subpixel_positioning(gl.font_rid) == SUBPIXEL_POSITIONING_ONE_HALF) || (_font_get_subpixel_positioning(gl.font_rid) == SUBPIXEL_POSITIONING_ONE_QUARTER) || (_font_get_subpixel_positioning(gl.font_rid) == SUBPIXEL_POSITIONING_AUTO && gl.font_size <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE);
if (sd->text[j - sd->start] != 0 && !is_linebreak(sd->text[j - sd->start])) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- gl.advance = Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x);
+ gl.advance = Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x);
gl.x_off = 0;
gl.y_off = 0;
- sd->ascent = MAX(sd->ascent, font_get_ascent(gl.font_rid, gl.font_size));
- sd->descent = MAX(sd->descent, font_get_descent(gl.font_rid, gl.font_size));
+ sd->ascent = MAX(sd->ascent, _font_get_ascent(gl.font_rid, gl.font_size));
+ sd->descent = MAX(sd->descent, _font_get_descent(gl.font_rid, gl.font_size));
} else {
- gl.advance = Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).y);
- gl.x_off = -Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5);
- gl.y_off = font_get_ascent(gl.font_rid, gl.font_size);
- sd->ascent = MAX(sd->ascent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
- sd->descent = MAX(sd->descent, Math::round(font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
+ gl.advance = Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).y);
+ gl.x_off = -Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5);
+ gl.y_off = _font_get_ascent(gl.font_rid, gl.font_size);
+ sd->ascent = MAX(sd->ascent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
+ sd->descent = MAX(sd->descent, Math::round(_font_get_glyph_advance(gl.font_rid, gl.font_size, gl.index).x * 0.5));
}
}
if (j < sd->end - 1) {
@@ -3651,17 +3676,17 @@ bool TextServerFallback::shaped_text_shape(const RID &p_shaped) {
gl.advance += sd->extra_spacing[SPACING_GLYPH];
}
}
- sd->upos = MAX(sd->upos, font_get_underline_position(gl.font_rid, gl.font_size));
- sd->uthk = MAX(sd->uthk, font_get_underline_thickness(gl.font_rid, gl.font_size));
+ sd->upos = MAX(sd->upos, _font_get_underline_position(gl.font_rid, gl.font_size));
+ sd->uthk = MAX(sd->uthk, _font_get_underline_thickness(gl.font_rid, gl.font_size));
// Add kerning to previous glyph.
if (sd->glyphs.size() > 0) {
Glyph &prev_gl = sd->glyphs.write[sd->glyphs.size() - 1];
if (prev_gl.font_rid == gl.font_rid && prev_gl.font_size == gl.font_size) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
- prev_gl.advance += font_get_kerning(gl.font_rid, gl.font_size, Vector2i(prev_gl.index, gl.index)).x;
+ prev_gl.advance += _font_get_kerning(gl.font_rid, gl.font_size, Vector2i(prev_gl.index, gl.index)).x;
} else {
- prev_gl.advance += font_get_kerning(gl.font_rid, gl.font_size, Vector2i(prev_gl.index, gl.index)).y;
+ prev_gl.advance += _font_get_kerning(gl.font_rid, gl.font_size, Vector2i(prev_gl.index, gl.index)).y;
}
}
}
@@ -3692,7 +3717,7 @@ bool TextServerFallback::shaped_text_shape(const RID &p_shaped) {
return sd->valid;
}
-bool TextServerFallback::shaped_text_is_ready(const RID &p_shaped) const {
+bool TextServerFallback::_shaped_text_is_ready(const RID &p_shaped) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
@@ -3700,41 +3725,41 @@ bool TextServerFallback::shaped_text_is_ready(const RID &p_shaped) const {
return sd->valid;
}
-const Glyph *TextServerFallback::shaped_text_get_glyphs(const RID &p_shaped) const {
+const Glyph *TextServerFallback::_shaped_text_get_glyphs(const RID &p_shaped) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, nullptr);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_shape(p_shaped);
}
return sd->glyphs.ptr();
}
-int64_t TextServerFallback::shaped_text_get_glyph_count(const RID &p_shaped) const {
+int64_t TextServerFallback::_shaped_text_get_glyph_count(const RID &p_shaped) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_shape(p_shaped);
}
return sd->glyphs.size();
}
-const Glyph *TextServerFallback::shaped_text_sort_logical(const RID &p_shaped) {
+const Glyph *TextServerFallback::_shaped_text_sort_logical(const RID &p_shaped) {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, nullptr);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_shape(p_shaped);
}
return sd->glyphs.ptr(); // Already in the logical order, return as is.
}
-Vector2i TextServerFallback::shaped_text_get_range(const RID &p_shaped) const {
+Vector2i TextServerFallback::_shaped_text_get_range(const RID &p_shaped) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Vector2i());
@@ -3742,7 +3767,7 @@ Vector2i TextServerFallback::shaped_text_get_range(const RID &p_shaped) const {
return Vector2(sd->start, sd->end);
}
-Array TextServerFallback::shaped_text_get_objects(const RID &p_shaped) const {
+Array TextServerFallback::_shaped_text_get_objects(const RID &p_shaped) const {
Array ret;
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, ret);
@@ -3755,25 +3780,25 @@ Array TextServerFallback::shaped_text_get_objects(const RID &p_shaped) const {
return ret;
}
-Rect2 TextServerFallback::shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const {
+Rect2 TextServerFallback::_shaped_text_get_object_rect(const RID &p_shaped, const Variant &p_key) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Rect2());
MutexLock lock(sd->mutex);
ERR_FAIL_COND_V(!sd->objects.has(p_key), Rect2());
if (!sd->valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_shape(p_shaped);
}
return sd->objects[p_key].rect;
}
-Size2 TextServerFallback::shaped_text_get_size(const RID &p_shaped) const {
+Size2 TextServerFallback::_shaped_text_get_size(const RID &p_shaped) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Size2());
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_shape(p_shaped);
}
if (sd->orientation == TextServer::ORIENTATION_HORIZONTAL) {
return Size2(sd->width, sd->ascent + sd->descent + sd->extra_spacing[SPACING_TOP] + sd->extra_spacing[SPACING_BOTTOM]).ceil();
@@ -3782,64 +3807,64 @@ Size2 TextServerFallback::shaped_text_get_size(const RID &p_shaped) const {
}
}
-double TextServerFallback::shaped_text_get_ascent(const RID &p_shaped) const {
+double TextServerFallback::_shaped_text_get_ascent(const RID &p_shaped) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_shape(p_shaped);
}
return sd->ascent + sd->extra_spacing[SPACING_TOP];
}
-double TextServerFallback::shaped_text_get_descent(const RID &p_shaped) const {
+double TextServerFallback::_shaped_text_get_descent(const RID &p_shaped) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_shape(p_shaped);
}
return sd->descent + sd->extra_spacing[SPACING_BOTTOM];
}
-double TextServerFallback::shaped_text_get_width(const RID &p_shaped) const {
+double TextServerFallback::_shaped_text_get_width(const RID &p_shaped) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_shape(p_shaped);
}
return Math::ceil(sd->width);
}
-double TextServerFallback::shaped_text_get_underline_position(const RID &p_shaped) const {
+double TextServerFallback::_shaped_text_get_underline_position(const RID &p_shaped) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_shape(p_shaped);
}
return sd->upos;
}
-double TextServerFallback::shaped_text_get_underline_thickness(const RID &p_shaped) const {
+double TextServerFallback::_shaped_text_get_underline_thickness(const RID &p_shaped) const {
const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.0);
MutexLock lock(sd->mutex);
if (!sd->valid) {
- const_cast<TextServerFallback *>(this)->shaped_text_shape(p_shaped);
+ const_cast<TextServerFallback *>(this)->_shaped_text_shape(p_shaped);
}
return sd->uthk;
}
-String TextServerFallback::string_to_upper(const String &p_string, const String &p_language) const {
+String TextServerFallback::_string_to_upper(const String &p_string, const String &p_language) const {
String upper = p_string;
for (int i = 0; i <= upper.length(); i++) {
@@ -3853,7 +3878,7 @@ String TextServerFallback::string_to_upper(const String &p_string, const String
return upper;
}
-String TextServerFallback::string_to_lower(const String &p_string, const String &p_language) const {
+String TextServerFallback::_string_to_lower(const String &p_string, const String &p_language) const {
String lower = p_string;
for (int i = 0; i <= lower.length(); i++) {
@@ -3867,7 +3892,7 @@ String TextServerFallback::string_to_lower(const String &p_string, const String
return lower;
}
-PackedInt32Array TextServerFallback::string_get_word_breaks(const String &p_string, const String &p_language) const {
+PackedInt32Array TextServerFallback::_string_get_word_breaks(const String &p_string, const String &p_language) const {
PackedInt32Array ret;
for (int i = 0; i < p_string.length(); i++) {
char32_t c = p_string[i];
diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h
index cbb2fb03f2..4aeec4f452 100644
--- a/modules/text_server_fb/text_server_fb.h
+++ b/modules/text_server_fb/text_server_fb.h
@@ -42,6 +42,7 @@
#include <godot_cpp/godot.hpp>
#include <godot_cpp/core/class_db.hpp>
+#include <godot_cpp/core/ext_wrappers.gen.inc>
#include <godot_cpp/core/mutex_lock.hpp>
#include <godot_cpp/variant/array.hpp>
@@ -52,6 +53,7 @@
#include <godot_cpp/variant/rect2.hpp>
#include <godot_cpp/variant/rid.hpp>
#include <godot_cpp/variant/string.hpp>
+#include <godot_cpp/variant/typed_array.hpp>
#include <godot_cpp/variant/vector2.hpp>
#include <godot_cpp/variant/vector2i.hpp>
@@ -79,6 +81,7 @@ using namespace godot;
#include "servers/text/text_server_extension.h"
+#include "core/extension/ext_wrappers.gen.inc"
#include "core/object/worker_thread_pool.h"
#include "core/templates/hash_map.h"
#include "core/templates/rid_owner.h"
@@ -337,251 +340,249 @@ protected:
void invalidate(ShapedTextDataFallback *p_shaped);
public:
- virtual bool has_feature(Feature p_feature) const override;
- virtual String get_name() const override;
- virtual int64_t get_features() const override;
+ MODBIND1RC(bool, has_feature, Feature);
+ MODBIND0RC(String, get_name);
+ MODBIND0RC(int64_t, get_features);
- 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;
+ MODBIND1(free_rid, const RID &);
+ MODBIND1R(bool, has, const RID &);
+ MODBIND1R(bool, load_support_data, const String &);
- virtual String get_support_data_filename() const override {
- return "";
- };
- virtual String get_support_data_info() const override {
- return "Not supported";
- };
- virtual bool save_support_data(const String &p_filename) const override;
+ MODBIND0RC(String, get_support_data_filename);
+ MODBIND0RC(String, get_support_data_info);
+ MODBIND1RC(bool, save_support_data, const String &);
- virtual bool is_locale_right_to_left(const String &p_locale) const override;
+ MODBIND1RC(bool, is_locale_right_to_left, const String &);
- virtual int64_t name_to_tag(const String &p_name) const override;
- virtual String tag_to_name(int64_t p_tag) const override;
+ MODBIND1RC(int64_t, name_to_tag, const String &);
+ MODBIND1RC(String, tag_to_name, int64_t);
/* Font interface */
- virtual RID create_font() 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;
+ MODBIND0R(RID, create_font);
+
+ MODBIND2(font_set_data, const RID &, const PackedByteArray &);
+ MODBIND3(font_set_data_ptr, const RID &, const uint8_t *, int64_t);
+
+ MODBIND2(font_set_face_index, const RID &, int64_t);
+ MODBIND1RC(int64_t, font_get_face_index, const RID &);
- virtual void font_set_face_index(const RID &p_font_rid, int64_t p_index) override;
- virtual int64_t font_get_face_index(const RID &p_font_rid) const override;
+ MODBIND1RC(int64_t, font_get_face_count, const RID &);
- virtual int64_t font_get_face_count(const RID &p_font_rid) const override;
+ MODBIND2(font_set_style, const RID &, BitField<FontStyle>);
+ MODBIND1RC(BitField<FontStyle>, font_get_style, const RID &);
- virtual void font_set_style(const RID &p_font_rid, BitField<FontStyle> p_style) override;
- virtual BitField<FontStyle> font_get_style(const RID &p_font_rid) const override;
+ MODBIND2(font_set_style_name, const RID &, const String &);
+ MODBIND1RC(String, font_get_style_name, const 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;
+ MODBIND2(font_set_name, const RID &, const String &);
+ MODBIND1RC(String, font_get_name, const 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;
+ MODBIND2(font_set_antialiasing, const RID &, TextServer::FontAntialiasing);
+ MODBIND1RC(TextServer::FontAntialiasing, font_get_antialiasing, const RID &);
- virtual void font_set_antialiasing(RID p_font_rid, TextServer::FontAntialiasing p_antialiasing) override;
- virtual TextServer::FontAntialiasing font_get_antialiasing(RID p_font_rid) const override;
+ MODBIND2(font_set_generate_mipmaps, const RID &, bool);
+ MODBIND1RC(bool, font_get_generate_mipmaps, const RID &);
- virtual void font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) override;
- virtual bool font_get_generate_mipmaps(const RID &p_font_rid) const override;
+ MODBIND2(font_set_multichannel_signed_distance_field, const RID &, bool);
+ MODBIND1RC(bool, font_is_multichannel_signed_distance_field, const 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;
+ MODBIND2(font_set_msdf_pixel_range, const RID &, int64_t);
+ MODBIND1RC(int64_t, font_get_msdf_pixel_range, const 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;
+ MODBIND2(font_set_msdf_size, const RID &, int64_t);
+ MODBIND1RC(int64_t, font_get_msdf_size, const 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;
+ MODBIND2(font_set_fixed_size, const RID &, int64_t);
+ MODBIND1RC(int64_t, font_get_fixed_size, const 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;
+ MODBIND2(font_set_force_autohinter, const RID &, bool);
+ MODBIND1RC(bool, font_is_force_autohinter, const 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;
+ MODBIND2(font_set_subpixel_positioning, const RID &, SubpixelPositioning);
+ MODBIND1RC(SubpixelPositioning, font_get_subpixel_positioning, const RID &);
- 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;
+ MODBIND2(font_set_embolden, const RID &, double);
+ MODBIND1RC(double, font_get_embolden, const 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;
+ MODBIND2(font_set_transform, const RID &, const Transform2D &);
+ MODBIND1RC(Transform2D, font_get_transform, const 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;
+ MODBIND2(font_set_variation_coordinates, const RID &, const Dictionary &);
+ MODBIND1RC(Dictionary, font_get_variation_coordinates, const 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;
+ MODBIND2(font_set_hinting, const RID &, TextServer::Hinting);
+ MODBIND1RC(TextServer::Hinting, font_get_hinting, const 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;
+ MODBIND2(font_set_oversampling, const RID &, double);
+ MODBIND1RC(double, font_get_oversampling, const 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;
+ MODBIND1RC(TypedArray<Vector2i>, font_get_size_cache_list, const RID &);
+ MODBIND1(font_clear_size_cache, const RID &);
+ MODBIND2(font_remove_size_cache, const RID &, const Vector2i &);
- virtual TypedArray<Vector2i> 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;
+ MODBIND3(font_set_ascent, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_ascent, const RID &, int64_t);
- 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;
+ MODBIND3(font_set_descent, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_descent, const 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;
+ MODBIND3(font_set_underline_position, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_underline_position, const 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;
+ MODBIND3(font_set_underline_thickness, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_underline_thickness, const 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;
+ MODBIND3(font_set_scale, const RID &, int64_t, double);
+ MODBIND2RC(double, font_get_scale, const 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;
+ MODBIND2RC(int64_t, font_get_texture_count, const RID &, const Vector2i &);
+ MODBIND2(font_clear_textures, const RID &, const Vector2i &);
+ MODBIND3(font_remove_texture, const RID &, const Vector2i &, int64_t);
- 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;
+ MODBIND4(font_set_texture_image, const RID &, const Vector2i &, int64_t, const Ref<Image> &);
+ MODBIND3RC(Ref<Image>, font_get_texture_image, const 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;
+ MODBIND4(font_set_texture_offsets, const RID &, const Vector2i &, int64_t, const PackedInt32Array &);
+ MODBIND3RC(PackedInt32Array, font_get_texture_offsets, const 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;
+ MODBIND2RC(PackedInt32Array, font_get_glyph_list, const RID &, const Vector2i &);
+ MODBIND2(font_clear_glyphs, const RID &, const Vector2i &);
+ MODBIND3(font_remove_glyph, const RID &, const Vector2i &, int64_t);
- virtual PackedInt32Array 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;
+ MODBIND3RC(Vector2, font_get_glyph_advance, const RID &, int64_t, int64_t);
+ MODBIND4(font_set_glyph_advance, const RID &, int64_t, int64_t, const Vector2 &);
- 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;
+ MODBIND3RC(Vector2, font_get_glyph_offset, const RID &, const Vector2i &, int64_t);
+ MODBIND4(font_set_glyph_offset, const RID &, const Vector2i &, 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;
+ MODBIND3RC(Vector2, font_get_glyph_size, const RID &, const Vector2i &, int64_t);
+ MODBIND4(font_set_glyph_size, const 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;
+ MODBIND3RC(Rect2, font_get_glyph_uv_rect, const RID &, const Vector2i &, int64_t);
+ MODBIND4(font_set_glyph_uv_rect, const RID &, const Vector2i &, int64_t, const Rect2 &);
- 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;
+ MODBIND3RC(int64_t, font_get_glyph_texture_idx, const RID &, const Vector2i &, int64_t);
+ MODBIND4(font_set_glyph_texture_idx, const RID &, const Vector2i &, int64_t, int64_t);
- 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 RID font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
- virtual Size2 font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override;
+ MODBIND3RC(RID, font_get_glyph_texture_rid, const RID &, const Vector2i &, int64_t);
+ MODBIND3RC(Size2, font_get_glyph_texture_size, const RID &, const Vector2i &, int64_t);
- virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override;
+ MODBIND3RC(Dictionary, font_get_glyph_contours, const RID &, int64_t, int64_t);
- virtual TypedArray<Vector2i> 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;
+ MODBIND2RC(TypedArray<Vector2i>, font_get_kerning_list, const RID &, int64_t);
+ MODBIND2(font_clear_kerning_map, const RID &, int64_t);
+ MODBIND3(font_remove_kerning, const 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;
+ MODBIND4(font_set_kerning, const RID &, int64_t, const Vector2i &, const Vector2 &);
+ MODBIND3RC(Vector2, font_get_kerning, const 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;
+ MODBIND4RC(int64_t, font_get_glyph_index, const 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;
+ MODBIND2RC(bool, font_has_char, const RID &, int64_t);
+ MODBIND1RC(String, font_get_supported_chars, const 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;
+ MODBIND4(font_render_range, const RID &, const Vector2i &, int64_t, int64_t);
+ MODBIND3(font_render_glyph, const 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;
+ MODBIND6C(font_draw_glyph, const RID &, const RID &, int64_t, const Vector2 &, int64_t, const Color &);
+ MODBIND7C(font_draw_glyph_outline, const RID &, const 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;
+ MODBIND2RC(bool, font_is_language_supported, const RID &, const String &);
+ MODBIND3(font_set_language_support_override, const RID &, const String &, bool);
+ MODBIND2R(bool, font_get_language_support_override, const RID &, const String &);
+ MODBIND2(font_remove_language_support_override, const RID &, const String &);
+ MODBIND1R(PackedStringArray, font_get_language_support_overrides, const 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;
+ MODBIND2RC(bool, font_is_script_supported, const RID &, const String &);
+ MODBIND3(font_set_script_support_override, const RID &, const String &, bool);
+ MODBIND2R(bool, font_get_script_support_override, const RID &, const String &);
+ MODBIND2(font_remove_script_support_override, const RID &, const String &);
+ MODBIND1R(PackedStringArray, font_get_script_support_overrides, const 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;
+ MODBIND2(font_set_opentype_feature_overrides, const RID &, const Dictionary &);
+ MODBIND1RC(Dictionary, font_get_opentype_feature_overrides, const 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;
+ MODBIND1RC(Dictionary, font_supported_feature_list, const RID &);
+ MODBIND1RC(Dictionary, font_supported_variation_list, const RID &);
- virtual double font_get_global_oversampling() const override;
- virtual void font_set_global_oversampling(double p_oversampling) override;
+ MODBIND0RC(double, font_get_global_oversampling);
+ MODBIND1(font_set_global_oversampling, double);
/* Shaped text buffer interface */
- virtual RID create_shaped_text(Direction p_direction = DIRECTION_AUTO, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
+ MODBIND2R(RID, create_shaped_text, Direction, Orientation);
- virtual void shaped_text_clear(const RID &p_shaped) override;
+ MODBIND1(shaped_text_clear, const 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;
+ MODBIND2(shaped_text_set_direction, const RID &, Direction);
+ MODBIND1RC(Direction, shaped_text_get_direction, const RID &);
+ MODBIND1RC(Direction, shaped_text_get_inferred_direction, const RID &);
- virtual void shaped_text_set_bidi_override(const RID &p_shaped, const Array &p_override) override;
+ MODBIND2(shaped_text_set_bidi_override, const 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;
+ MODBIND2(shaped_text_set_custom_punctuation, const RID &, const String &);
+ MODBIND1RC(String, shaped_text_get_custom_punctuation, const 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;
+ MODBIND2(shaped_text_set_orientation, const RID &, Orientation);
+ MODBIND1RC(Orientation, shaped_text_get_orientation, const 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;
+ MODBIND2(shaped_text_set_preserve_invalid, const RID &, bool);
+ MODBIND1RC(bool, shaped_text_get_preserve_invalid, const 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;
+ MODBIND2(shaped_text_set_preserve_control, const RID &, bool);
+ MODBIND1RC(bool, shaped_text_get_preserve_control, const RID &);
- virtual void shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) override;
- virtual int64_t shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const override;
+ MODBIND3(shaped_text_set_spacing, const RID &, SpacingType, int64_t);
+ MODBIND2RC(int64_t, shaped_text_get_spacing, const RID &, SpacingType);
- virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const TypedArray<RID> &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;
+ MODBIND7R(bool, shaped_text_add_string, const RID &, const String &, const TypedArray<RID> &, int64_t, const Dictionary &, const String &, const Variant &);
+ MODBIND5R(bool, shaped_text_add_object, const RID &, const Variant &, const Size2 &, InlineAlignment, int64_t);
+ MODBIND4R(bool, shaped_text_resize_object, const 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 TypedArray<RID> &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary()) override;
+ MODBIND1RC(int64_t, shaped_get_span_count, const RID &);
+ MODBIND2RC(Variant, shaped_get_span_meta, const RID &, int64_t);
+ MODBIND5(shaped_set_span_update_font, const RID &, int64_t, const TypedArray<RID> &, 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;
+ MODBIND3RC(RID, shaped_text_substr, const RID &, int64_t, int64_t);
+ MODBIND1RC(RID, shaped_text_get_parent, const RID &);
- virtual double shaped_text_fit_to_width(const RID &p_shaped, double p_width, BitField<TextServer::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;
+ MODBIND3R(double, shaped_text_fit_to_width, const RID &, double, BitField<TextServer::JustificationFlag>);
+ MODBIND2R(double, shaped_text_tab_align, const 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;
+ MODBIND1R(bool, shaped_text_shape, const RID &);
+ MODBIND1R(bool, shaped_text_update_breaks, const RID &);
+ MODBIND1R(bool, shaped_text_update_justification_ops, const RID &);
- 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;
+ MODBIND1RC(int64_t, shaped_text_get_trim_pos, const RID &);
+ MODBIND1RC(int64_t, shaped_text_get_ellipsis_pos, const RID &);
+ MODBIND1RC(const Glyph *, shaped_text_get_ellipsis_glyphs, const RID &);
+ MODBIND1RC(int64_t, shaped_text_get_ellipsis_glyph_count, const RID &);
- virtual void shaped_text_overrun_trim_to_width(const RID &p_shaped, double p_width, BitField<TextServer::TextOverrunFlag> p_trim_flags) override;
+ MODBIND3(shaped_text_overrun_trim_to_width, const RID &, double, BitField<TextServer::TextOverrunFlag>);
- virtual bool shaped_text_is_ready(const RID &p_shaped) const override;
+ MODBIND1RC(bool, shaped_text_is_ready, const 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;
+ MODBIND1RC(const Glyph *, shaped_text_get_glyphs, const RID &);
+ MODBIND1R(const Glyph *, shaped_text_sort_logical, const RID &);
+ MODBIND1RC(int64_t, shaped_text_get_glyph_count, const RID &);
- virtual Vector2i shaped_text_get_range(const RID &p_shaped) const override;
+ MODBIND1RC(Vector2i, shaped_text_get_range, const RID &);
- 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;
+ MODBIND1RC(Array, shaped_text_get_objects, const RID &);
+ MODBIND2RC(Rect2, shaped_text_get_object_rect, const 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;
+ MODBIND1RC(Size2, shaped_text_get_size, const RID &);
+ MODBIND1RC(double, shaped_text_get_ascent, const RID &);
+ MODBIND1RC(double, shaped_text_get_descent, const RID &);
+ MODBIND1RC(double, shaped_text_get_width, const RID &);
+ MODBIND1RC(double, shaped_text_get_underline_position, const RID &);
+ MODBIND1RC(double, shaped_text_get_underline_thickness, const RID &);
- virtual PackedInt32Array string_get_word_breaks(const String &p_string, const String &p_language = "") const override;
+ MODBIND2RC(PackedInt32Array, string_get_word_breaks, const String &, 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;
+ MODBIND2RC(String, string_to_upper, const String &, const String &);
+ MODBIND2RC(String, string_to_lower, const String &, const String &);
TextServerFallback();
~TextServerFallback();
diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp
index 16d9bf7b93..aed95294e7 100644
--- a/modules/tga/image_loader_tga.cpp
+++ b/modules/tga/image_loader_tga.cpp
@@ -100,7 +100,7 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff
uint32_t width = p_header.image_width;
uint32_t height = p_header.image_height;
tga_origin_e origin = static_cast<tga_origin_e>((p_header.image_descriptor & TGA_ORIGIN_MASK) >> TGA_ORIGIN_SHIFT);
-
+ uint8_t alpha_bits = p_header.image_descriptor & TGA_IMAGE_DESCRIPTOR_ALPHA_MASK;
uint32_t x_start;
int32_t x_step;
uint32_t x_end;
@@ -184,6 +184,27 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff
y += y_step;
}
}
+ } else if (p_header.pixel_depth == 16) {
+ while (y != y_end) {
+ while (x != x_end) {
+ if (i + 1 >= p_input_size) {
+ return ERR_PARSE_ERROR;
+ }
+
+ // Always stored as RGBA5551
+ uint8_t r = (p_buffer[i + 1] & 0x7c) << 1;
+ uint8_t g = ((p_buffer[i + 1] & 0x03) << 6) | ((p_buffer[i + 0] & 0xe0) >> 2);
+ uint8_t b = (p_buffer[i + 0] & 0x1f) << 3;
+ uint8_t a = (p_buffer[i + 1] & 0x80) ? 0xff : 0;
+
+ TGA_PUT_PIXEL(r, g, b, alpha_bits ? a : 0xff);
+
+ x += x_step;
+ i += 2;
+ }
+ x = x_start;
+ y += y_step;
+ }
} else if (p_header.pixel_depth == 24) {
while (y != y_end) {
while (x != x_end) {
@@ -230,7 +251,7 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff
return OK;
}
-Error ImageLoaderTGA::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) {
+Error ImageLoaderTGA::load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale) {
Vector<uint8_t> src_image;
uint64_t src_image_len = f->get_length();
ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
@@ -277,7 +298,7 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t
err = FAILED;
}
- if (!(tga_header.pixel_depth == 8 || tga_header.pixel_depth == 24 || tga_header.pixel_depth == 32)) {
+ if (!(tga_header.pixel_depth == 8 || tga_header.pixel_depth == 16 || tga_header.pixel_depth == 24 || tga_header.pixel_depth == 32)) {
err = FAILED;
}
diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h
index d95c5ff30b..de964373ed 100644
--- a/modules/tga/image_loader_tga.h
+++ b/modules/tga/image_loader_tga.h
@@ -33,6 +33,8 @@
#include "core/io/image_loader.h"
+#define TGA_IMAGE_DESCRIPTOR_ALPHA_MASK 0xf
+
class ImageLoaderTGA : public ImageFormatLoader {
enum tga_type_e {
TGA_TYPE_NO_DATA = 0,
@@ -73,7 +75,7 @@ class ImageLoaderTGA : public ImageFormatLoader {
static Error convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome, size_t p_input_size);
public:
- virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale);
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderTGA();
};
diff --git a/modules/tga/register_types.cpp b/modules/tga/register_types.cpp
index 520ed5f799..3a9d2324e7 100644
--- a/modules/tga/register_types.cpp
+++ b/modules/tga/register_types.cpp
@@ -32,14 +32,14 @@
#include "image_loader_tga.h"
-static ImageLoaderTGA *image_loader_tga = nullptr;
+static Ref<ImageLoaderTGA> image_loader_tga;
void initialize_tga_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}
- image_loader_tga = memnew(ImageLoaderTGA);
+ image_loader_tga.instantiate();
ImageLoader::add_image_format_loader(image_loader_tga);
}
@@ -48,5 +48,6 @@ void uninitialize_tga_module(ModuleInitializationLevel p_level) {
return;
}
- memdelete(image_loader_tga);
+ ImageLoader::remove_image_format_loader(image_loader_tga);
+ image_loader_tga.unref();
}
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index c4462ba687..57f055ca42 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -91,8 +91,6 @@ void VideoStreamPlaybackTheora::video_write() {
uint8_t *w = frame_data.ptrw();
char *dst = (char *)w;
- //uv_offset=(ti.pic_x/2)+(yuv[1].stride)*(ti.pic_y/2);
-
if (px_fmt == TH_PF_444) {
yuv444_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2);
@@ -101,7 +99,7 @@ void VideoStreamPlaybackTheora::video_write() {
} else if (px_fmt == TH_PF_420) {
yuv420_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2);
- };
+ }
format = Image::FORMAT_RGBA8;
}
@@ -123,7 +121,7 @@ void VideoStreamPlaybackTheora::clear() {
if (vorbis_p >= 3) {
vorbis_block_clear(&vb);
vorbis_dsp_clear(&vd);
- };
+ }
vorbis_comment_clear(&vc);
vorbis_info_clear(&vi);
vorbis_p = 0;
@@ -154,7 +152,7 @@ void VideoStreamPlaybackTheora::clear() {
file.unref();
playing = false;
-};
+}
void VideoStreamPlaybackTheora::set_file(const String &p_file) {
ERR_FAIL_COND(playing);
@@ -174,7 +172,6 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
ring_buffer.write(read_buffer.ptr(), read);
thread.start(_streaming_thread, this);
-
#endif
ogg_sync_init(&oy);
@@ -245,6 +242,12 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
/* we're expecting more header packets. */
while ((theora_p && theora_p < 3) || (vorbis_p && vorbis_p < 3)) {
+#ifdef _MSC_VER
+ // Make exception for these assignments in conditional expression.
+#pragma warning(push)
+#pragma warning(disable : 4706)
+#endif
+
int ret;
/* look for further theora headers */
@@ -281,6 +284,10 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
}
}
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
/* The header pages/packets will arrive before anything else we
care about, or the stream is not obeying spec */
@@ -355,20 +362,20 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
buffering = true;
time = 0;
audio_frames_wrote = 0;
-};
+}
-float VideoStreamPlaybackTheora::get_time() const {
+double VideoStreamPlaybackTheora::get_time() const {
// FIXME: AudioServer output latency was fixed in af9bb0e, previously it used to
// systematically return 0. Now that it gives a proper latency, it broke this
// code where the delay compensation likely never really worked.
return time - /* AudioServer::get_singleton()->get_output_latency() - */ delay_compensation;
-};
+}
Ref<Texture2D> VideoStreamPlaybackTheora::get_texture() const {
return texture;
}
-void VideoStreamPlaybackTheora::update(float p_delta) {
+void VideoStreamPlaybackTheora::update(double p_delta) {
if (file.is_null()) {
return;
}
@@ -376,7 +383,7 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
if (!playing || paused) {
//printf("not playing\n");
return;
- };
+ }
#ifdef THEORA_USE_THREAD_STREAMING
thread_sem->post();
@@ -444,7 +451,7 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
}
} else { /* we need more data; break out to suck in another page */
break;
- };
+ }
}
audio_done = videobuf_time < (audio_frames_wrote / float(vi.rate));
@@ -507,7 +514,7 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
//printf("video done, stopping\n");
stop();
return;
- };
+ }
if (!frame_done || !audio_done) {
//what's the point of waiting for audio to grab a page?
@@ -529,7 +536,7 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
//printf("frame at %f not ready (time %f), ready %i\n", (float)videobuf_time, get_time(), videobuf_ready);
}
- float tdiff = videobuf_time - get_time();
+ double tdiff = videobuf_time - get_time();
/*If we have lots of extra time, increase the post-processing level.*/
if (tdiff > ti.fps_denominator * 0.25 / ti.fps_numerator) {
pp_inc = pp_level < pp_level_max ? 1 : 0;
@@ -539,7 +546,7 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
}
video_write();
-};
+}
void VideoStreamPlaybackTheora::play() {
if (!playing) {
@@ -551,7 +558,7 @@ void VideoStreamPlaybackTheora::play() {
playing = true;
delay_compensation = ProjectSettings::get_singleton()->get("audio/video/video_delay_compensation_ms");
delay_compensation /= 1000.0;
-};
+}
void VideoStreamPlaybackTheora::stop() {
if (playing) {
@@ -560,44 +567,44 @@ void VideoStreamPlaybackTheora::stop() {
}
playing = false;
time = 0;
-};
+}
bool VideoStreamPlaybackTheora::is_playing() const {
return playing;
-};
+}
void VideoStreamPlaybackTheora::set_paused(bool p_paused) {
paused = p_paused;
-};
+}
bool VideoStreamPlaybackTheora::is_paused() const {
return paused;
-};
+}
void VideoStreamPlaybackTheora::set_loop(bool p_enable) {
}
bool VideoStreamPlaybackTheora::has_loop() const {
return false;
-};
+}
-float VideoStreamPlaybackTheora::get_length() const {
+double VideoStreamPlaybackTheora::get_length() const {
return 0;
-};
+}
String VideoStreamPlaybackTheora::get_stream_name() const {
return "";
-};
+}
int VideoStreamPlaybackTheora::get_loop_count() const {
return 0;
-};
+}
-float VideoStreamPlaybackTheora::get_playback_position() const {
+double VideoStreamPlaybackTheora::get_playback_position() const {
return get_time();
-};
+}
-void VideoStreamPlaybackTheora::seek(float p_time) {
+void VideoStreamPlaybackTheora::seek(double p_time) {
WARN_PRINT_ONCE("Seeking in Theora videos is not implemented yet (it's only supported for GDExtension-provided video streams).");
}
@@ -650,15 +657,14 @@ VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() {
thread_sem = Semaphore::create();
#endif
-};
+}
VideoStreamPlaybackTheora::~VideoStreamPlaybackTheora() {
#ifdef THEORA_USE_THREAD_STREAMING
-
memdelete(thread_sem);
#endif
clear();
-};
+}
void VideoStreamTheora::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_file", "file"), &VideoStreamTheora::set_file);
diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h
index 00d799dc24..3efb653651 100644
--- a/modules/theora/video_stream_theora.h
+++ b/modules/theora/video_stream_theora.h
@@ -64,7 +64,7 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback {
int buffer_data();
int queue_page(ogg_page *page);
void video_write();
- float get_time() const;
+ double get_time() const;
bool theora_eos = false;
bool vorbis_eos = false;
@@ -136,19 +136,19 @@ public:
virtual void set_loop(bool p_enable) override;
virtual bool has_loop() const override;
- virtual float get_length() const override;
+ virtual double get_length() const override;
virtual String get_stream_name() const;
virtual int get_loop_count() const;
- virtual float get_playback_position() const override;
- virtual void seek(float p_time) override;
+ virtual double get_playback_position() const override;
+ virtual void seek(double p_time) override;
void set_file(const String &p_file);
virtual Ref<Texture2D> get_texture() const override;
- virtual void update(float p_delta) override;
+ virtual void update(double p_delta) override;
virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata) override;
virtual int get_channels() const override;
diff --git a/modules/tinyexr/config.py b/modules/tinyexr/config.py
index 53b8f2f2e3..eb565b85b9 100644
--- a/modules/tinyexr/config.py
+++ b/modules/tinyexr/config.py
@@ -1,5 +1,5 @@
def can_build(env, platform):
- return env["tools"]
+ return env.editor_build
def configure(env):
diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp
index 6f61251f9b..5c43bfc8b7 100644
--- a/modules/tinyexr/image_loader_tinyexr.cpp
+++ b/modules/tinyexr/image_loader_tinyexr.cpp
@@ -37,7 +37,7 @@
#include "thirdparty/tinyexr/tinyexr.h"
-Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) {
+Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale) {
Vector<uint8_t> src_image;
uint64_t src_image_len = f->get_length();
ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
diff --git a/modules/tinyexr/image_loader_tinyexr.h b/modules/tinyexr/image_loader_tinyexr.h
index 8da2a0d4af..ab34a59da5 100644
--- a/modules/tinyexr/image_loader_tinyexr.h
+++ b/modules/tinyexr/image_loader_tinyexr.h
@@ -35,7 +35,7 @@
class ImageLoaderTinyEXR : public ImageFormatLoader {
public:
- virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale);
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderTinyEXR();
};
diff --git a/modules/tinyexr/register_types.cpp b/modules/tinyexr/register_types.cpp
index c5897f37c3..b1a9f18e3b 100644
--- a/modules/tinyexr/register_types.cpp
+++ b/modules/tinyexr/register_types.cpp
@@ -33,14 +33,14 @@
#include "image_loader_tinyexr.h"
#include "image_saver_tinyexr.h"
-static ImageLoaderTinyEXR *image_loader_tinyexr = nullptr;
+static Ref<ImageLoaderTinyEXR> image_loader_tinyexr;
void initialize_tinyexr_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
return;
}
- image_loader_tinyexr = memnew(ImageLoaderTinyEXR);
+ image_loader_tinyexr.instantiate();
ImageLoader::add_image_format_loader(image_loader_tinyexr);
Image::save_exr_func = save_exr;
@@ -52,7 +52,8 @@ void uninitialize_tinyexr_module(ModuleInitializationLevel p_level) {
return;
}
- memdelete(image_loader_tinyexr);
+ ImageLoader::remove_image_format_loader(image_loader_tinyexr);
+ image_loader_tinyexr.unref();
Image::save_exr_func = nullptr;
}
diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp
index 8315eea614..792103cd31 100644
--- a/modules/vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp
@@ -74,7 +74,7 @@ int AudioStreamPlaybackOggVorbis::_mix_internal(AudioFrame *p_buffer, int p_fram
if (beat_length_frames >= 0) {
/**
* Length determined by beat length
- * This code is commented out because, in practice, it is prefered that the fade
+ * This code is commented out because, in practice, it is preferred that the fade
* is done by the transitioner and this stream just goes on until it ends while fading out.
*
* End fade implementation is left here for reference in case at some point this feature
@@ -153,8 +153,11 @@ int AudioStreamPlaybackOggVorbis::_mix_frames_vorbis(AudioFrame *p_buffer, int p
return -1;
}
- ERR_FAIL_COND_V_MSG((err = vorbis_synthesis(&block, packet)), 0, "Error during vorbis synthesis " + itos(err));
- ERR_FAIL_COND_V_MSG((err = vorbis_synthesis_blockin(&dsp_state, &block)), 0, "Error during vorbis block processing " + itos(err));
+ err = vorbis_synthesis(&block, packet);
+ ERR_FAIL_COND_V_MSG(err != 0, 0, "Error during vorbis synthesis " + itos(err));
+
+ err = vorbis_synthesis_blockin(&dsp_state, &block);
+ ERR_FAIL_COND_V_MSG(err != 0, 0, "Error during vorbis block processing " + itos(err));
have_packets_left = !packet->e_o_s;
}
@@ -223,7 +226,7 @@ bool AudioStreamPlaybackOggVorbis::_alloc_vorbis() {
return true;
}
-void AudioStreamPlaybackOggVorbis::start(float p_from_pos) {
+void AudioStreamPlaybackOggVorbis::start(double p_from_pos) {
ERR_FAIL_COND(!ready);
loop_fade_remaining = FADE_SIZE;
active = true;
@@ -244,15 +247,15 @@ int AudioStreamPlaybackOggVorbis::get_loop_count() const {
return loops;
}
-float AudioStreamPlaybackOggVorbis::get_playback_position() const {
- return float(frames_mixed) / vorbis_data->get_sampling_rate();
+double AudioStreamPlaybackOggVorbis::get_playback_position() const {
+ return double(frames_mixed) / (double)vorbis_data->get_sampling_rate();
}
void AudioStreamPlaybackOggVorbis::tag_used_streams() {
vorbis_stream->tag_used(get_playback_position());
}
-void AudioStreamPlaybackOggVorbis::seek(float p_time) {
+void AudioStreamPlaybackOggVorbis::seek(double p_time) {
ERR_FAIL_COND(!ready);
ERR_FAIL_COND(vorbis_stream.is_null());
if (!active) {
@@ -290,11 +293,15 @@ void AudioStreamPlaybackOggVorbis::seek(float p_time) {
headers_remaining = 3;
}
if (!headers_remaining) {
- ERR_FAIL_COND_MSG((err = vorbis_synthesis(&block, packet)), "Error during vorbis synthesis " + itos(err));
- ERR_FAIL_COND_MSG((err = vorbis_synthesis_blockin(&dsp_state, &block)), "Error during vorbis block processing " + itos(err));
+ err = vorbis_synthesis(&block, packet);
+ ERR_FAIL_COND_MSG(err != 0, "Error during vorbis synthesis " + itos(err));
+
+ err = vorbis_synthesis_blockin(&dsp_state, &block);
+ ERR_FAIL_COND_MSG(err != 0, "Error during vorbis block processing " + itos(err));
int samples_out = vorbis_synthesis_pcmout(&dsp_state, nullptr);
- ERR_FAIL_COND_MSG((err = vorbis_synthesis_read(&dsp_state, samples_out)), "Error during vorbis read updating " + itos(err));
+ err = vorbis_synthesis_read(&dsp_state, samples_out);
+ ERR_FAIL_COND_MSG(err != 0, "Error during vorbis read updating " + itos(err));
samples_in_page += samples_out;
@@ -341,12 +348,16 @@ void AudioStreamPlaybackOggVorbis::seek(float p_time) {
headers_remaining = 3;
}
if (!headers_remaining) {
- ERR_FAIL_COND_MSG((err = vorbis_synthesis(&block, packet)), "Error during vorbis synthesis " + itos(err));
- ERR_FAIL_COND_MSG((err = vorbis_synthesis_blockin(&dsp_state, &block)), "Error during vorbis block processing " + itos(err));
+ err = vorbis_synthesis(&block, packet);
+ ERR_FAIL_COND_MSG(err != 0, "Error during vorbis synthesis " + itos(err));
+
+ err = vorbis_synthesis_blockin(&dsp_state, &block);
+ ERR_FAIL_COND_MSG(err != 0, "Error during vorbis block processing " + itos(err));
int samples_out = vorbis_synthesis_pcmout(&dsp_state, nullptr);
int read_samples = samples_to_burn > samples_out ? samples_out : samples_to_burn;
- ERR_FAIL_COND_MSG((err = vorbis_synthesis_read(&dsp_state, samples_out)), "Error during vorbis read updating " + itos(err));
+ err = vorbis_synthesis_read(&dsp_state, samples_out);
+ ERR_FAIL_COND_MSG(err != 0, "Error during vorbis read updating " + itos(err));
samples_to_burn -= read_samples;
if (samples_to_burn <= 0) {
@@ -462,15 +473,15 @@ bool AudioStreamOggVorbis::has_loop() const {
return loop;
}
-void AudioStreamOggVorbis::set_loop_offset(float p_seconds) {
+void AudioStreamOggVorbis::set_loop_offset(double p_seconds) {
loop_offset = p_seconds;
}
-float AudioStreamOggVorbis::get_loop_offset() const {
+double AudioStreamOggVorbis::get_loop_offset() const {
return loop_offset;
}
-float AudioStreamOggVorbis::get_length() const {
+double AudioStreamOggVorbis::get_length() const {
ERR_FAIL_COND_V(packet_sequence.is_null(), 0);
return packet_sequence->get_length();
}
diff --git a/modules/vorbis/audio_stream_ogg_vorbis.h b/modules/vorbis/audio_stream_ogg_vorbis.h
index 0350e1f761..3aa99971be 100644
--- a/modules/vorbis/audio_stream_ogg_vorbis.h
+++ b/modules/vorbis/audio_stream_ogg_vorbis.h
@@ -83,14 +83,14 @@ protected:
virtual float get_stream_sampling_rate() override;
public:
- virtual void start(float p_from_pos = 0.0) override;
+ virtual void start(double p_from_pos = 0.0) override;
virtual void stop() override;
virtual bool is_playing() const override;
virtual int get_loop_count() const override; //times it looped
- virtual float get_playback_position() const override;
- virtual void seek(float p_time) override;
+ virtual double get_playback_position() const override;
+ virtual void seek(double p_time) override;
virtual void tag_used_streams() override;
@@ -127,8 +127,8 @@ public:
void set_loop(bool p_enable);
virtual bool has_loop() const override;
- void set_loop_offset(float p_seconds);
- float get_loop_offset() const;
+ void set_loop_offset(double p_seconds);
+ double get_loop_offset() const;
void set_bpm(double p_bpm);
virtual double get_bpm() const override;
@@ -145,7 +145,7 @@ public:
void set_packet_sequence(Ref<OggPacketSequence> p_packet_sequence);
Ref<OggPacketSequence> get_packet_sequence() const;
- virtual float get_length() const override; //if supported, otherwise return 0
+ virtual double get_length() const override; //if supported, otherwise return 0
virtual bool is_monophonic() const override;
diff --git a/modules/vorbis/resource_importer_ogg_vorbis.cpp b/modules/vorbis/resource_importer_ogg_vorbis.cpp
index bf5f7206b8..a491c3d3fb 100644
--- a/modules/vorbis/resource_importer_ogg_vorbis.cpp
+++ b/modules/vorbis/resource_importer_ogg_vorbis.cpp
@@ -110,15 +110,18 @@ Ref<AudioStreamOggVorbis> ResourceImporterOggVorbis::import_ogg_vorbis(const Str
size_t packet_count = 0;
bool done = false;
while (!done) {
- ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err));
+ err = ogg_sync_check(&sync_state);
+ ERR_FAIL_COND_V_MSG(err != 0, Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err));
while (ogg_sync_pageout(&sync_state, &page) != 1) {
if (cursor >= len) {
done = true;
break;
}
- ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err));
+ err = ogg_sync_check(&sync_state);
+ ERR_FAIL_COND_V_MSG(err != 0, Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err));
char *sync_buf = ogg_sync_buffer(&sync_state, OGG_SYNC_BUFFER_SIZE);
- ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err));
+ err = ogg_sync_check(&sync_state);
+ ERR_FAIL_COND_V_MSG(err != 0, Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err));
ERR_FAIL_COND_V(cursor > len, Ref<AudioStreamOggVorbis>());
size_t copy_size = len - cursor;
if (copy_size > OGG_SYNC_BUFFER_SIZE) {
@@ -127,12 +130,14 @@ Ref<AudioStreamOggVorbis> ResourceImporterOggVorbis::import_ogg_vorbis(const Str
memcpy(sync_buf, &file_data[cursor], copy_size);
ogg_sync_wrote(&sync_state, copy_size);
cursor += copy_size;
- ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err));
+ err = ogg_sync_check(&sync_state);
+ ERR_FAIL_COND_V_MSG(err != 0, Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err));
}
if (done) {
break;
}
- ERR_FAIL_COND_V_MSG((err = ogg_sync_check(&sync_state)), Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err));
+ err = ogg_sync_check(&sync_state);
+ ERR_FAIL_COND_V_MSG(err != 0, Ref<AudioStreamOggVorbis>(), "Ogg sync error " + itos(err));
// Have a page now.
if (!initialized_stream) {
@@ -142,7 +147,8 @@ Ref<AudioStreamOggVorbis> ResourceImporterOggVorbis::import_ogg_vorbis(const Str
initialized_stream = true;
}
ogg_stream_pagein(&stream_state, &page);
- ERR_FAIL_COND_V_MSG((err = ogg_stream_check(&stream_state)), Ref<AudioStreamOggVorbis>(), "Ogg stream error " + itos(err));
+ err = ogg_stream_check(&stream_state);
+ ERR_FAIL_COND_V_MSG(err != 0, Ref<AudioStreamOggVorbis>(), "Ogg stream error " + itos(err));
int desync_iters = 0;
Vector<Vector<uint8_t>> packet_data;
diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp
index 705ab508ab..dd387db554 100644
--- a/modules/webp/image_loader_webp.cpp
+++ b/modules/webp/image_loader_webp.cpp
@@ -48,7 +48,7 @@ static Ref<Image> _webp_mem_loader_func(const uint8_t *p_png, int p_size) {
return img;
}
-Error ImageLoaderWebP::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) {
+Error ImageLoaderWebP::load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale) {
Vector<uint8_t> src_image;
uint64_t src_image_len = f->get_length();
ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
diff --git a/modules/webp/image_loader_webp.h b/modules/webp/image_loader_webp.h
index d868ae3f7f..0522e4ef91 100644
--- a/modules/webp/image_loader_webp.h
+++ b/modules/webp/image_loader_webp.h
@@ -35,7 +35,7 @@
class ImageLoaderWebP : public ImageFormatLoader {
public:
- virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale);
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderWebP();
};
diff --git a/modules/webp/register_types.cpp b/modules/webp/register_types.cpp
index 29f633743e..e523f43cfe 100644
--- a/modules/webp/register_types.cpp
+++ b/modules/webp/register_types.cpp
@@ -33,7 +33,7 @@
#include "image_loader_webp.h"
#include "resource_saver_webp.h"
-static ImageLoaderWebP *image_loader_webp = nullptr;
+static Ref<ImageLoaderWebP> image_loader_webp;
static Ref<ResourceSaverWebP> resource_saver_webp;
void initialize_webp_module(ModuleInitializationLevel p_level) {
@@ -41,9 +41,10 @@ void initialize_webp_module(ModuleInitializationLevel p_level) {
return;
}
- image_loader_webp = memnew(ImageLoaderWebP);
- resource_saver_webp.instantiate();
+ image_loader_webp.instantiate();
ImageLoader::add_image_format_loader(image_loader_webp);
+
+ resource_saver_webp.instantiate();
ResourceSaver::add_resource_format_saver(resource_saver_webp);
}
@@ -52,7 +53,9 @@ void uninitialize_webp_module(ModuleInitializationLevel p_level) {
return;
}
- memdelete(image_loader_webp);
+ ImageLoader::remove_image_format_loader(image_loader_webp);
+ image_loader_webp.unref();
+
ResourceSaver::remove_resource_format_saver(resource_saver_webp);
resource_saver_webp.unref();
}
diff --git a/modules/websocket/SCsub b/modules/websocket/SCsub
index 890fb71592..3f834471e5 100644
--- a/modules/websocket/SCsub
+++ b/modules/websocket/SCsub
@@ -41,7 +41,7 @@ elif env["builtin_wslay"]:
module_obj = []
env_ws.add_source_files(module_obj, "*.cpp")
-if env["tools"]:
+if env.editor_build:
env_ws.add_source_files(module_obj, "editor/*.cpp")
env.modules_sources += module_obj
diff --git a/modules/websocket/websocket_macros.h b/modules/websocket/websocket_macros.h
index a01ae65c56..b03bd8f45c 100644
--- a/modules/websocket/websocket_macros.h
+++ b/modules/websocket/websocket_macros.h
@@ -35,34 +35,32 @@
#define DEF_PKT_SHIFT 10
#define DEF_BUF_SHIFT 16
-/* clang-format off */
-#define GDCICLASS(CNAME) \
-public:\
- static CNAME *(*_create)();\
-\
- static Ref<CNAME > create_ref() {\
-\
- if (!_create)\
- return Ref<CNAME >();\
- return Ref<CNAME >(_create());\
- }\
-\
- static CNAME *create() {\
-\
- if (!_create)\
- return nullptr;\
- return _create();\
- }\
-protected:\
+#define GDCICLASS(CNAME) \
+public: \
+ static CNAME *(*_create)(); \
+ \
+ static Ref<CNAME> create_ref() { \
+ if (!_create) \
+ return Ref<CNAME>(); \
+ return Ref<CNAME>(_create()); \
+ } \
+ \
+ static CNAME *create() { \
+ if (!_create) \
+ return nullptr; \
+ return _create(); \
+ } \
+ \
+protected:
#define GDCINULL(CNAME) \
-CNAME *(*CNAME::_create)() = nullptr;
+ CNAME *(*CNAME::_create)() = nullptr;
-#define GDCIIMPL(IMPNAME, CNAME) \
-public:\
- static CNAME *_create() { return memnew(IMPNAME); }\
- static void make_default() { CNAME::_create = IMPNAME::_create; }\
-protected:\
-/* clang-format on */
+#define GDCIIMPL(IMPNAME, CNAME) \
+public: \
+ static CNAME *_create() { return memnew(IMPNAME); } \
+ static void make_default() { CNAME::_create = IMPNAME::_create; } \
+ \
+protected:
#endif // WEBSOCKET_MACROS_H
diff --git a/modules/webxr/config.py b/modules/webxr/config.py
index f676ef3483..8d75e7f531 100644
--- a/modules/webxr/config.py
+++ b/modules/webxr/config.py
@@ -1,5 +1,5 @@
def can_build(env, platform):
- return not env["disable_3d"]
+ return env["opengl3"] and not env["disable_3d"]
def configure(env):
diff --git a/modules/webxr/godot_webxr.h b/modules/webxr/godot_webxr.h
index 52104895d4..34d068be3e 100644
--- a/modules/webxr/godot_webxr.h
+++ b/modules/webxr/godot_webxr.h
@@ -65,8 +65,7 @@ extern int godot_webxr_get_view_count();
extern int *godot_webxr_get_render_target_size();
extern float *godot_webxr_get_transform_for_eye(int p_eye);
extern float *godot_webxr_get_projection_for_eye(int p_eye);
-extern int godot_webxr_get_external_texture_for_eye(int p_eye);
-extern void godot_webxr_commit_for_eye(int p_eye);
+extern void godot_webxr_commit_for_eye(int p_eye, unsigned int p_destination_fbo);
extern void godot_webxr_sample_controller_data();
extern int godot_webxr_get_controller_count();
diff --git a/modules/webxr/native/library_godot_webxr.js b/modules/webxr/native/library_godot_webxr.js
index c4b21defce..9b75796ee5 100644
--- a/modules/webxr/native/library_godot_webxr.js
+++ b/modules/webxr/native/library_godot_webxr.js
@@ -32,9 +32,6 @@ const GodotWebXR = {
$GodotWebXR: {
gl: null,
- texture_ids: [null, null],
- textures: [null, null],
-
session: null,
space: null,
frame: null,
@@ -77,110 +74,6 @@ const GodotWebXR = {
}, 0);
},
- // Some custom WebGL code for blitting our eye textures to the
- // framebuffer we get from WebXR.
- shaderProgram: null,
- programInfo: null,
- buffer: null,
- // Vertex shader source.
- vsSource: `
- const vec2 scale = vec2(0.5, 0.5);
- attribute vec4 aVertexPosition;
-
- varying highp vec2 vTextureCoord;
-
- void main () {
- gl_Position = aVertexPosition;
- vTextureCoord = aVertexPosition.xy * scale + scale;
- }
- `,
- // Fragment shader source.
- fsSource: `
- varying highp vec2 vTextureCoord;
-
- uniform sampler2D uSampler;
-
- void main() {
- gl_FragColor = texture2D(uSampler, vTextureCoord);
- }
- `,
-
- initShaderProgram: (gl, vsSource, fsSource) => {
- const vertexShader = GodotWebXR.loadShader(gl, gl.VERTEX_SHADER, vsSource);
- const fragmentShader = GodotWebXR.loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
-
- const shaderProgram = gl.createProgram();
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
-
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- GodotRuntime.error(`Unable to initialize the shader program: ${gl.getProgramInfoLog(shaderProgram)}`);
- return null;
- }
-
- return shaderProgram;
- },
- loadShader: (gl, type, source) => {
- const shader = gl.createShader(type);
- gl.shaderSource(shader, source);
- gl.compileShader(shader);
-
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- GodotRuntime.error(`An error occurred compiling the shader: ${gl.getShaderInfoLog(shader)}`);
- gl.deleteShader(shader);
- return null;
- }
-
- return shader;
- },
- initBuffer: (gl) => {
- const positionBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- const positions = [
- -1.0, -1.0,
- 1.0, -1.0,
- -1.0, 1.0,
- 1.0, 1.0,
- ];
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
- return positionBuffer;
- },
- blitTexture: (gl, texture) => {
- if (GodotWebXR.shaderProgram === null) {
- GodotWebXR.shaderProgram = GodotWebXR.initShaderProgram(gl, GodotWebXR.vsSource, GodotWebXR.fsSource);
- GodotWebXR.programInfo = {
- program: GodotWebXR.shaderProgram,
- attribLocations: {
- vertexPosition: gl.getAttribLocation(GodotWebXR.shaderProgram, 'aVertexPosition'),
- },
- uniformLocations: {
- uSampler: gl.getUniformLocation(GodotWebXR.shaderProgram, 'uSampler'),
- },
- };
- GodotWebXR.buffer = GodotWebXR.initBuffer(gl);
- }
-
- const orig_program = gl.getParameter(gl.CURRENT_PROGRAM);
- gl.useProgram(GodotWebXR.shaderProgram);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, GodotWebXR.buffer);
- gl.vertexAttribPointer(GodotWebXR.programInfo.attribLocations.vertexPosition, 2, gl.FLOAT, false, 0, 0);
- gl.enableVertexAttribArray(GodotWebXR.programInfo.attribLocations.vertexPosition);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.uniform1i(GodotWebXR.programInfo.uniformLocations.uSampler, 0);
-
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
-
- // Restore state.
- gl.bindTexture(gl.TEXTURE_2D, null);
- gl.disableVertexAttribArray(GodotWebXR.programInfo.attribLocations.vertexPosition);
- gl.bindBuffer(gl.ARRAY_BUFFER, null);
- gl.useProgram(orig_program);
- },
-
// Holds the controllers list between function calls.
controllers: [],
@@ -370,22 +263,6 @@ const GodotWebXR = {
.catch((e) => { });
}
- // Clean-up the textures we allocated for each view.
- const gl = GodotWebXR.gl;
- for (let i = 0; i < GodotWebXR.textures.length; i++) {
- const texture = GodotWebXR.textures[i];
- if (texture !== null) {
- gl.deleteTexture(texture);
- }
- GodotWebXR.textures[i] = null;
-
- const texture_id = GodotWebXR.texture_ids[i];
- if (texture_id !== null) {
- GL.textures[texture_id] = null;
- }
- GodotWebXR.texture_ids[i] = null;
- }
-
GodotWebXR.session = null;
GodotWebXR.space = null;
GodotWebXR.frame = null;
@@ -460,50 +337,9 @@ const GodotWebXR = {
return buf;
},
- godot_webxr_get_external_texture_for_eye__proxy: 'sync',
- godot_webxr_get_external_texture_for_eye__sig: 'ii',
- godot_webxr_get_external_texture_for_eye: function (p_eye) {
- if (!GodotWebXR.session) {
- return 0;
- }
-
- const view_index = (p_eye === 2 /* ARVRInterface::EYE_RIGHT */) ? 1 : 0;
- if (GodotWebXR.texture_ids[view_index]) {
- return GodotWebXR.texture_ids[view_index];
- }
-
- // Check pose separately and after returning the cached texture id,
- // because we won't get a pose in some cases if we lose tracking, and
- // we don't want to return 0 just because tracking was lost.
- if (!GodotWebXR.pose) {
- return 0;
- }
-
- const glLayer = GodotWebXR.session.renderState.baseLayer;
- const view = GodotWebXR.pose.views[view_index];
- const viewport = glLayer.getViewport(view);
- const gl = GodotWebXR.gl;
-
- const texture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, texture);
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, viewport.width, viewport.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
-
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- gl.bindTexture(gl.TEXTURE_2D, null);
-
- const texture_id = GL.getNewId(GL.textures);
- GL.textures[texture_id] = texture;
- GodotWebXR.textures[view_index] = texture;
- GodotWebXR.texture_ids[view_index] = texture_id;
- return texture_id;
- },
-
godot_webxr_commit_for_eye__proxy: 'sync',
- godot_webxr_commit_for_eye__sig: 'vi',
- godot_webxr_commit_for_eye: function (p_eye) {
+ godot_webxr_commit_for_eye__sig: 'vii',
+ godot_webxr_commit_for_eye: function (p_eye, p_destination_fbo) {
if (!GodotWebXR.session || !GodotWebXR.pose) {
return;
}
@@ -514,18 +350,29 @@ const GodotWebXR = {
const viewport = glLayer.getViewport(view);
const gl = GodotWebXR.gl;
+ const framebuffer = GL.framebuffers[p_destination_fbo];
+
const orig_framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
- const orig_viewport = gl.getParameter(gl.VIEWPORT);
+ const orig_read_framebuffer = gl.getParameter(gl.READ_FRAMEBUFFER_BINDING);
+ const orig_read_buffer = gl.getParameter(gl.READ_BUFFER);
+ const orig_draw_framebuffer = gl.getParameter(gl.DRAW_FRAMEBUFFER_BINDING);
- // Bind to WebXR's framebuffer.
- gl.bindFramebuffer(gl.FRAMEBUFFER, glLayer.framebuffer);
- gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+ // Copy from Godot render target into framebuffer from WebXR.
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, framebuffer);
+ gl.readBuffer(gl.COLOR_ATTACHMENT0);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, glLayer.framebuffer);
- GodotWebXR.blitTexture(gl, GodotWebXR.textures[view_index]);
+ // Flip Y upside down on destination.
+ gl.blitFramebuffer(0, 0, viewport.width, viewport.height,
+ viewport.x, viewport.height, viewport.width, viewport.y,
+ gl.COLOR_BUFFER_BIT, gl.NEAREST);
// Restore state.
gl.bindFramebuffer(gl.FRAMEBUFFER, orig_framebuffer);
- gl.viewport(orig_viewport[0], orig_viewport[1], orig_viewport[2], orig_viewport[3]);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, orig_read_framebuffer);
+ gl.readBuffer(orig_read_buffer);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, orig_draw_framebuffer);
},
godot_webxr_sample_controller_data__proxy: 'sync',
diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp
index 7d97dbfa0b..d0c7484aa1 100644
--- a/modules/webxr/webxr_interface_js.cpp
+++ b/modules/webxr/webxr_interface_js.cpp
@@ -34,9 +34,11 @@
#include "core/input/input.h"
#include "core/os/os.h"
+#include "drivers/gles3/storage/texture_storage.h"
#include "emscripten.h"
#include "godot_webxr.h"
#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/rendering_server_globals.h"
#include <stdlib.h>
@@ -232,6 +234,8 @@ bool WebXRInterfaceJS::initialize() {
}
// we must create a tracker for our head
+ head_transform.basis = Basis();
+ head_transform.origin = Vector3();
head_tracker.instantiate();
head_tracker->set_tracker_type(XRServer::TRACKER_HEAD);
head_tracker->set_tracker_name("head");
@@ -334,15 +338,17 @@ Transform3D WebXRInterfaceJS::get_camera_transform() {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, transform_for_eye);
- float *js_matrix = godot_webxr_get_transform_for_eye(0);
- if (!initialized || js_matrix == nullptr) {
- return transform_for_eye;
- }
+ if (initialized) {
+ float world_scale = xr_server->get_world_scale();
- transform_for_eye = _js_matrix_to_transform(js_matrix);
- free(js_matrix);
+ // just scale our origin point of our transform
+ Transform3D _head_transform = head_transform;
+ _head_transform.origin *= world_scale;
+
+ transform_for_eye = (xr_server->get_reference_frame()) * _head_transform;
+ }
- return xr_server->get_reference_frame() * transform_for_eye;
+ return transform_for_eye;
};
Transform3D WebXRInterfaceJS::get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) {
@@ -360,6 +366,14 @@ Transform3D WebXRInterfaceJS::get_transform_for_view(uint32_t p_view, const Tran
transform_for_eye = _js_matrix_to_transform(js_matrix);
free(js_matrix);
+ float world_scale = xr_server->get_world_scale();
+ // Scale only the center point of our eye transform, so we don't scale the
+ // distance between the eyes.
+ Transform3D _head_transform = head_transform;
+ transform_for_eye.origin -= _head_transform.origin;
+ _head_transform.origin *= world_scale;
+ transform_for_eye.origin += _head_transform.origin;
+
return p_cam_transform * xr_server->get_reference_frame() * transform_for_eye;
};
@@ -394,29 +408,33 @@ Vector<BlitToScreen> WebXRInterfaceJS::post_draw_viewport(RID p_render_target, c
return blit_to_screen;
}
- // @todo Refactor this to be based on "views" rather than "eyes".
- godot_webxr_commit_for_eye(1);
- if (godot_webxr_get_view_count() > 1) {
- godot_webxr_commit_for_eye(2);
+ GLES3::TextureStorage *texture_storage = dynamic_cast<GLES3::TextureStorage *>(RSG::texture_storage);
+ if (!texture_storage) {
+ return blit_to_screen;
}
+ GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target);
+
+ // @todo Support multiple eyes!
+ godot_webxr_commit_for_eye(1, rt->fbo);
+
return blit_to_screen;
};
void WebXRInterfaceJS::process() {
if (initialized) {
- godot_webxr_sample_controller_data();
-
+ // Get the "head" position.
+ float *js_matrix = godot_webxr_get_transform_for_eye(0);
+ if (js_matrix != nullptr) {
+ head_transform = _js_matrix_to_transform(js_matrix);
+ free(js_matrix);
+ }
if (head_tracker.is_valid()) {
- // TODO set default pose to our head location (i.e. get_camera_transform without world scale and reference frame applied)
- // head_tracker->set_pose("default", head_transform, Vector3(), Vector3());
+ head_tracker->set_pose("default", head_transform, Vector3(), Vector3());
}
+ godot_webxr_sample_controller_data();
int controller_count = godot_webxr_get_controller_count();
- if (controller_count == 0) {
- return;
- }
-
for (int i = 0; i < controller_count; i++) {
_update_tracker(i);
}
diff --git a/modules/webxr/webxr_interface_js.h b/modules/webxr/webxr_interface_js.h
index dbe89dad83..319adc2ac9 100644
--- a/modules/webxr/webxr_interface_js.h
+++ b/modules/webxr/webxr_interface_js.h
@@ -45,6 +45,7 @@ class WebXRInterfaceJS : public WebXRInterface {
private:
bool initialized;
Ref<XRPositionalTracker> head_tracker;
+ Transform3D head_transform;
String session_mode;
String required_features;
diff --git a/modules/xatlas_unwrap/config.py b/modules/xatlas_unwrap/config.py
index 2e73c51626..ecc61c2d7e 100644
--- a/modules/xatlas_unwrap/config.py
+++ b/modules/xatlas_unwrap/config.py
@@ -1,5 +1,5 @@
def can_build(env, platform):
- return env["tools"] and platform not in ["android", "ios"]
+ return env.editor_build and platform not in ["android", "ios"]
def configure(env):