summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/bmp/image_loader_bmp.cpp2
-rw-r--r--modules/bmp/image_loader_bmp.h2
-rw-r--r--modules/csg/csg_shape.cpp4
-rw-r--r--modules/denoise/config.py9
-rw-r--r--modules/enet/doc_classes/ENetPacketPeer.xml12
-rw-r--r--modules/enet/enet_packet_peer.cpp2
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml10
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp4
-rw-r--r--modules/gdscript/editor/script_templates/CharacterBody2D/basic_movement.gd2
-rw-r--r--modules/gdscript/editor/script_templates/CharacterBody3D/basic_movement.gd2
-rw-r--r--modules/gdscript/gdscript_utility_functions.cpp8
-rw-r--r--modules/gltf/gltf_document.cpp8
-rw-r--r--modules/gltf/register_types.cpp4
-rw-r--r--modules/gltf/structures/gltf_camera.h2
-rw-r--r--modules/hdr/image_loader_hdr.cpp4
-rw-r--r--modules/hdr/image_loader_hdr.h2
-rw-r--r--modules/jpg/image_loader_jpegd.cpp2
-rw-r--r--modules/jpg/image_loader_jpegd.h2
-rw-r--r--modules/lightmapper_rd/lightmapper_rd.cpp4
-rw-r--r--modules/mono/build_scripts/mono_configure.py90
-rw-r--r--modules/mono/config.py4
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props1
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs111
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs11
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs1
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotMemberData.cs22
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs4
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs100
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs2
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs29
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs2
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs2
-rw-r--r--modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/GodotIdeMetadata.cs5
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs16
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs45
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs20
-rw-r--r--modules/mono/editor/bindings_generator.cpp82
-rw-r--r--modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs2
-rw-r--r--modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs11
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs182
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/DebuggingUtils.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs8
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs21
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs38
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs19
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs8
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs24
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs6
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs7
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj1
-rw-r--r--modules/mono/glue/runtime_interop.cpp16
-rw-r--r--modules/navigation/godot_navigation_server.cpp4
-rw-r--r--modules/navigation/godot_navigation_server.h2
-rw-r--r--modules/noise/config.py2
-rw-r--r--modules/noise/doc_classes/NoiseTexture2D.xml (renamed from modules/noise/doc_classes/NoiseTexture.xml)6
-rw-r--r--modules/noise/editor/noise_editor_plugin.cpp4
-rw-r--r--modules/noise/noise_texture_2d.cpp (renamed from modules/noise/noise_texture.cpp)130
-rw-r--r--modules/noise/noise_texture_2d.h (renamed from modules/noise/noise_texture.h)16
-rw-r--r--modules/noise/register_types.cpp5
-rw-r--r--modules/raycast/SCsub4
-rw-r--r--modules/raycast/config.py16
-rw-r--r--modules/svg/image_loader_svg.cpp4
-rw-r--r--modules/svg/image_loader_svg.h2
-rw-r--r--modules/text_server_adv/text_server_adv.cpp278
-rw-r--r--modules/text_server_adv/text_server_adv.h8
-rw-r--r--modules/text_server_fb/text_server_fb.cpp266
-rw-r--r--modules/text_server_fb/text_server_fb.h8
-rw-r--r--modules/tga/image_loader_tga.cpp2
-rw-r--r--modules/tga/image_loader_tga.h2
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp6
-rw-r--r--modules/tinyexr/image_loader_tinyexr.h2
-rw-r--r--modules/webp/image_loader_webp.cpp2
-rw-r--r--modules/webp/image_loader_webp.h2
93 files changed, 1226 insertions, 630 deletions
diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp
index 8813c3827a..ae03abca50 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, bool p_force_linear, float p_scale) {
+Error ImageLoaderBMP::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t 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 63dee0a969..cf8346ecad 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, bool p_force_linear, float p_scale);
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderBMP();
};
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index 243c23342e..6294790132 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -1838,7 +1838,7 @@ CSGBrush *CSGPolygon3D::_build_brush() {
u_step *= curve_length / path_u_distance;
}
double v_step = 1.0 / shape_sides;
- double spin_step = Math::deg2rad(spin_degrees / spin_sides);
+ double spin_step = Math::deg_to_rad(spin_degrees / spin_sides);
double extrusion_step = 1.0 / extrusions;
if (mode == MODE_PATH) {
if (path_joined) {
@@ -1902,7 +1902,7 @@ CSGBrush *CSGPolygon3D::_build_brush() {
}
}
- real_t angle_simplify_dot = Math::cos(Math::deg2rad(path_simplify_angle));
+ real_t angle_simplify_dot = Math::cos(Math::deg_to_rad(path_simplify_angle));
Vector3 previous_simplify_dir = Vector3(0, 0, 0);
int faces_combined = 0;
diff --git a/modules/denoise/config.py b/modules/denoise/config.py
index 521115dae5..350839651a 100644
--- a/modules/denoise/config.py
+++ b/modules/denoise/config.py
@@ -5,14 +5,7 @@ def can_build(env, platform):
# as doing lightmap generation and denoising on Android or HTML5
# would be a bit far-fetched.
desktop_platforms = ["linuxbsd", "macos", "windows"]
- supported_arch = env["bits"] == "64"
- if env["arch"] == "arm64":
- supported_arch = False
- if env["arch"].startswith("ppc"):
- supported_arch = False
- if env["arch"].startswith("rv"):
- supported_arch = False
- return env["tools"] and platform in desktop_platforms and supported_arch
+ return env["tools"] and platform in desktop_platforms and env["arch"] == "x86_64"
def configure(env):
diff --git a/modules/enet/doc_classes/ENetPacketPeer.xml b/modules/enet/doc_classes/ENetPacketPeer.xml
index 46008317a2..67760ba5e8 100644
--- a/modules/enet/doc_classes/ENetPacketPeer.xml
+++ b/modules/enet/doc_classes/ENetPacketPeer.xml
@@ -18,6 +18,18 @@
Returns the number of channels allocated for communication with peer.
</description>
</method>
+ <method name="get_remote_address" qualifiers="const">
+ <return type="String" />
+ <description>
+ Returns the IP address of this peer.
+ </description>
+ </method>
+ <method name="get_remote_port" qualifiers="const">
+ <return type="int" />
+ <description>
+ Returns the remote port of this peer.
+ </description>
+ </method>
<method name="get_state" qualifiers="const">
<return type="int" enum="ENetPacketPeer.PeerState" />
<description>
diff --git a/modules/enet/enet_packet_peer.cpp b/modules/enet/enet_packet_peer.cpp
index 62c0550edb..5a96f75c4f 100644
--- a/modules/enet/enet_packet_peer.cpp
+++ b/modules/enet/enet_packet_peer.cpp
@@ -206,6 +206,8 @@ void ENetPacketPeer::_bind_methods() {
ClassDB::bind_method(D_METHOD("send", "channel", "packet", "flags"), &ENetPacketPeer::_send);
ClassDB::bind_method(D_METHOD("throttle_configure", "interval", "acceleration", "deceleration"), &ENetPacketPeer::throttle_configure);
ClassDB::bind_method(D_METHOD("set_timeout", "timeout", "timeout_min", "timeout_max"), &ENetPacketPeer::set_timeout);
+ ClassDB::bind_method(D_METHOD("get_remote_address"), &ENetPacketPeer::get_remote_address);
+ ClassDB::bind_method(D_METHOD("get_remote_port"), &ENetPacketPeer::get_remote_port);
ClassDB::bind_method(D_METHOD("get_statistic", "statistic"), &ENetPacketPeer::get_statistic);
ClassDB::bind_method(D_METHOD("get_state"), &ENetPacketPeer::get_state);
ClassDB::bind_method(D_METHOD("get_channels"), &ENetPacketPeer::get_channels);
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index a44be04b2d..c2301c3e27 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -74,11 +74,11 @@
[/codeblock]
</description>
</method>
- <method name="dict2inst">
+ <method name="dict_to_inst">
<return type="Object" />
<param index="0" name="dictionary" type="Dictionary" />
<description>
- Converts a dictionary (previously created with [method inst2dict]) back to an instance. Useful for deserializing.
+ Converts a [param dictionary] (previously created with [method inst_to_dict]) back to an Object instance. Useful for deserializing.
</description>
</method>
<method name="get_stack">
@@ -102,15 +102,15 @@
[b]Note:[/b] Not supported for calling from threads. Instead, this will return an empty array.
</description>
</method>
- <method name="inst2dict">
+ <method name="inst_to_dict">
<return type="Dictionary" />
<param index="0" name="instance" type="Object" />
<description>
- Returns the passed instance converted to a dictionary (useful for serializing).
+ Returns the passed [param instance] converted to a Dictionary (useful for serializing).
[codeblock]
var foo = "bar"
func _ready():
- var d = inst2dict(self)
+ var d = inst_to_dict(self)
print(d.keys())
print(d.values())
[/codeblock]
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index 681aa45c8f..b9560ea69b 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -646,13 +646,13 @@ void GDScriptSyntaxHighlighter::_update_cache() {
node_path_color = Color(0.72, 0.77, 0.49);
node_ref_color = Color(0.39, 0.76, 0.35);
annotation_color = Color(1.0, 0.7, 0.45);
- string_name_color = Color(1.0, 0.66, 0.72);
+ string_name_color = Color(1.0, 0.76, 0.65);
} else {
function_definition_color = Color(0, 0.6, 0.6);
node_path_color = Color(0.18, 0.55, 0);
node_ref_color = Color(0.0, 0.5, 0);
annotation_color = Color(0.8, 0.37, 0);
- string_name_color = Color(0.8, 0.46, 0.52);
+ string_name_color = Color(0.8, 0.56, 0.45);
}
EDITOR_DEF("text_editor/theme/highlighting/gdscript/function_definition_color", function_definition_color);
diff --git a/modules/gdscript/editor/script_templates/CharacterBody2D/basic_movement.gd b/modules/gdscript/editor/script_templates/CharacterBody2D/basic_movement.gd
index a379d915a9..b8fc8c75dc 100644
--- a/modules/gdscript/editor/script_templates/CharacterBody2D/basic_movement.gd
+++ b/modules/gdscript/editor/script_templates/CharacterBody2D/basic_movement.gd
@@ -6,7 +6,7 @@ extends _BASE_
const SPEED = 300.0
const JUMP_VELOCITY = -400.0
-# Get the gravity from the project settings to be synced with RigidDynamicBody nodes.
+# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity")
diff --git a/modules/gdscript/editor/script_templates/CharacterBody3D/basic_movement.gd b/modules/gdscript/editor/script_templates/CharacterBody3D/basic_movement.gd
index 360b199e56..53bc606c9a 100644
--- a/modules/gdscript/editor/script_templates/CharacterBody3D/basic_movement.gd
+++ b/modules/gdscript/editor/script_templates/CharacterBody3D/basic_movement.gd
@@ -6,7 +6,7 @@ extends _BASE_
const SPEED = 5.0
const JUMP_VELOCITY = 4.5
-# Get the gravity from the project settings to be synced with RigidDynamicBody nodes.
+# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")
diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp
index 38893a422d..bcbe8b8d2b 100644
--- a/modules/gdscript/gdscript_utility_functions.cpp
+++ b/modules/gdscript/gdscript_utility_functions.cpp
@@ -262,7 +262,7 @@ struct GDScriptUtilityFunctionsDefinitions {
}
}
- static inline void inst2dict(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
+ static inline void inst_to_dict(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() == Variant::NIL) {
@@ -329,7 +329,7 @@ struct GDScriptUtilityFunctionsDefinitions {
}
}
- static inline void dict2inst(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
+ static inline void dict_to_inst(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() != Variant::DICTIONARY) {
@@ -653,8 +653,8 @@ void GDScriptUtilityFunctions::register_functions() {
REGISTER_VARARG_FUNC(str, true, Variant::STRING);
REGISTER_VARARG_FUNC(range, false, Variant::ARRAY);
REGISTER_CLASS_FUNC(load, false, "Resource", ARG("path", Variant::STRING));
- REGISTER_FUNC(inst2dict, false, Variant::DICTIONARY, ARG("instance", Variant::OBJECT));
- REGISTER_FUNC(dict2inst, false, Variant::OBJECT, ARG("dictionary", Variant::DICTIONARY));
+ REGISTER_FUNC(inst_to_dict, false, Variant::DICTIONARY, ARG("instance", Variant::OBJECT));
+ REGISTER_FUNC(dict_to_inst, false, Variant::OBJECT, ARG("dictionary", Variant::DICTIONARY));
REGISTER_FUNC_DEF(Color8, true, 255, Variant::COLOR, ARG("r8", Variant::INT), ARG("g8", Variant::INT), ARG("b8", Variant::INT), ARG("a8", Variant::INT));
REGISTER_VARARG_FUNC(print_debug, false, Variant::NIL);
REGISTER_FUNC_NO_ARGS(print_stack, false, Variant::NIL);
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index b913a771e1..87ba1d9869 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -5176,7 +5176,7 @@ Node3D *GLTFDocument::_generate_light(Ref<GLTFState> state, const GLTFNodeIndex
SpotLight3D *light = memnew(SpotLight3D);
light->set_param(SpotLight3D::PARAM_ENERGY, intensity);
light->set_param(SpotLight3D::PARAM_RANGE, range);
- light->set_param(SpotLight3D::PARAM_SPOT_ANGLE, Math::rad2deg(l->outer_cone_angle));
+ light->set_param(SpotLight3D::PARAM_SPOT_ANGLE, Math::rad_to_deg(l->outer_cone_angle));
light->set_color(l->color);
// Line of best fit derived from guessing, see https://www.desmos.com/calculator/biiflubp8b
@@ -5200,7 +5200,7 @@ Camera3D *GLTFDocument::_generate_camera(Ref<GLTFState> state, const GLTFNodeInd
Ref<GLTFCamera> c = state->cameras[gltf_node->camera];
camera->set_projection(c->get_perspective() ? Camera3D::PROJECTION_PERSPECTIVE : Camera3D::PROJECTION_ORTHOGONAL);
// GLTF spec (yfov) is in radians, Godot's camera (fov) is in degrees.
- camera->set_fov(Math::rad2deg(c->get_fov()));
+ camera->set_fov(Math::rad_to_deg(c->get_fov()));
// GLTF spec (xmag and ymag) is a radius in meters, Godot's camera (size) is a diameter in meters.
camera->set_size(c->get_size_mag() * 2.0f);
camera->set_near(c->get_depth_near());
@@ -5215,7 +5215,7 @@ GLTFCameraIndex GLTFDocument::_convert_camera(Ref<GLTFState> state, Camera3D *p_
c.instantiate();
c->set_perspective(p_camera->get_projection() == Camera3D::ProjectionType::PROJECTION_PERSPECTIVE);
// GLTF spec (yfov) is in radians, Godot's camera (fov) is in degrees.
- c->set_fov(Math::deg2rad(p_camera->get_fov()));
+ c->set_fov(Math::deg_to_rad(p_camera->get_fov()));
// GLTF spec (xmag and ymag) is a radius in meters, Godot's camera (size) is a diameter in meters.
c->set_size_mag(p_camera->get_size() * 0.5f);
c->set_depth_far(p_camera->get_far());
@@ -5246,7 +5246,7 @@ GLTFLightIndex GLTFDocument::_convert_light(Ref<GLTFState> state, Light3D *p_lig
SpotLight3D *light = cast_to<SpotLight3D>(p_light);
l->range = light->get_param(SpotLight3D::PARAM_RANGE);
l->intensity = light->get_param(SpotLight3D::PARAM_ENERGY);
- l->outer_cone_angle = Math::deg2rad(light->get_param(SpotLight3D::PARAM_SPOT_ANGLE));
+ l->outer_cone_angle = Math::deg_to_rad(light->get_param(SpotLight3D::PARAM_SPOT_ANGLE));
// This equation is the inverse of the import equation (which has a desmos link).
float angle_ratio = 1 - (0.2 / (0.1 + light->get_param(SpotLight3D::PARAM_SPOT_ATTENUATION)));
diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp
index cc1ca9131d..dbbccc9bcc 100644
--- a/modules/gltf/register_types.cpp
+++ b/modules/gltf/register_types.cpp
@@ -73,8 +73,8 @@ static void _editor_init() {
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
if (blender3_path.is_empty()) {
WARN_PRINT("Blend file import is enabled in the project settings, but no Blender path is configured in the editor settings. Blend files will not be imported.");
- } else if (!da->file_exists(blender3_path)) {
- WARN_PRINT("Blend file import is enabled, but the Blender path doesn't point to an accessible file. Blend files will not be imported.");
+ } else if (!da->dir_exists(blender3_path)) {
+ WARN_PRINT("Blend file import is enabled, but the Blender path doesn't point to an accessible directory. Blend files will not be imported.");
} else {
Ref<EditorSceneFormatImporterBlend> importer;
importer.instantiate();
diff --git a/modules/gltf/structures/gltf_camera.h b/modules/gltf/structures/gltf_camera.h
index 714ec21693..8e528c063f 100644
--- a/modules/gltf/structures/gltf_camera.h
+++ b/modules/gltf/structures/gltf_camera.h
@@ -44,7 +44,7 @@ private:
// GLTF has no default camera values, they should always be specified in
// the GLTF file. Here we default to Godot's default camera settings.
bool perspective = true;
- real_t fov = Math::deg2rad(75.0);
+ real_t fov = Math::deg_to_rad(75.0);
real_t size_mag = 0.5;
real_t depth_far = 4000.0;
real_t depth_near = 0.05;
diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp
index eca689e87a..e7c6fe592d 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, bool p_force_linear, float p_scale) {
+Error ImageLoaderHDR::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t 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 + ".");
@@ -131,7 +131,7 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_f
ptr[1] * exp / 255.0,
ptr[2] * exp / 255.0);
- if (p_force_linear) {
+ if (p_flags & FLAG_FORCE_LINEAR) {
c = c.srgb_to_linear();
}
diff --git a/modules/hdr/image_loader_hdr.h b/modules/hdr/image_loader_hdr.h
index 16c0816562..1bff05129b 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, bool p_force_linear, float p_scale);
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderHDR();
};
diff --git a/modules/jpg/image_loader_jpegd.cpp b/modules/jpg/image_loader_jpegd.cpp
index 0e03fa65c8..3e138bf633 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, bool p_force_linear, float p_scale) {
+Error ImageLoaderJPG::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t 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 6d631446e7..caa0461d05 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, bool p_force_linear, float p_scale);
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderJPG();
};
diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp
index 83ac478a97..2dcf644a06 100644
--- a/modules/lightmapper_rd/lightmapper_rd.cpp
+++ b/modules/lightmapper_rd/lightmapper_rd.cpp
@@ -62,7 +62,7 @@ void LightmapperRD::add_directional_light(bool p_static, const Vector3 &p_direct
l.color[2] = p_color.b;
l.energy = p_energy;
l.static_bake = p_static;
- l.size = Math::tan(Math::deg2rad(p_angular_distance));
+ l.size = Math::tan(Math::deg_to_rad(p_angular_distance));
l.shadow_blur = p_shadow_blur;
lights.push_back(l);
}
@@ -96,7 +96,7 @@ void LightmapperRD::add_spot_light(bool p_static, const Vector3 &p_position, con
l.direction[2] = p_direction.z;
l.range = p_range;
l.attenuation = p_attenuation;
- l.cos_spot_angle = Math::cos(Math::deg2rad(p_spot_angle));
+ l.cos_spot_angle = Math::cos(Math::deg_to_rad(p_spot_angle));
l.inv_spot_attenuation = 1.0f / p_spot_attenuation;
l.color[0] = p_color.r;
l.color[1] = p_color.g;
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py
index c7f9b39b48..3277f9beeb 100644
--- a/modules/mono/build_scripts/mono_configure.py
+++ b/modules/mono/build_scripts/mono_configure.py
@@ -3,11 +3,11 @@ import os.path
def is_desktop(platform):
- return platform in ["windows", "macos", "linuxbsd", "server", "uwp", "haiku"]
+ return platform in ["windows", "macos", "linuxbsd", "uwp", "haiku"]
def is_unix_like(platform):
- return platform in ["macos", "linuxbsd", "server", "android", "haiku", "ios"]
+ return platform in ["macos", "linuxbsd", "android", "haiku", "ios"]
def module_supports_tools_on(platform):
@@ -18,7 +18,7 @@ def configure(env, env_mono):
# is_android = env["platform"] == "android"
# is_javascript = env["platform"] == "javascript"
# is_ios = env["platform"] == "ios"
- # is_ios_sim = is_ios and env["arch"] in ["x86", "x86_64"]
+ # is_ios_sim = is_ios and env["arch"] in ["x86_32", "x86_64"]
tools_enabled = env["tools"]
@@ -82,7 +82,7 @@ def find_dotnet_app_host_dir(env):
dotnet_root = env["dotnet_root"]
if not dotnet_root:
- dotnet_cmd = find_executable("dotnet")
+ dotnet_cmd = find_dotnet_executable(env["arch"])
if dotnet_cmd:
sdk_path = find_dotnet_sdk(dotnet_cmd, dotnet_version)
if sdk_path:
@@ -128,27 +128,22 @@ def find_dotnet_app_host_dir(env):
def determine_runtime_identifier(env):
+ # The keys are Godot's names, the values are the Microsoft's names.
+ # List: https://docs.microsoft.com/en-us/dotnet/core/rid-catalog
names_map = {
"windows": "win",
"macos": "osx",
"linuxbsd": "linux",
- "server": "linux", # FIXME: Is server linux only, or also macos?
}
-
- # .NET RID architectures: x86, x64, arm, or arm64
-
+ arch_map = {
+ "x86_64": "x64",
+ "x86_32": "x86",
+ "arm64": "arm64",
+ "arm32": "arm",
+ }
platform = env["platform"]
-
if is_desktop(platform):
- if env["arch"] in ["arm", "arm32"]:
- rid = "arm"
- elif env["arch"] == "arm64":
- rid = "arm64"
- else:
- bits = env["bits"]
- bit_arch_map = {"64": "x64", "32": "x86"}
- rid = bit_arch_map[bits]
- return "%s-%s" % (names_map[platform], rid)
+ return "%s-%s" % (names_map[platform], arch_map[env["arch"]])
else:
raise NotImplementedError()
@@ -186,6 +181,35 @@ def find_app_host_version(dotnet_cmd, search_version_str):
return ""
+def find_dotnet_arch(dotnet_cmd):
+ import subprocess
+
+ try:
+ env = dict(os.environ, DOTNET_CLI_UI_LANGUAGE="en-US")
+ lines = subprocess.check_output([dotnet_cmd, "--info"], env=env).splitlines()
+
+ for line_bytes in lines:
+ line = line_bytes.decode("utf-8")
+
+ parts = line.split(":", 1)
+ if len(parts) < 2:
+ continue
+
+ arch_str = parts[0].strip()
+ if arch_str != "Architecture":
+ continue
+
+ arch_value = parts[1].strip()
+ arch_map = {"x64": "x86_64", "x86": "x86_32", "arm64": "arm64", "arm32": "arm32"}
+ return arch_map[arch_value]
+ except (subprocess.CalledProcessError, OSError) as e:
+ import sys
+
+ print(e, file=sys.stderr)
+
+ return ""
+
+
def find_dotnet_sdk(dotnet_cmd, search_version_str):
import subprocess
from distutils.version import LooseVersion
@@ -248,24 +272,44 @@ def find_dotnet_cli_rid(dotnet_cmd):
ENV_PATH_SEP = ";" if os.name == "nt" else ":"
-def find_executable(name):
+def find_dotnet_executable(arch):
is_windows = os.name == "nt"
windows_exts = os.environ["PATHEXT"].split(ENV_PATH_SEP) if is_windows else None
path_dirs = os.environ["PATH"].split(ENV_PATH_SEP)
search_dirs = path_dirs + [os.getcwd()] # cwd is last in the list
+ for dir in path_dirs:
+ search_dirs += [
+ os.path.join(dir, "x64"),
+ os.path.join(dir, "x86"),
+ os.path.join(dir, "arm64"),
+ os.path.join(dir, "arm32"),
+ ] # search subfolders for cross compiling
+
+ # `dotnet --info` may not specify architecture. In such cases,
+ # we fallback to the first one we find without architecture.
+ sdk_path_unknown_arch = ""
+
for dir in search_dirs:
- path = os.path.join(dir, name)
+ path = os.path.join(dir, "dotnet")
if is_windows:
for extension in windows_exts:
path_with_ext = path + extension
if os.path.isfile(path_with_ext) and os.access(path_with_ext, os.X_OK):
- return path_with_ext
+ sdk_arch = find_dotnet_arch(path_with_ext)
+ if sdk_arch == arch or arch == "":
+ return path_with_ext
+ elif sdk_arch == "":
+ sdk_path_unknown_arch = path_with_ext
else:
if os.path.isfile(path) and os.access(path, os.X_OK):
- return path
+ sdk_arch = find_dotnet_arch(path)
+ if sdk_arch == arch or arch == "":
+ return path
+ elif sdk_arch == "":
+ sdk_path_unknown_arch = path
- return ""
+ return sdk_path_unknown_arch
diff --git a/modules/mono/config.py b/modules/mono/config.py
index d156877929..b599414a2c 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -1,6 +1,6 @@
-# Prior to .NET Core, we supported these: ["windows", "macos", "linuxbsd", "server", "android", "haiku", "javascript", "ios"]
+# Prior to .NET Core, we supported these: ["windows", "macos", "linuxbsd", "android", "haiku", "javascript", "ios"]
# Eventually support for each them should be added back (except Haiku if not supported by .NET Core)
-supported_platforms = ["windows", "macos", "linuxbsd", "server"]
+supported_platforms = ["windows", "macos", "linuxbsd"]
def can_build(env, platform):
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
index 652b9e8e43..ad41ab04d5 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.NET.Sdk/Sdk/Sdk.props
@@ -77,7 +77,6 @@
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'windows' ">GODOT_WINDOWS;GODOT_PC</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'linuxbsd' ">GODOT_LINUXBSD;GODOT_PC</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'macos' ">GODOT_OSX;GODOT_MACOS;GODOT_PC</GodotPlatformConstants>
- <GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'server' ">GODOT_SERVER;GODOT_PC</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'uwp' ">GODOT_UWP;GODOT_PC</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'haiku' ">GODOT_HAIKU;GODOT_PC</GodotPlatformConstants>
<GodotPlatformConstants Condition=" '$(GodotTargetPlatform)' == 'android' ">GODOT_ANDROID;GODOT_MOBILE</GodotPlatformConstants>
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
index 0f8b128da8..3dfa8000ba 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/Common.cs
@@ -1,6 +1,7 @@
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Diagnostics;
namespace Godot.SourceGenerators
{
@@ -19,7 +20,7 @@ namespace Godot.SourceGenerators
"must be declared with the partial modifier.";
context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor(id: "GODOT-G0001",
+ new DiagnosticDescriptor(id: "GD0001",
title: message,
messageFormat: message,
category: "Usage",
@@ -51,7 +52,7 @@ namespace Godot.SourceGenerators
"containing types must be declared with the partial modifier.";
context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor(id: "GODOT-G0002",
+ new DiagnosticDescriptor(id: "GD0002",
title: message,
messageFormat: message,
category: "Usage",
@@ -78,7 +79,7 @@ namespace Godot.SourceGenerators
" Remove the 'static' modifier or the '[Export]' attribute.";
context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor(id: "GODOT-G0101",
+ new DiagnosticDescriptor(id: "GD0101",
title: message,
messageFormat: message,
category: "Usage",
@@ -104,7 +105,7 @@ namespace Godot.SourceGenerators
string description = $"{message}. Use a supported type or remove the '[Export]' attribute.";
context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor(id: "GODOT-G0102",
+ new DiagnosticDescriptor(id: "GD0102",
title: message,
messageFormat: message,
category: "Usage",
@@ -132,7 +133,7 @@ namespace Godot.SourceGenerators
$"{message}. Exported properties must be writable.";
context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor(id: "GODOT-G0103",
+ new DiagnosticDescriptor(id: "GD0103",
title: message,
messageFormat: message,
category: "Usage",
@@ -156,7 +157,7 @@ namespace Godot.SourceGenerators
string description = $"{message}. Exported properties must be readable.";
context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor(id: "GODOT-G0104",
+ new DiagnosticDescriptor(id: "GD0104",
title: message,
messageFormat: message,
category: "Usage",
@@ -181,7 +182,7 @@ namespace Godot.SourceGenerators
string description = $"{message}. Rename the delegate accordingly or remove the '[Signal]' attribute.";
context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor(id: "GODOT-G0201",
+ new DiagnosticDescriptor(id: "GD0201",
title: message,
messageFormat: message,
category: "Usage",
@@ -205,7 +206,7 @@ namespace Godot.SourceGenerators
string description = $"{message}. Use supported types only or remove the '[Signal]' attribute.";
context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor(id: "GODOT-G0202",
+ new DiagnosticDescriptor(id: "GD0202",
title: message,
messageFormat: message,
category: "Usage",
@@ -229,7 +230,7 @@ namespace Godot.SourceGenerators
string description = $"{message}. Return void or remove the '[Signal]' attribute.";
context.ReportDiagnostic(Diagnostic.Create(
- new DiagnosticDescriptor(id: "GODOT-G0203",
+ new DiagnosticDescriptor(id: "GD0203",
title: message,
messageFormat: message,
category: "Usage",
@@ -239,5 +240,97 @@ namespace Godot.SourceGenerators
location,
location?.SourceTree?.FilePath));
}
+
+ public static readonly DiagnosticDescriptor GenericTypeArgumentMustBeVariantRule =
+ new DiagnosticDescriptor(id: "GD0301",
+ title: "The generic type argument must be a Variant compatible type",
+ messageFormat: "The generic type argument must be a Variant compatible type: {0}",
+ category: "Usage",
+ DiagnosticSeverity.Error,
+ isEnabledByDefault: true,
+ "The generic type argument must be a Variant compatible type. Use a Variant compatible type as the generic type argument.");
+
+ public static void ReportGenericTypeArgumentMustBeVariant(
+ SyntaxNodeAnalysisContext context,
+ SyntaxNode typeArgumentSyntax,
+ ISymbol typeArgumentSymbol)
+ {
+ string message = "The generic type argument " +
+ $"must be a Variant compatible type: '{typeArgumentSymbol.ToDisplayString()}'";
+
+ string description = $"{message}. Use a Variant compatible type as the generic type argument.";
+
+ context.ReportDiagnostic(Diagnostic.Create(
+ new DiagnosticDescriptor(id: "GD0301",
+ title: message,
+ messageFormat: message,
+ category: "Usage",
+ DiagnosticSeverity.Error,
+ isEnabledByDefault: true,
+ description),
+ typeArgumentSyntax.GetLocation(),
+ typeArgumentSyntax.SyntaxTree.FilePath));
+ }
+
+ public static readonly DiagnosticDescriptor GenericTypeParameterMustBeVariantAnnotatedRule =
+ new DiagnosticDescriptor(id: "GD0302",
+ title: "The generic type parameter must be annotated with the MustBeVariant attribute",
+ messageFormat: "The generic type argument must be a Variant type: {0}",
+ category: "Usage",
+ DiagnosticSeverity.Error,
+ isEnabledByDefault: true,
+ "The generic type argument must be a Variant type. Use a Variant type as the generic type argument.");
+
+ public static void ReportGenericTypeParameterMustBeVariantAnnotated(
+ SyntaxNodeAnalysisContext context,
+ SyntaxNode typeArgumentSyntax,
+ ISymbol typeArgumentSymbol)
+ {
+ string message = "The generic type parameter must be annotated with the MustBeVariant attribute";
+
+ string description = $"{message}. Add the MustBeVariant attribute to the generic type parameter.";
+
+ context.ReportDiagnostic(Diagnostic.Create(
+ new DiagnosticDescriptor(id: "GD0302",
+ title: message,
+ messageFormat: message,
+ category: "Usage",
+ DiagnosticSeverity.Error,
+ isEnabledByDefault: true,
+ description),
+ typeArgumentSyntax.GetLocation(),
+ typeArgumentSyntax.SyntaxTree.FilePath));
+ }
+
+ public static readonly DiagnosticDescriptor TypeArgumentParentSymbolUnhandledRule =
+ new DiagnosticDescriptor(id: "GD0303",
+ title: "The generic type parameter must be annotated with the MustBeVariant attribute",
+ messageFormat: "The generic type argument must be a Variant type: {0}",
+ category: "Usage",
+ DiagnosticSeverity.Error,
+ isEnabledByDefault: true,
+ "The generic type argument must be a Variant type. Use a Variant type as the generic type argument.");
+
+ public static void ReportTypeArgumentParentSymbolUnhandled(
+ SyntaxNodeAnalysisContext context,
+ SyntaxNode typeArgumentSyntax,
+ ISymbol parentSymbol)
+ {
+ string message = $"Symbol '{parentSymbol.ToDisplayString()}' parent of a type argument " +
+ "that must be Variant compatible was not handled.";
+
+ string description = $"{message}. Handle type arguments that are children of the unhandled symbol type.";
+
+ context.ReportDiagnostic(Diagnostic.Create(
+ new DiagnosticDescriptor(id: "GD0303",
+ title: message,
+ messageFormat: message,
+ category: "Usage",
+ DiagnosticSeverity.Error,
+ isEnabledByDefault: true,
+ description),
+ typeArgumentSyntax.GetLocation(),
+ typeArgumentSyntax.SyntaxTree.FilePath));
+ }
}
}
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 bac4708165..de3b6c862a 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ExtensionMethods.cs
@@ -177,6 +177,9 @@ namespace Godot.SourceGenerators
public static bool IsGodotSignalAttribute(this INamedTypeSymbol symbol)
=> symbol.ToString() == GodotClasses.SignalAttr;
+ public static bool IsGodotMustBeVariantAttribute(this INamedTypeSymbol symbol)
+ => symbol.ToString() == GodotClasses.MustBeVariantAttr;
+
public static bool IsGodotClassNameAttribute(this INamedTypeSymbol symbol)
=> symbol.ToString() == GodotClasses.GodotClassNameAttr;
@@ -272,5 +275,13 @@ namespace Godot.SourceGenerators
yield return new GodotFieldData(field, marshalType.Value);
}
}
+
+ public static string Path(this Location location)
+ => location.SourceTree?.GetLineSpan(location.SourceSpan).Path
+ ?? location.GetLineSpan().Path;
+
+ public static int StartLine(this Location location)
+ => location.SourceTree?.GetLineSpan(location.SourceSpan).StartLinePosition.Line
+ ?? location.GetLineSpan().StartLinePosition.Line;
}
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs
index e899440e10..1d8ddbabf2 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs
@@ -9,6 +9,7 @@ namespace Godot.SourceGenerators
public const string ExportGroupAttr = "Godot.ExportGroupAttribute";
public const string ExportSubgroupAttr = "Godot.ExportSubgroupAttribute";
public const string SignalAttr = "Godot.SignalAttribute";
+ public const string MustBeVariantAttr = "Godot.MustBeVariantAttribute";
public const string GodotClassNameAttr = "Godot.GodotClassName";
public const string SystemFlagsAttr = "System.FlagsAttribute";
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotMemberData.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotMemberData.cs
index a3ad8cbabd..db395e21cb 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotMemberData.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotMemberData.cs
@@ -59,4 +59,26 @@ namespace Godot.SourceGenerators
public IFieldSymbol FieldSymbol { get; }
public MarshalType Type { get; }
}
+
+ public struct GodotPropertyOrFieldData
+ {
+ public GodotPropertyOrFieldData(ISymbol symbol, MarshalType type)
+ {
+ Symbol = symbol;
+ Type = type;
+ }
+
+ public GodotPropertyOrFieldData(GodotPropertyData propertyData)
+ : this(propertyData.PropertySymbol, propertyData.Type)
+ {
+ }
+
+ public GodotPropertyOrFieldData(GodotFieldData fieldData)
+ : this(fieldData.FieldSymbol, fieldData.Type)
+ {
+ }
+
+ public ISymbol Symbol { get; }
+ public MarshalType Type { get; }
+ }
}
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 ca84518c0c..831ac3bdeb 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MarshalUtils.cs
@@ -11,11 +11,11 @@ namespace Godot.SourceGenerators
{
public INamedTypeSymbol GodotObjectType { get; }
- public TypeCache(GeneratorExecutionContext context)
+ public TypeCache(Compilation compilation)
{
INamedTypeSymbol GetTypeByMetadataNameOrThrow(string fullyQualifiedMetadataName)
{
- return context.Compilation.GetTypeByMetadataName(fullyQualifiedMetadataName) ??
+ return compilation.GetTypeByMetadataName(fullyQualifiedMetadataName) ??
throw new InvalidOperationException("Type not found: " + fullyQualifiedMetadataName);
}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs
new file mode 100644
index 0000000000..7aaadb27be
--- /dev/null
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/MustBeVariantAnalyzer.cs
@@ -0,0 +1,100 @@
+using System.Collections.Immutable;
+using System.Diagnostics;
+using System.Linq;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Diagnostics;
+
+namespace Godot.SourceGenerators
+{
+ [DiagnosticAnalyzer(LanguageNames.CSharp)]
+ public class MustBeVariantAnalyzer : DiagnosticAnalyzer
+ {
+ public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
+ => ImmutableArray.Create(
+ Common.GenericTypeArgumentMustBeVariantRule,
+ Common.GenericTypeParameterMustBeVariantAnnotatedRule,
+ Common.TypeArgumentParentSymbolUnhandledRule);
+
+ public override void Initialize(AnalysisContext context)
+ {
+ context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
+ context.EnableConcurrentExecution();
+ context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.TypeArgumentList);
+ }
+
+ private void AnalyzeNode(SyntaxNodeAnalysisContext context)
+ {
+ var typeArgListSyntax = (TypeArgumentListSyntax)context.Node;
+
+ // Method invocation or variable declaration that contained the type arguments
+ var parentSyntax = context.Node.Parent;
+ Debug.Assert(parentSyntax != null);
+
+ var sm = context.SemanticModel;
+
+ var typeCache = new MarshalUtils.TypeCache(context.Compilation);
+
+ for (int i = 0; i < typeArgListSyntax.Arguments.Count; i++)
+ {
+ var typeSyntax = typeArgListSyntax.Arguments[i];
+ var typeSymbol = sm.GetSymbolInfo(typeSyntax).Symbol as ITypeSymbol;
+ Debug.Assert(typeSymbol != null);
+
+ var parentSymbol = sm.GetSymbolInfo(parentSyntax).Symbol;
+
+ if (!ShouldCheckTypeArgument(context, parentSyntax, parentSymbol, typeSyntax, typeSymbol, i))
+ {
+ return;
+ }
+
+ if (typeSymbol is ITypeParameterSymbol typeParamSymbol)
+ {
+ if (!typeParamSymbol.GetAttributes().Any(a => a.AttributeClass?.IsGodotMustBeVariantAttribute() ?? false))
+ {
+ Common.ReportGenericTypeParameterMustBeVariantAnnotated(context, typeSyntax, typeSymbol);
+ }
+ continue;
+ }
+
+ var marshalType = MarshalUtils.ConvertManagedTypeToMarshalType(typeSymbol, typeCache);
+
+ if (marshalType == null)
+ {
+ Common.ReportGenericTypeArgumentMustBeVariant(context, typeSyntax, typeSymbol);
+ continue;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Check if the given type argument is being used in a type parameter that contains
+ /// the <c>MustBeVariantAttribute</c>; otherwise, we ignore the attribute.
+ /// </summary>
+ /// <param name="context">Context for a syntax node action.</param>
+ /// <param name="parentSyntax">The parent node syntax that contains the type node syntax.</param>
+ /// <param name="parentSymbol">The symbol retrieved for the parent node syntax.</param>
+ /// <param name="typeArgumentSyntax">The type node syntax of the argument type to check.</param>
+ /// <param name="typeArgumentSymbol">The symbol retrieved for the type node syntax.</param>
+ /// <returns><see langword="true"/> if the type must be variant and must be analyzed.</returns>
+ private bool ShouldCheckTypeArgument(SyntaxNodeAnalysisContext context, SyntaxNode parentSyntax, ISymbol parentSymbol, TypeSyntax typeArgumentSyntax, ITypeSymbol typeArgumentSymbol, int typeArgumentIndex)
+ {
+ var typeParamSymbol = parentSymbol switch
+ {
+ IMethodSymbol methodSymbol => methodSymbol.TypeParameters[typeArgumentIndex],
+ INamedTypeSymbol typeSymbol => typeSymbol.TypeParameters[typeArgumentIndex],
+ _ => null,
+ };
+
+ if (typeParamSymbol == null)
+ {
+ Common.ReportTypeArgumentParentSymbolUnhandled(context, typeArgumentSyntax, parentSymbol);
+ return false;
+ }
+
+ return typeParamSymbol.GetAttributes()
+ .Any(a => a.AttributeClass?.IsGodotMustBeVariantAttribute() ?? false);
+ }
+ }
+}
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs
index 1fdc04a262..5ac4f4a47e 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptMethodsGenerator.cs
@@ -49,7 +49,7 @@ namespace Godot.SourceGenerators
if (godotClasses.Length > 0)
{
- var typeCache = new MarshalUtils.TypeCache(context);
+ var typeCache = new MarshalUtils.TypeCache(context.Compilation);
foreach (var godotClass in godotClasses)
{
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
index b4db3fda62..7629595b3a 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs
@@ -49,7 +49,7 @@ namespace Godot.SourceGenerators
if (godotClasses.Length > 0)
{
- var typeCache = new MarshalUtils.TypeCache(context);
+ var typeCache = new MarshalUtils.TypeCache(context.Compilation);
foreach (var godotClass in godotClasses)
{
@@ -225,28 +225,21 @@ namespace Godot.SourceGenerators
.Append(dictionaryType)
.Append("();\n");
- foreach (var property in godotClassProperties)
- {
- foreach (var groupingInfo in DetermineGroupingPropertyInfo(property.PropertySymbol))
- AppendGroupingPropertyInfo(source, groupingInfo);
+ // To retain the definition order (and display categories correctly), we want to
+ // iterate over fields and properties at the same time, sorted by line number.
+ var godotClassPropertiesAndFields = Enumerable.Empty<GodotPropertyOrFieldData>()
+ .Concat(godotClassProperties.Select(propertyData => new GodotPropertyOrFieldData(propertyData)))
+ .Concat(godotClassFields.Select(fieldData => new GodotPropertyOrFieldData(fieldData)))
+ .OrderBy(data => data.Symbol.Locations[0].Path())
+ .ThenBy(data => data.Symbol.Locations[0].StartLine());
- var propertyInfo = DeterminePropertyInfo(context, typeCache,
- property.PropertySymbol, property.Type);
-
- if (propertyInfo == null)
- continue;
-
- AppendPropertyInfo(source, propertyInfo.Value);
- }
-
- foreach (var field in godotClassFields)
+ foreach (var member in godotClassPropertiesAndFields)
{
-
- foreach (var groupingInfo in DetermineGroupingPropertyInfo(field.FieldSymbol))
+ foreach (var groupingInfo in DetermineGroupingPropertyInfo(member.Symbol))
AppendGroupingPropertyInfo(source, groupingInfo);
var propertyInfo = DeterminePropertyInfo(context, typeCache,
- field.FieldSymbol, field.Type);
+ member.Symbol, member.Type);
if (propertyInfo == null)
continue;
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
index 3b8ba21107..85fadaa52e 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertyDefValGenerator.cs
@@ -49,7 +49,7 @@ namespace Godot.SourceGenerators
if (godotClasses.Length > 0)
{
- var typeCache = new MarshalUtils.TypeCache(context);
+ var typeCache = new MarshalUtils.TypeCache(context.Compilation);
foreach (var godotClass in godotClasses)
{
diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
index 1b87c6e760..5a84122c4c 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSerializationGenerator.cs
@@ -49,7 +49,7 @@ namespace Godot.SourceGenerators
if (godotClasses.Length > 0)
{
- var typeCache = new MarshalUtils.TypeCache(context);
+ var typeCache = new MarshalUtils.TypeCache(context.Compilation);
foreach (var godotClass in godotClasses)
{
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 f1c7706f9c..6b06f10db1 100644
--- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
+++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptSignalsGenerator.cs
@@ -56,7 +56,7 @@ namespace Godot.SourceGenerators
if (godotClasses.Length > 0)
{
- var typeCache = new MarshalUtils.TypeCache(context);
+ var typeCache = new MarshalUtils.TypeCache(context.Compilation);
foreach (var godotClass in godotClasses)
{
@@ -117,10 +117,6 @@ namespace Godot.SourceGenerators
source.Append(symbol.NameWithTypeParameters());
source.Append("\n{\n");
- // TODO:
- // The delegate name already needs to end with 'Signal' to avoid collision with the event name.
- // Requiring SignalAttribute is redundant. Should we remove it to make declaration shorter?
-
var members = symbol.GetMembers();
var signalDelegateSymbols = members
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/GodotIdeMetadata.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/GodotIdeMetadata.cs
index 686202e81e..2448a2953b 100644
--- a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/GodotIdeMetadata.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/GodotIdeMetadata.cs
@@ -25,10 +25,7 @@ namespace GodotTools.IdeMessaging
public override bool Equals(object obj)
{
- if (obj is GodotIdeMetadata metadata)
- return metadata == this;
-
- return false;
+ return obj is GodotIdeMetadata metadata && metadata == this;
}
public bool Equals(GodotIdeMetadata other)
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs
index 3c5b897719..edbf53a389 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildInfo.cs
@@ -27,15 +27,13 @@ namespace GodotTools.Build
public override bool Equals(object? obj)
{
- if (obj is BuildInfo other)
- return other.Solution == Solution &&
- other.Configuration == Configuration && other.RuntimeIdentifier == RuntimeIdentifier &&
- other.PublishOutputDir == PublishOutputDir && other.Restore == Restore &&
- other.Rebuild == Rebuild && other.OnlyClean == OnlyClean &&
- other.CustomProperties == CustomProperties &&
- other.LogsDirPath == LogsDirPath;
-
- return false;
+ return obj is BuildInfo other &&
+ other.Solution == Solution &&
+ other.Configuration == Configuration && other.RuntimeIdentifier == RuntimeIdentifier &&
+ other.PublishOutputDir == PublishOutputDir && other.Restore == Restore &&
+ other.Rebuild == Rebuild && other.OnlyClean == OnlyClean &&
+ other.CustomProperties == CustomProperties &&
+ other.LogsDirPath == LogsDirPath;
}
public override int GetHashCode()
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
index 87549f61fe..fc325fc25b 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
@@ -75,8 +75,17 @@ namespace GodotTools.Export
}
else
{
- string bits = features.Contains("64") ? "64" : features.Contains("32") ? "32" : null;
- CompileAssembliesForDesktop(exporter, platform, isDebug, bits, aotOpts, aotTempDir, outputDataDir, assembliesPrepared, bclDir);
+ string arch = "";
+ if (features.Contains("x86_64")) {
+ arch = "x86_64";
+ } else if (features.Contains("x86_32")) {
+ arch = "x86_32";
+ } else if (features.Contains("arm64")) {
+ arch = "arm64";
+ } else if (features.Contains("arm32")) {
+ arch = "arm32";
+ }
+ CompileAssembliesForDesktop(exporter, platform, isDebug, arch, aotOpts, aotTempDir, outputDataDir, assembliesPrepared, bclDir);
}
}
@@ -112,7 +121,7 @@ namespace GodotTools.Export
}
}
- public static void CompileAssembliesForDesktop(ExportPlugin exporter, string platform, bool isDebug, string bits, AotOptions aotOpts, string aotTempDir, string outputDataDir, IDictionary<string, string> assemblies, string bclDir)
+ public static void CompileAssembliesForDesktop(ExportPlugin exporter, string platform, bool isDebug, string arch, AotOptions aotOpts, string aotTempDir, string outputDataDir, IDictionary<string, string> assemblies, string bclDir)
{
foreach (var assembly in assemblies)
{
@@ -126,9 +135,9 @@ namespace GodotTools.Export
string outputFileName = assemblyName + ".dll" + outputFileExtension;
string tempOutputFilePath = Path.Combine(aotTempDir, outputFileName);
- var compilerArgs = GetAotCompilerArgs(platform, isDebug, bits, aotOpts, assemblyPath, tempOutputFilePath);
+ var compilerArgs = GetAotCompilerArgs(platform, isDebug, arch, aotOpts, assemblyPath, tempOutputFilePath);
- string compilerDirPath = GetMonoCrossDesktopDirName(platform, bits);
+ string compilerDirPath = GetMonoCrossDesktopDirName(platform, arch);
ExecuteCompiler(FindCrossCompiler(compilerDirPath), compilerArgs, bclDir);
@@ -432,9 +441,9 @@ MONO_AOT_MODE_LAST = 1000,
var androidToolPrefixes = new Dictionary<string, string>
{
- ["armeabi-v7a"] = "arm-linux-androideabi-",
- ["arm64-v8a"] = "aarch64-linux-android-",
- ["x86"] = "i686-linux-android-",
+ ["arm32"] = "arm-linux-androideabi-",
+ ["arm64"] = "aarch64-linux-android-",
+ ["x86_32"] = "i686-linux-android-",
["x86_64"] = "x86_64-linux-android-"
};
@@ -547,9 +556,9 @@ MONO_AOT_MODE_LAST = 1000,
{
var androidAbis = new[]
{
- "armeabi-v7a",
- "arm64-v8a",
- "x86",
+ "arm32",
+ "arm64",
+ "x86_32",
"x86_64"
};
@@ -560,9 +569,9 @@ MONO_AOT_MODE_LAST = 1000,
{
var abiArchs = new Dictionary<string, string>
{
- ["armeabi-v7a"] = "armv7",
- ["arm64-v8a"] = "aarch64-v8a",
- ["x86"] = "i686",
+ ["arm32"] = "armv7",
+ ["arm64"] = "aarch64-v8a",
+ ["x86_32"] = "i686",
["x86_64"] = "x86_64"
};
@@ -571,31 +580,25 @@ MONO_AOT_MODE_LAST = 1000,
return $"{arch}-linux-android";
}
- private static string GetMonoCrossDesktopDirName(string platform, string bits)
+ private static string GetMonoCrossDesktopDirName(string platform, string arch)
{
switch (platform)
{
case OS.Platforms.Windows:
case OS.Platforms.UWP:
{
- string arch = bits == "64" ? "x86_64" : "i686";
return $"windows-{arch}";
}
case OS.Platforms.MacOS:
{
- Debug.Assert(bits == null || bits == "64");
- string arch = "x86_64";
return $"{platform}-{arch}";
}
case OS.Platforms.LinuxBSD:
- case OS.Platforms.Server:
{
- string arch = bits == "64" ? "x86_64" : "i686";
return $"linux-{arch}";
}
case OS.Platforms.Haiku:
{
- string arch = bits == "64" ? "x86_64" : "i686";
return $"{platform}-{arch}";
}
default:
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
index ecf363c106..e1b5530b93 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
@@ -100,7 +100,7 @@ namespace GodotTools.Export
if (!DeterminePlatformFromFeatures(features, out string platform))
throw new NotSupportedException("Target platform not supported");
- if (!new[] { OS.Platforms.Windows, OS.Platforms.LinuxBSD, OS.Platforms.MacOS, OS.Platforms.Server }
+ if (!new[] { OS.Platforms.Windows, OS.Platforms.LinuxBSD, OS.Platforms.MacOS }
.Contains(platform))
{
throw new NotImplementedException("Target platform not yet implemented");
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
index 62140d41bc..651922d019 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
@@ -15,6 +15,9 @@ namespace GodotTools.Utils
[SuppressMessage("ReSharper", "InconsistentNaming")]
public static class OS
{
+ /// <summary>
+ /// Display names for the OS platforms.
+ /// </summary>
private static class Names
{
public const string Windows = "Windows";
@@ -23,7 +26,6 @@ namespace GodotTools.Utils
public const string FreeBSD = "FreeBSD";
public const string NetBSD = "NetBSD";
public const string BSD = "BSD";
- public const string Server = "Server";
public const string UWP = "UWP";
public const string Haiku = "Haiku";
public const string Android = "Android";
@@ -31,12 +33,14 @@ namespace GodotTools.Utils
public const string HTML5 = "HTML5";
}
+ /// <summary>
+ /// Godot platform identifiers.
+ /// </summary>
public static class Platforms
{
public const string Windows = "windows";
public const string MacOS = "macos";
public const string LinuxBSD = "linuxbsd";
- public const string Server = "server";
public const string UWP = "uwp";
public const string Haiku = "haiku";
public const string Android = "android";
@@ -44,6 +48,10 @@ namespace GodotTools.Utils
public const string HTML5 = "javascript";
}
+ /// <summary>
+ /// OS name part of the .NET runtime identifier (RID).
+ /// See https://docs.microsoft.com/en-us/dotnet/core/rid-catalog.
+ /// </summary>
public static class DotNetOS
{
public const string Win = "win";
@@ -65,7 +73,6 @@ namespace GodotTools.Utils
["LinuxBSD"] = Platforms.LinuxBSD,
// "X11" for compatibility, temporarily, while we are on an outdated branch
["X11"] = Platforms.LinuxBSD,
- ["Server"] = Platforms.Server,
["UWP"] = Platforms.UWP,
["Haiku"] = Platforms.Haiku,
["Android"] = Platforms.Android,
@@ -81,7 +88,6 @@ namespace GodotTools.Utils
[Names.FreeBSD] = Platforms.LinuxBSD,
[Names.NetBSD] = Platforms.LinuxBSD,
[Names.BSD] = Platforms.LinuxBSD,
- [Names.Server] = Platforms.Server,
[Names.UWP] = Platforms.UWP,
[Names.Haiku] = Platforms.Haiku,
[Names.Android] = Platforms.Android,
@@ -98,7 +104,6 @@ namespace GodotTools.Utils
// instead of `linux` in the runtime identifier. This would be a problem as
// Godot has a single export profile for both, named LinuxBSD.
[Platforms.LinuxBSD] = DotNetOS.Linux,
- [Platforms.Server] = DotNetOS.Linux,
[Platforms.UWP] = DotNetOS.Win10,
[Platforms.Android] = DotNetOS.Android,
[Platforms.iOS] = DotNetOS.iOS,
@@ -129,13 +134,12 @@ namespace GodotTools.Utils
new[] { Names.Linux, Names.FreeBSD, Names.NetBSD, Names.BSD };
private static readonly IEnumerable<string> UnixLikePlatforms =
- new[] { Names.MacOS, Names.Server, Names.Haiku, Names.Android, Names.iOS }
+ new[] { Names.MacOS, Names.Haiku, Names.Android, Names.iOS }
.Concat(LinuxBSDPlatforms).ToArray();
private static readonly Lazy<bool> _isWindows = new(() => IsOS(Names.Windows));
private static readonly Lazy<bool> _isMacOS = new(() => IsOS(Names.MacOS));
private static readonly Lazy<bool> _isLinuxBSD = new(() => IsAnyOS(LinuxBSDPlatforms));
- private static readonly Lazy<bool> _isServer = new(() => IsOS(Names.Server));
private static readonly Lazy<bool> _isUWP = new(() => IsOS(Names.UWP));
private static readonly Lazy<bool> _isHaiku = new(() => IsOS(Names.Haiku));
private static readonly Lazy<bool> _isAndroid = new(() => IsOS(Names.Android));
@@ -149,8 +153,6 @@ namespace GodotTools.Utils
[SupportedOSPlatformGuard("linux")] public static bool IsLinuxBSD => _isLinuxBSD.Value;
- [SupportedOSPlatformGuard("linux")] public static bool IsServer => _isServer.Value;
-
[SupportedOSPlatformGuard("windows")] public static bool IsUWP => _isUWP.Value;
public static bool IsHaiku => _isHaiku.Value;
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 73d8f23081..d70a1e6c88 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -87,9 +87,7 @@ StringBuilder &operator<<(StringBuilder &r_sb, const char *p_cstring) {
#define CS_STATIC_FIELD_NATIVE_CTOR "NativeCtor"
#define CS_STATIC_FIELD_METHOD_BIND_PREFIX "MethodBind"
-#define CS_STATIC_FIELD_METHOD_NAME_PREFIX "MethodName_"
#define CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX "MethodProxyName_"
-#define CS_STATIC_FIELD_SIGNAL_NAME_PREFIX "SignalName_"
#define ICALL_PREFIX "godot_icall_"
#define ICALL_CLASSDB_GET_METHOD "ClassDB_get_method"
@@ -1606,12 +1604,6 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output << MEMBER_BEGIN "// ReSharper disable once InconsistentNaming\n"
<< INDENT1 "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n"
<< INDENT1 "private static readonly StringName "
- << CS_STATIC_FIELD_METHOD_NAME_PREFIX << imethod.name
- << " = \"" << imethod.name << "\";\n";
-
- output << MEMBER_BEGIN "// ReSharper disable once InconsistentNaming\n"
- << INDENT1 "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n"
- << INDENT1 "private static readonly StringName "
<< CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX << imethod.name
<< " = \"" << imethod.proxy_name << "\";\n";
}
@@ -1637,7 +1629,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
// We check both native names (snake_case) and proxy names (PascalCase)
output << INDENT2 "if ((method == " << CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX << imethod.name
- << " || method == " << CS_STATIC_FIELD_METHOD_NAME_PREFIX << imethod.name
+ << " || method == MethodName." << imethod.proxy_name
<< ") && argCount == " << itos(imethod.arguments.size())
<< " && " << CS_METHOD_HAS_GODOT_CLASS_METHOD << "((godot_string_name)"
<< CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX << imethod.name << ".NativeValue))\n"
@@ -1713,7 +1705,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
// again, but this time with the respective proxy name (PascalCase). It's the job of
// user derived classes to override the method and check for those. Our C# source
// generators take care of generating those override methods.
- output << INDENT2 "if (method == " << CS_STATIC_FIELD_METHOD_NAME_PREFIX << imethod.name
+ output << INDENT2 "if (method == MethodName." << imethod.proxy_name
<< ")\n" INDENT2 "{\n"
<< INDENT3 "if (" CS_METHOD_HAS_GODOT_CLASS_METHOD "("
<< CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX << imethod.name
@@ -1731,6 +1723,45 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output << INDENT1 "}\n";
}
+ //Generate StringName for all class members
+ bool is_inherit = !itype.is_singleton && obj_types.has(itype.base_name);
+ //PropertyName
+ if (is_inherit) {
+ output << MEMBER_BEGIN "public new class PropertyName : " << obj_types[itype.base_name].proxy_name << ".PropertyName";
+ } else {
+ output << MEMBER_BEGIN "public class PropertyName";
+ }
+ output << "\n"
+ << INDENT1 "{\n";
+ for (const PropertyInterface &iprop : itype.properties) {
+ output << INDENT2 "public static readonly StringName " << iprop.proxy_name << " = \"" << iprop.cname << "\";\n";
+ }
+ output << INDENT1 "}\n";
+ //MethodName
+ if (is_inherit) {
+ output << MEMBER_BEGIN "public new class MethodName : " << obj_types[itype.base_name].proxy_name << ".MethodName";
+ } else {
+ output << MEMBER_BEGIN "public class MethodName";
+ }
+ output << "\n"
+ << INDENT1 "{\n";
+ for (const MethodInterface &imethod : itype.methods) {
+ output << INDENT2 "public static readonly StringName " << imethod.proxy_name << " = \"" << imethod.cname << "\";\n";
+ }
+ output << INDENT1 "}\n";
+ //SignalName
+ if (is_inherit) {
+ output << MEMBER_BEGIN "public new class SignalName : " << obj_types[itype.base_name].proxy_name << ".SignalName";
+ } else {
+ output << MEMBER_BEGIN "public class SignalName";
+ }
+ output << "\n"
+ << INDENT1 "{\n";
+ for (const SignalInterface &isignal : itype.signals_) {
+ output << INDENT2 "public static readonly StringName " << isignal.proxy_name << " = \"" << isignal.cname << "\";\n";
+ }
+ output << INDENT1 "}\n";
+
output.append(CLOSE_BLOCK /* class */);
output.append("\n"
@@ -2052,9 +2083,9 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
p_output << "Object.";
}
- p_output << ICALL_CLASSDB_GET_METHOD "(" BINDINGS_NATIVE_NAME_FIELD ", \""
- << p_imethod.name
- << "\");\n";
+ p_output << ICALL_CLASSDB_GET_METHOD "(" BINDINGS_NATIVE_NAME_FIELD ", MethodName."
+ << p_imethod.proxy_name
+ << ");\n";
}
if (p_imethod.method_doc && p_imethod.method_doc->description.size()) {
@@ -2226,7 +2257,7 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
}
String delegate_name = p_isignal.proxy_name;
- delegate_name += "Handler"; // Delegate name is [SignalName]Handler
+ delegate_name += "EventHandler"; // Delegate name is [SignalName]EventHandler
// Generate delegate
p_output.append(MEMBER_BEGIN "public delegate void ");
@@ -2239,17 +2270,8 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
// Could we assume the StringName instance of signal name will never be freed (it's stored in ClassDB) before the managed world is unloaded?
// If so, we could store the pointer we get from `data_unique_pointer()` instead of allocating StringName here.
- // Cached signal name (StringName)
- p_output.append(MEMBER_BEGIN "// ReSharper disable once InconsistentNaming\n");
- p_output.append(INDENT1 "[DebuggerBrowsable(DebuggerBrowsableState.Never)]" MEMBER_BEGIN
- "private static readonly StringName " CS_STATIC_FIELD_SIGNAL_NAME_PREFIX);
- p_output.append(p_isignal.name);
- p_output.append(" = \"");
- p_output.append(p_isignal.name);
- p_output.append("\";\n");
-
// Generate event
- p_output.append(MEMBER_BEGIN "[Signal]" MEMBER_BEGIN "public ");
+ p_output.append(MEMBER_BEGIN "public ");
if (p_itype.is_singleton) {
p_output.append("static ");
@@ -2262,21 +2284,21 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
p_output.append("\n" OPEN_BLOCK_L1 INDENT2);
if (p_itype.is_singleton) {
- p_output.append("add => " CS_PROPERTY_SINGLETON ".Connect(" CS_STATIC_FIELD_SIGNAL_NAME_PREFIX);
+ p_output.append("add => " CS_PROPERTY_SINGLETON ".Connect(SignalName.");
} else {
- p_output.append("add => Connect(" CS_STATIC_FIELD_SIGNAL_NAME_PREFIX);
+ p_output.append("add => Connect(SignalName.");
}
- p_output.append(p_isignal.name);
+ p_output.append(p_isignal.proxy_name);
p_output.append(", new Callable(value));\n");
if (p_itype.is_singleton) {
- p_output.append(INDENT2 "remove => " CS_PROPERTY_SINGLETON ".Disconnect(" CS_STATIC_FIELD_SIGNAL_NAME_PREFIX);
+ p_output.append(INDENT2 "remove => " CS_PROPERTY_SINGLETON ".Disconnect(SignalName.");
} else {
- p_output.append(INDENT2 "remove => Disconnect(" CS_STATIC_FIELD_SIGNAL_NAME_PREFIX);
+ p_output.append(INDENT2 "remove => Disconnect(SignalName.");
}
- p_output.append(p_isignal.name);
+ p_output.append(p_isignal.proxy_name);
p_output.append(", new Callable(value));\n");
p_output.append(CLOSE_BLOCK_L1);
}
diff --git a/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs b/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs
index c34f1a17f3..1f5ea7532d 100644
--- a/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs
+++ b/modules/mono/editor/script_templates/CharacterBody2D/basic_movement.cs
@@ -8,7 +8,7 @@ public partial class _CLASS_ : _BASE_
public const float Speed = 300.0f;
public const float JumpVelocity = -400.0f;
- // Get the gravity from the project settings to be synced with RigidDynamicBody nodes.
+ // Get the gravity from the project settings to be synced with RigidBody nodes.
public float gravity = ProjectSettings.GetSetting("physics/2d/default_gravity").AsSingle();
public override void _PhysicsProcess(float delta)
diff --git a/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs b/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs
index 069908c426..4e978b7549 100644
--- a/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs
+++ b/modules/mono/editor/script_templates/CharacterBody3D/basic_movement.cs
@@ -8,7 +8,7 @@ public partial class _CLASS_ : _BASE_
public const float Speed = 5.0f;
public const float JumpVelocity = 4.5f;
- // Get the gravity from the project settings to be synced with RigidDynamicBody nodes.
+ // Get the gravity from the project settings to be synced with RigidBody nodes.
public float gravity = ProjectSettings.GetSetting("physics/3d/default_gravity").AsSingle();
public override void _PhysicsProcess(float delta)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs
index f87f37bc43..b3a36e8ac8 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/AABB.cs
@@ -697,12 +697,7 @@ namespace Godot
/// <returns>Whether or not the AABB and the object are equal.</returns>
public override bool Equals(object obj)
{
- if (obj is AABB)
- {
- return Equals((AABB)obj);
- }
-
- return false;
+ return obj is AABB other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
index 81991c6626..f2984bd1fb 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
@@ -483,7 +483,7 @@ namespace Godot.Collections
/// <typeparam name="T">The type of the array.</typeparam>
[SuppressMessage("ReSharper", "RedundantExtendsListEntry")]
[SuppressMessage("Naming", "CA1710", MessageId = "Identifiers should have correct suffix")]
- public sealed class Array<T> :
+ public sealed class Array<[MustBeVariant] T> :
IList<T>,
IReadOnlyList<T>,
ICollection<T>,
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs
new file mode 100644
index 0000000000..23088378d1
--- /dev/null
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/MustBeVariantAttribute.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace Godot
+{
+ /// <summary>
+ /// Attribute that restricts generic type parameters to be only types
+ /// that can be marshaled from/to a <see cref="Variant"/>.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.GenericParameter)]
+ public class MustBeVariantAttribute : Attribute { }
+}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs
index 07a214f543..38e68a89d5 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/SignalAttribute.cs
@@ -2,6 +2,6 @@ using System;
namespace Godot
{
- [AttributeUsage(AttributeTargets.Delegate | AttributeTargets.Event)]
+ [AttributeUsage(AttributeTargets.Delegate)]
public class SignalAttribute : Attribute { }
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
index 4cb9bf5758..87adf9efe5 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
@@ -892,12 +892,7 @@ namespace Godot
/// <returns>Whether or not the basis matrix and the object are exactly equal.</returns>
public override bool Equals(object obj)
{
- if (obj is Basis)
- {
- return Equals((Basis)obj);
- }
-
- return false;
+ return obj is Basis other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
index ed0e1efd35..0cbaef3dad 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
@@ -1151,12 +1151,7 @@ namespace Godot
/// <returns>Whether or not the color and the other object are equal.</returns>
public override bool Equals(object obj)
{
- if (obj is Color)
- {
- return Equals((Color)obj);
- }
-
- return false;
+ return obj is Color other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs
index bacf7c89e6..5bce66ea87 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Colors.cs
@@ -10,136 +10,136 @@ namespace Godot
{
// Color names and values are derived from core/math/color_names.inc
internal static readonly Dictionary<string, Color> namedColors = new Dictionary<string, Color> {
- { "ALICE_BLUE", new Color(0xF0F8FFFF) },
- { "ANTIQUE_WHITE", new Color(0xFAEBD7FF) },
+ { "ALICEBLUE", new Color(0xF0F8FFFF) },
+ { "ANTIQUEWHITE", new Color(0xFAEBD7FF) },
{ "AQUA", new Color(0x00FFFFFF) },
{ "AQUAMARINE", new Color(0x7FFFD4FF) },
{ "AZURE", new Color(0xF0FFFFFF) },
{ "BEIGE", new Color(0xF5F5DCFF) },
{ "BISQUE", new Color(0xFFE4C4FF) },
{ "BLACK", new Color(0x000000FF) },
- { "BLANCHED_ALMOND", new Color(0xFFEBCDFF) },
+ { "BLANCHEDALMOND", new Color(0xFFEBCDFF) },
{ "BLUE", new Color(0x0000FFFF) },
- { "BLUE_VIOLET", new Color(0x8A2BE2FF) },
+ { "BLUEVIOLET", new Color(0x8A2BE2FF) },
{ "BROWN", new Color(0xA52A2AFF) },
{ "BURLYWOOD", new Color(0xDEB887FF) },
- { "CADET_BLUE", new Color(0x5F9EA0FF) },
+ { "CADETBLUE", new Color(0x5F9EA0FF) },
{ "CHARTREUSE", new Color(0x7FFF00FF) },
{ "CHOCOLATE", new Color(0xD2691EFF) },
{ "CORAL", new Color(0xFF7F50FF) },
- { "CORNFLOWER_BLUE", new Color(0x6495EDFF) },
+ { "CORNFLOWERBLUE", new Color(0x6495EDFF) },
{ "CORNSILK", new Color(0xFFF8DCFF) },
{ "CRIMSON", new Color(0xDC143CFF) },
{ "CYAN", new Color(0x00FFFFFF) },
- { "DARK_BLUE", new Color(0x00008BFF) },
- { "DARK_CYAN", new Color(0x008B8BFF) },
- { "DARK_GOLDENROD", new Color(0xB8860BFF) },
- { "DARK_GRAY", new Color(0xA9A9A9FF) },
- { "DARK_GREEN", new Color(0x006400FF) },
- { "DARK_KHAKI", new Color(0xBDB76BFF) },
- { "DARK_MAGENTA", new Color(0x8B008BFF) },
- { "DARK_OLIVE_GREEN", new Color(0x556B2FFF) },
- { "DARK_ORANGE", new Color(0xFF8C00FF) },
- { "DARK_ORCHID", new Color(0x9932CCFF) },
- { "DARK_RED", new Color(0x8B0000FF) },
- { "DARK_SALMON", new Color(0xE9967AFF) },
- { "DARK_SEA_GREEN", new Color(0x8FBC8FFF) },
- { "DARK_SLATE_BLUE", new Color(0x483D8BFF) },
- { "DARK_SLATE_GRAY", new Color(0x2F4F4FFF) },
- { "DARK_TURQUOISE", new Color(0x00CED1FF) },
- { "DARK_VIOLET", new Color(0x9400D3FF) },
- { "DEEP_PINK", new Color(0xFF1493FF) },
- { "DEEP_SKY_BLUE", new Color(0x00BFFFFF) },
- { "DIM_GRAY", new Color(0x696969FF) },
- { "DODGER_BLUE", new Color(0x1E90FFFF) },
+ { "DARKBLUE", new Color(0x00008BFF) },
+ { "DARKCYAN", new Color(0x008B8BFF) },
+ { "DARKGOLDENROD", new Color(0xB8860BFF) },
+ { "DARKGRAY", new Color(0xA9A9A9FF) },
+ { "DARKGREEN", new Color(0x006400FF) },
+ { "DARKKHAKI", new Color(0xBDB76BFF) },
+ { "DARKMAGENTA", new Color(0x8B008BFF) },
+ { "DARKOLIVEGREEN", new Color(0x556B2FFF) },
+ { "DARKORANGE", new Color(0xFF8C00FF) },
+ { "DARKORCHID", new Color(0x9932CCFF) },
+ { "DARKRED", new Color(0x8B0000FF) },
+ { "DARKSALMON", new Color(0xE9967AFF) },
+ { "DARKSEAGREEN", new Color(0x8FBC8FFF) },
+ { "DARKSLATEBLUE", new Color(0x483D8BFF) },
+ { "DARKSLATEGRAY", new Color(0x2F4F4FFF) },
+ { "DARKTURQUOISE", new Color(0x00CED1FF) },
+ { "DARKVIOLET", new Color(0x9400D3FF) },
+ { "DEEPPINK", new Color(0xFF1493FF) },
+ { "DEEPSKYBLUE", new Color(0x00BFFFFF) },
+ { "DIMGRAY", new Color(0x696969FF) },
+ { "DODGERBLUE", new Color(0x1E90FFFF) },
{ "FIREBRICK", new Color(0xB22222FF) },
- { "FLORAL_WHITE", new Color(0xFFFAF0FF) },
- { "FOREST_GREEN", new Color(0x228B22FF) },
+ { "FLORALWHITE", new Color(0xFFFAF0FF) },
+ { "FORESTGREEN", new Color(0x228B22FF) },
{ "FUCHSIA", new Color(0xFF00FFFF) },
{ "GAINSBORO", new Color(0xDCDCDCFF) },
- { "GHOST_WHITE", new Color(0xF8F8FFFF) },
+ { "GHOSTWHITE", new Color(0xF8F8FFFF) },
{ "GOLD", new Color(0xFFD700FF) },
{ "GOLDENROD", new Color(0xDAA520FF) },
{ "GRAY", new Color(0xBEBEBEFF) },
{ "GREEN", new Color(0x00FF00FF) },
- { "GREEN_YELLOW", new Color(0xADFF2FFF) },
+ { "GREENYELLOW", new Color(0xADFF2FFF) },
{ "HONEYDEW", new Color(0xF0FFF0FF) },
- { "HOT_PINK", new Color(0xFF69B4FF) },
- { "INDIAN_RED", new Color(0xCD5C5CFF) },
+ { "HOTPINK", new Color(0xFF69B4FF) },
+ { "INDIANRED", new Color(0xCD5C5CFF) },
{ "INDIGO", new Color(0x4B0082FF) },
{ "IVORY", new Color(0xFFFFF0FF) },
{ "KHAKI", new Color(0xF0E68CFF) },
{ "LAVENDER", new Color(0xE6E6FAFF) },
- { "LAVENDER_BLUSH", new Color(0xFFF0F5FF) },
- { "LAWN_GREEN", new Color(0x7CFC00FF) },
- { "LEMON_CHIFFON", new Color(0xFFFACDFF) },
- { "LIGHT_BLUE", new Color(0xADD8E6FF) },
- { "LIGHT_CORAL", new Color(0xF08080FF) },
- { "LIGHT_CYAN", new Color(0xE0FFFFFF) },
- { "LIGHT_GOLDENROD", new Color(0xFAFAD2FF) },
- { "LIGHT_GRAY", new Color(0xD3D3D3FF) },
- { "LIGHT_GREEN", new Color(0x90EE90FF) },
- { "LIGHT_PINK", new Color(0xFFB6C1FF) },
- { "LIGHT_SALMON", new Color(0xFFA07AFF) },
- { "LIGHT_SEA_GREEN", new Color(0x20B2AAFF) },
- { "LIGHT_SKY_BLUE", new Color(0x87CEFAFF) },
- { "LIGHT_SLATE_GRAY", new Color(0x778899FF) },
- { "LIGHT_STEEL_BLUE", new Color(0xB0C4DEFF) },
- { "LIGHT_YELLOW", new Color(0xFFFFE0FF) },
+ { "LAVENDERBLUSH", new Color(0xFFF0F5FF) },
+ { "LAWNGREEN", new Color(0x7CFC00FF) },
+ { "LEMONCHIFFON", new Color(0xFFFACDFF) },
+ { "LIGHTBLUE", new Color(0xADD8E6FF) },
+ { "LIGHTCORAL", new Color(0xF08080FF) },
+ { "LIGHTCYAN", new Color(0xE0FFFFFF) },
+ { "LIGHTGOLDENROD", new Color(0xFAFAD2FF) },
+ { "LIGHTGRAY", new Color(0xD3D3D3FF) },
+ { "LIGHTGREEN", new Color(0x90EE90FF) },
+ { "LIGHTPINK", new Color(0xFFB6C1FF) },
+ { "LIGHTSALMON", new Color(0xFFA07AFF) },
+ { "LIGHTSEAGREEN", new Color(0x20B2AAFF) },
+ { "LIGHTSKYBLUE", new Color(0x87CEFAFF) },
+ { "LIGHTSLATEGRAY", new Color(0x778899FF) },
+ { "LIGHTSTEELBLUE", new Color(0xB0C4DEFF) },
+ { "LIGHTYELLOW", new Color(0xFFFFE0FF) },
{ "LIME", new Color(0x00FF00FF) },
- { "LIME_GREEN", new Color(0x32CD32FF) },
+ { "LIMEGREEN", new Color(0x32CD32FF) },
{ "LINEN", new Color(0xFAF0E6FF) },
{ "MAGENTA", new Color(0xFF00FFFF) },
{ "MAROON", new Color(0xB03060FF) },
- { "MEDIUM_AQUAMARINE", new Color(0x66CDAAFF) },
- { "MEDIUM_BLUE", new Color(0x0000CDFF) },
- { "MEDIUM_ORCHID", new Color(0xBA55D3FF) },
- { "MEDIUM_PURPLE", new Color(0x9370DBFF) },
- { "MEDIUM_SEA_GREEN", new Color(0x3CB371FF) },
- { "MEDIUM_SLATE_BLUE", new Color(0x7B68EEFF) },
- { "MEDIUM_SPRING_GREEN", new Color(0x00FA9AFF) },
- { "MEDIUM_TURQUOISE", new Color(0x48D1CCFF) },
- { "MEDIUM_VIOLET_RED", new Color(0xC71585FF) },
- { "MIDNIGHT_BLUE", new Color(0x191970FF) },
- { "MINT_CREAM", new Color(0xF5FFFAFF) },
- { "MISTY_ROSE", new Color(0xFFE4E1FF) },
+ { "MEDIUMAQUAMARINE", new Color(0x66CDAAFF) },
+ { "MEDIUMBLUE", new Color(0x0000CDFF) },
+ { "MEDIUMORCHID", new Color(0xBA55D3FF) },
+ { "MEDIUMPURPLE", new Color(0x9370DBFF) },
+ { "MEDIUMSEAGREEN", new Color(0x3CB371FF) },
+ { "MEDIUMSLATEBLUE", new Color(0x7B68EEFF) },
+ { "MEDIUMSPRINGGREEN", new Color(0x00FA9AFF) },
+ { "MEDIUMTURQUOISE", new Color(0x48D1CCFF) },
+ { "MEDIUMVIOLETRED", new Color(0xC71585FF) },
+ { "MIDNIGHTBLUE", new Color(0x191970FF) },
+ { "MINTCREAM", new Color(0xF5FFFAFF) },
+ { "MISTYROSE", new Color(0xFFE4E1FF) },
{ "MOCCASIN", new Color(0xFFE4B5FF) },
- { "NAVAJO_WHITE", new Color(0xFFDEADFF) },
- { "NAVY_BLUE", new Color(0x000080FF) },
- { "OLD_LACE", new Color(0xFDF5E6FF) },
+ { "NAVAJOWHITE", new Color(0xFFDEADFF) },
+ { "NAVYBLUE", new Color(0x000080FF) },
+ { "OLDLACE", new Color(0xFDF5E6FF) },
{ "OLIVE", new Color(0x808000FF) },
- { "OLIVE_DRAB", new Color(0x6B8E23FF) },
+ { "OLIVEDRAB", new Color(0x6B8E23FF) },
{ "ORANGE", new Color(0xFFA500FF) },
- { "ORANGE_RED", new Color(0xFF4500FF) },
+ { "ORANGERED", new Color(0xFF4500FF) },
{ "ORCHID", new Color(0xDA70D6FF) },
- { "PALE_GOLDENROD", new Color(0xEEE8AAFF) },
- { "PALE_GREEN", new Color(0x98FB98FF) },
- { "PALE_TURQUOISE", new Color(0xAFEEEEFF) },
- { "PALE_VIOLET_RED", new Color(0xDB7093FF) },
- { "PAPAYA_WHIP", new Color(0xFFEFD5FF) },
- { "PEACH_PUFF", new Color(0xFFDAB9FF) },
+ { "PALEGOLDENROD", new Color(0xEEE8AAFF) },
+ { "PALEGREEN", new Color(0x98FB98FF) },
+ { "PALETURQUOISE", new Color(0xAFEEEEFF) },
+ { "PALEVIOLETRED", new Color(0xDB7093FF) },
+ { "PAPAYAWHIP", new Color(0xFFEFD5FF) },
+ { "PEACHPUFF", new Color(0xFFDAB9FF) },
{ "PERU", new Color(0xCD853FFF) },
{ "PINK", new Color(0xFFC0CBFF) },
{ "PLUM", new Color(0xDDA0DDFF) },
- { "POWDER_BLUE", new Color(0xB0E0E6FF) },
+ { "POWDERBLUE", new Color(0xB0E0E6FF) },
{ "PURPLE", new Color(0xA020F0FF) },
- { "REBECCA_PURPLE", new Color(0x663399FF) },
+ { "REBECCAPURPLE", new Color(0x663399FF) },
{ "RED", new Color(0xFF0000FF) },
- { "ROSY_BROWN", new Color(0xBC8F8FFF) },
- { "ROYAL_BLUE", new Color(0x4169E1FF) },
- { "SADDLE_BROWN", new Color(0x8B4513FF) },
+ { "ROSYBROWN", new Color(0xBC8F8FFF) },
+ { "ROYALBLUE", new Color(0x4169E1FF) },
+ { "SADDLEBROWN", new Color(0x8B4513FF) },
{ "SALMON", new Color(0xFA8072FF) },
- { "SANDY_BROWN", new Color(0xF4A460FF) },
- { "SEA_GREEN", new Color(0x2E8B57FF) },
+ { "SANDYBROWN", new Color(0xF4A460FF) },
+ { "SEAGREEN", new Color(0x2E8B57FF) },
{ "SEASHELL", new Color(0xFFF5EEFF) },
{ "SIENNA", new Color(0xA0522DFF) },
{ "SILVER", new Color(0xC0C0C0FF) },
- { "SKY_BLUE", new Color(0x87CEEBFF) },
- { "SLATE_BLUE", new Color(0x6A5ACDFF) },
- { "SLATE_GRAY", new Color(0x708090FF) },
+ { "SKYBLUE", new Color(0x87CEEBFF) },
+ { "SLATEBLUE", new Color(0x6A5ACDFF) },
+ { "SLATEGRAY", new Color(0x708090FF) },
{ "SNOW", new Color(0xFFFAFAFF) },
- { "SPRING_GREEN", new Color(0x00FF7FFF) },
- { "STEEL_BLUE", new Color(0x4682B4FF) },
+ { "SPRINGGREEN", new Color(0x00FF7FFF) },
+ { "STEELBLUE", new Color(0x4682B4FF) },
{ "TAN", new Color(0xD2B48CFF) },
{ "TEAL", new Color(0x008080FF) },
{ "THISTLE", new Color(0xD8BFD8FF) },
@@ -147,15 +147,15 @@ namespace Godot
{ "TRANSPARENT", new Color(0xFFFFFF00) },
{ "TURQUOISE", new Color(0x40E0D0FF) },
{ "VIOLET", new Color(0xEE82EEFF) },
- { "WEB_GRAY", new Color(0x808080FF) },
- { "WEB_GREEN", new Color(0x008000FF) },
- { "WEB_MAROON", new Color(0x800000FF) },
- { "WEB_PURPLE", new Color(0x800080FF) },
+ { "WEBGRAY", new Color(0x808080FF) },
+ { "WEBGREEN", new Color(0x008000FF) },
+ { "WEBMAROON", new Color(0x800000FF) },
+ { "WEBPURPLE", new Color(0x800080FF) },
{ "WHEAT", new Color(0xF5DEB3FF) },
{ "WHITE", new Color(0xFFFFFFFF) },
- { "WHITE_SMOKE", new Color(0xF5F5F5FF) },
+ { "WHITESMOKE", new Color(0xF5F5F5FF) },
{ "YELLOW", new Color(0xFFFF00FF) },
- { "YELLOW_GREEN", new Color(0x9ACD32FF) },
+ { "YELLOWGREEN", new Color(0x9ACD32FF) },
};
#pragma warning disable CS1591 // Disable warning: "Missing XML comment for publicly visible type or member"
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DebuggingUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DebuggingUtils.cs
index 6fbc04702a..c4161d2ded 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DebuggingUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DebuggingUtils.cs
@@ -121,8 +121,8 @@ namespace Godot
var sb = new StringBuilder();
- if (methodBase is MethodInfo)
- sb.AppendTypeName(((MethodInfo)methodBase).ReturnType);
+ if (methodBase is MethodInfo methodInfo)
+ sb.AppendTypeName(methodInfo.ReturnType);
sb.Append(methodBase.DeclaringType?.FullName ?? "<unknown>");
sb.Append('.');
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs
index 266038a0af..3c75d18943 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs
@@ -181,9 +181,9 @@ namespace Godot
if (variantType == Variant.Type.Nil)
return false;
- static byte[] Var2Bytes(in godot_variant var)
+ static byte[] VarToBytes(in godot_variant var)
{
- NativeFuncs.godotsharp_var2bytes(var, false.ToGodotBool(), out var varBytes);
+ NativeFuncs.godotsharp_var_to_bytes(var, false.ToGodotBool(), out var varBytes);
using (varBytes)
return Marshaling.ConvertNativePackedByteArrayToSystemArray(varBytes);
}
@@ -192,7 +192,7 @@ namespace Godot
var fieldValue = field.GetValue(target);
using var fieldValueVariant = Marshaling.ConvertManagedObjectToVariant(fieldValue);
- byte[] valueBuffer = Var2Bytes(fieldValueVariant);
+ byte[] valueBuffer = VarToBytes(fieldValueVariant);
writer.Write(valueBuffer.Length);
writer.Write(valueBuffer);
}
@@ -448,7 +448,7 @@ namespace Godot
FieldInfo? fieldInfo = targetType.GetField(name,
BindingFlags.Instance | BindingFlags.Public);
- fieldInfo?.SetValue(recreatedTarget, GD.Bytes2Var(valueBuffer));
+ fieldInfo?.SetValue(recreatedTarget, GD.BytesToVar(valueBuffer));
}
@delegate = Delegate.CreateDelegate(delegateType, recreatedTarget, methodInfo,
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
index fa8c94ed18..95ad097192 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
@@ -352,7 +352,7 @@ namespace Godot.Collections
/// </summary>
/// <typeparam name="TKey">The type of the dictionary's keys.</typeparam>
/// <typeparam name="TValue">The type of the dictionary's values.</typeparam>
- public class Dictionary<TKey, TValue> :
+ public class Dictionary<[MustBeVariant] TKey, [MustBeVariant] TValue> :
IDictionary<TKey, TValue>,
IReadOnlyDictionary<TKey, TValue>
{
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs
index 1dc21b6303..df0e839866 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/NodeExtensions.cs
@@ -93,8 +93,12 @@ namespace Godot
/// Negative indices access the children from the last one.
/// To access a child node via its name, use <see cref="GetNode"/>.
/// </summary>
- /// <seealso cref="GetChildOrNull{T}(int)"/>
+ /// <seealso cref="GetChildOrNull{T}(int, bool)"/>
/// <param name="idx">Child index.</param>
+ /// <param name="includeInternal">
+ /// If <see langword="false"/>, internal children are skipped (see <c>internal</c>
+ /// parameter in <see cref="AddChild(Node, bool, InternalMode)"/>).
+ /// </param>
/// <exception cref="InvalidCastException">
/// Thrown when the given the fetched node can't be casted to the given type <typeparamref name="T"/>.
/// </exception>
@@ -102,9 +106,9 @@ namespace Godot
/// <returns>
/// The child <see cref="Node"/> at the given index <paramref name="idx"/>.
/// </returns>
- public T GetChild<T>(int idx) where T : class
+ public T GetChild<T>(int idx, bool includeInternal = false) where T : class
{
- return (T)(object)GetChild(idx);
+ return (T)(object)GetChild(idx, includeInternal);
}
/// <summary>
@@ -113,15 +117,20 @@ namespace Godot
/// Negative indices access the children from the last one.
/// To access a child node via its name, use <see cref="GetNode"/>.
/// </summary>
- /// <seealso cref="GetChild{T}(int)"/>
+ /// <seealso cref="GetChild{T}(int, bool)"/>
/// <param name="idx">Child index.</param>
+ /// <param name="includeInternal">
+ /// If <see langword="false"/>, internal children are skipped (see <c>internal</c>
+ /// parameter in <see cref="AddChild(Node, bool, InternalMode)"/>).
+ /// </param>
/// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>
/// <returns>
/// The child <see cref="Node"/> at the given index <paramref name="idx"/>, or <see langword="null"/> if not found.
/// </returns>
- public T GetChildOrNull<T>(int idx) where T : class
+ public T GetChildOrNull<T>(int idx, bool includeInternal = false) where T : class
{
- return GetChild(idx) as T;
+ int count = GetChildCount(includeInternal);
+ return idx >= -count && idx < count ? GetChild(idx, includeInternal) as T : null;
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
index 9348cc1d00..e4b79e7ec4 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GD.cs
@@ -21,10 +21,10 @@ namespace Godot
/// <param name="bytes">Byte array that will be decoded to a <c>Variant</c>.</param>
/// <param name="allowObjects">If objects should be decoded.</param>
/// <returns>The decoded <c>Variant</c>.</returns>
- public static Variant Bytes2Var(Span<byte> bytes, bool allowObjects = false)
+ public static Variant BytesToVar(Span<byte> bytes, bool allowObjects = false)
{
using var varBytes = Marshaling.ConvertSystemArrayToNativePackedByteArray(bytes);
- NativeFuncs.godotsharp_bytes2var(varBytes, allowObjects.ToGodotBool(), out godot_variant ret);
+ NativeFuncs.godotsharp_bytes_to_var(varBytes, allowObjects.ToGodotBool(), out godot_variant ret);
return Variant.CreateTakingOwnershipOfDisposableValue(ret);
}
@@ -52,10 +52,10 @@ namespace Godot
/// <summary>
/// Converts from decibels to linear energy (audio).
/// </summary>
- /// <seealso cref="Linear2Db(real_t)"/>
+ /// <seealso cref="LinearToDb(real_t)"/>
/// <param name="db">Decibels to convert.</param>
/// <returns>Audio volume as linear energy.</returns>
- public static real_t Db2Linear(real_t db)
+ public static real_t DbToLinear(real_t db)
{
return (real_t)Math.Exp(db * 0.11512925464970228420089957273422);
}
@@ -115,18 +115,18 @@ namespace Godot
/// Converts from linear energy to decibels (audio).
/// This can be used to implement volume sliders that behave as expected (since volume isn't linear).
/// </summary>
- /// <seealso cref="Db2Linear(real_t)"/>
+ /// <seealso cref="DbToLinear(real_t)"/>
/// <example>
/// <code>
/// // "slider" refers to a node that inherits Range such as HSlider or VSlider.
/// // Its range must be configured to go from 0 to 1.
/// // Change the bus name if you'd like to change the volume of a specific bus only.
- /// AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex("Master"), GD.Linear2Db(slider.value));
+ /// AudioServer.SetBusVolumeDb(AudioServer.GetBusIndex("Master"), GD.LinearToDb(slider.value));
/// </code>
/// </example>
/// <param name="linear">The linear energy to convert.</param>
/// <returns>Audio as decibels.</returns>
- public static real_t Linear2Db(real_t linear)
+ public static real_t LinearToDb(real_t linear)
{
return (real_t)(Math.Log(linear) * 8.6858896380650365530225783783321);
}
@@ -189,8 +189,6 @@ namespace Godot
/// Pushes an error message to Godot's built-in debugger and to the OS terminal.
///
/// Note: Errors printed this way will not pause project execution.
- /// To print an error message and pause project execution in debug builds,
- /// use [code]assert(false, "test error")[/code] instead.
/// </summary>
/// <example>
/// <code>
@@ -520,21 +518,21 @@ namespace Godot
}
/// <summary>
- /// Converts a formatted string that was returned by <see cref="Var2Str(Variant)"/> to the original value.
+ /// Converts a formatted string that was returned by <see cref="VarToStr(Variant)"/> to the original value.
/// </summary>
/// <example>
/// <code>
/// string a = "{\"a\": 1, \"b\": 2 }";
- /// var b = (Godot.Collections.Dictionary)GD.Str2Var(a);
+ /// var b = (Godot.Collections.Dictionary)GD.StrToVar(a);
/// GD.Print(b["a"]); // Prints 1
/// </code>
/// </example>
/// <param name="str">String that will be converted to Variant.</param>
/// <returns>The decoded <c>Variant</c>.</returns>
- public static Variant Str2Var(string str)
+ public static Variant StrToVar(string str)
{
using var godotStr = Marshaling.ConvertStringToNative(str);
- NativeFuncs.godotsharp_str2var(godotStr, out godot_variant ret);
+ NativeFuncs.godotsharp_str_to_var(godotStr, out godot_variant ret);
return Variant.CreateTakingOwnershipOfDisposableValue(ret);
}
@@ -542,26 +540,26 @@ namespace Godot
/// Encodes a <c>Variant</c> value to a byte array.
/// If <paramref name="fullObjects"/> is <see langword="true"/> encoding objects is allowed
/// (and can potentially include code).
- /// Deserialization can be done with <see cref="Bytes2Var(Span{byte}, bool)"/>.
+ /// Deserialization can be done with <see cref="BytesToVar(Span{byte}, bool)"/>.
/// </summary>
/// <param name="var">Variant that will be encoded.</param>
/// <param name="fullObjects">If objects should be serialized.</param>
/// <returns>The <c>Variant</c> encoded as an array of bytes.</returns>
- public static byte[] Var2Bytes(Variant var, bool fullObjects = false)
+ public static byte[] VarToBytes(Variant var, bool fullObjects = false)
{
- NativeFuncs.godotsharp_var2bytes((godot_variant)var.NativeVar, fullObjects.ToGodotBool(), out var varBytes);
+ NativeFuncs.godotsharp_var_to_bytes((godot_variant)var.NativeVar, fullObjects.ToGodotBool(), out var varBytes);
using (varBytes)
return Marshaling.ConvertNativePackedByteArrayToSystemArray(varBytes);
}
/// <summary>
/// Converts a <c>Variant</c> <paramref name="var"/> to a formatted string that
- /// can later be parsed using <see cref="Str2Var(string)"/>.
+ /// can later be parsed using <see cref="StrToVar(string)"/>.
/// </summary>
/// <example>
/// <code>
/// var a = new Godot.Collections.Dictionary { ["a"] = 1, ["b"] = 2 };
- /// GD.Print(GD.Var2Str(a));
+ /// GD.Print(GD.VarToStr(a));
/// // Prints
/// // {
/// // "a": 1,
@@ -571,9 +569,9 @@ namespace Godot
/// </example>
/// <param name="var">Variant that will be converted to string.</param>
/// <returns>The <c>Variant</c> encoded as a string.</returns>
- public static string Var2Str(Variant var)
+ public static string VarToStr(Variant var)
{
- NativeFuncs.godotsharp_var2str((godot_variant)var.NativeVar, out godot_string ret);
+ NativeFuncs.godotsharp_var_to_str((godot_variant)var.NativeVar, out godot_string ret);
using (ret)
return Marshaling.ConvertStringToManaged(ret);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
index 08beff8104..00e775e6ad 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs
@@ -35,9 +35,9 @@ namespace Godot
public const real_t NaN = real_t.NaN;
// 0.0174532924f and 0.0174532925199433
- private const real_t _deg2RadConst = (real_t)0.0174532925199432957692369077M;
+ private const real_t _degToRadConst = (real_t)0.0174532925199432957692369077M;
// 57.29578f and 57.2957795130823
- private const real_t _rad2DegConst = (real_t)57.295779513082320876798154814M;
+ private const real_t _radToDegConst = (real_t)57.295779513082320876798154814M;
/// <summary>
/// Returns the absolute value of <paramref name="s"/> (i.e. positive value).
@@ -219,9 +219,9 @@ namespace Godot
/// </summary>
/// <param name="deg">An angle expressed in degrees.</param>
/// <returns>The same angle expressed in radians.</returns>
- public static real_t Deg2Rad(real_t deg)
+ public static real_t DegToRad(real_t deg)
{
- return deg * _deg2RadConst;
+ return deg * _degToRadConst;
}
/// <summary>
@@ -531,9 +531,9 @@ namespace Godot
/// </summary>
/// <param name="rad">An angle expressed in radians.</param>
/// <returns>The same angle expressed in degrees.</returns>
- public static real_t Rad2Deg(real_t rad)
+ public static real_t RadToDeg(real_t rad)
{
- return rad * _rad2DegConst;
+ return rad * _radToDegConst;
}
/// <summary>
@@ -754,9 +754,10 @@ namespace Godot
}
/// <summary>
- /// Returns the [code]value[/code] wrapped between [code]0[/code] and the [code]length[/code].
- /// If the limit is reached, the next value the function returned is decreased to the [code]0[/code] side or increased to the [code]length[/code] side (like a triangle wave).
- /// If [code]length[/code] is less than zero, it becomes positive.
+ /// Returns the <paramref name="value"/> wrapped between <c>0</c> and the <paramref name="length"/>.
+ /// If the limit is reached, the next value the function returned is decreased to the <c>0</c> side
+ /// or increased to the <paramref name="length"/> side (like a triangle wave).
+ /// If <paramref name="length"/> is less than zero, it becomes positive.
/// </summary>
/// <param name="value">The value to pingpong.</param>
/// <param name="length">The maximum value of the function.</param>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs
index 6d2534e6f7..48c1b48c59 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs
@@ -461,7 +461,7 @@ namespace Godot.NativeInterop
// GD, etc
- internal static partial void godotsharp_bytes2var(in godot_packed_byte_array p_bytes,
+ internal static partial void godotsharp_bytes_to_var(in godot_packed_byte_array p_bytes,
godot_bool p_allow_objects,
out godot_variant r_ret);
@@ -504,12 +504,12 @@ namespace Godot.NativeInterop
internal static partial void godotsharp_str(in godot_array p_what, out godot_string r_ret);
- internal static partial void godotsharp_str2var(in godot_string p_str, out godot_variant r_ret);
+ internal static partial void godotsharp_str_to_var(in godot_string p_str, out godot_variant r_ret);
- internal static partial void godotsharp_var2bytes(in godot_variant p_what, godot_bool p_full_objects,
+ internal static partial void godotsharp_var_to_bytes(in godot_variant p_what, godot_bool p_full_objects,
out godot_packed_byte_array r_bytes);
- internal static partial void godotsharp_var2str(in godot_variant p_var, out godot_string r_ret);
+ internal static partial void godotsharp_var_to_str(in godot_variant p_var, out godot_string r_ret);
internal static partial void godotsharp_pusherror(in godot_string p_str);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs
index 50832d7679..13070c8033 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Plane.cs
@@ -353,12 +353,7 @@ namespace Godot
/// <returns>Whether or not the plane and the other object are exactly equal.</returns>
public override bool Equals(object obj)
{
- if (obj is Plane)
- {
- return Equals((Plane)obj);
- }
-
- return false;
+ return obj is Plane other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs
index b85a105a0b..9d08e7120a 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Projection.cs
@@ -39,22 +39,22 @@ namespace Godot
}
/// <summary>
- /// The projections's X column. Also accessible by using the index position <c>[0]</c>.
+ /// The projection's X column. Also accessible by using the index position <c>[0]</c>.
/// </summary>
public Vector4 x;
/// <summary>
- /// The projections's Y column. Also accessible by using the index position <c>[1]</c>.
+ /// The projection's Y column. Also accessible by using the index position <c>[1]</c>.
/// </summary>
public Vector4 y;
/// <summary>
- /// The projections's Z column. Also accessible by using the index position <c>[2]</c>.
+ /// The projection's Z column. Also accessible by using the index position <c>[2]</c>.
/// </summary>
public Vector4 z;
/// <summary>
- /// The projections's W column. Also accessible by using the index position <c>[3]</c>.
+ /// The projection's W column. Also accessible by using the index position <c>[3]</c>.
/// </summary>
public Vector4 w;
@@ -226,7 +226,7 @@ namespace Godot
{
fovyDegrees = GetFovy(fovyDegrees, (real_t)1.0 / aspect);
}
- real_t radians = Mathf.Deg2Rad(fovyDegrees / (real_t)2.0);
+ real_t radians = Mathf.DegToRad(fovyDegrees / (real_t)2.0);
real_t deltaZ = zFar - zNear;
real_t sine = Mathf.Sin(radians);
@@ -256,7 +256,7 @@ namespace Godot
fovyDegrees = GetFovy(fovyDegrees, (real_t)1.0 / aspect);
}
- real_t ymax = zNear * Mathf.Tan(Mathf.Deg2Rad(fovyDegrees / (real_t)2.0));
+ real_t ymax = zNear * Mathf.Tan(Mathf.DegToRad(fovyDegrees / (real_t)2.0));
real_t xmax = ymax * aspect;
real_t frustumshift = (intraocularDist / (real_t)2.0) * zNear / convergenceDist;
real_t left;
@@ -313,18 +313,18 @@ namespace Godot
Plane rightPlane = new Plane(x.w - x.x, y.w - y.x, z.w - z.x, -w.w + w.x).Normalized();
if (z.x == 0 && z.y == 0)
{
- return Mathf.Rad2Deg(Mathf.Acos(Mathf.Abs(rightPlane.Normal.x))) * (real_t)2.0;
+ return Mathf.RadToDeg(Mathf.Acos(Mathf.Abs(rightPlane.Normal.x))) * (real_t)2.0;
}
else
{
Plane leftPlane = new Plane(x.w + x.x, y.w + y.x, z.w + z.x, w.w + w.x).Normalized();
- return Mathf.Rad2Deg(Mathf.Acos(Mathf.Abs(leftPlane.Normal.x))) + Mathf.Rad2Deg(Mathf.Acos(Mathf.Abs(rightPlane.Normal.x)));
+ return Mathf.RadToDeg(Mathf.Acos(Mathf.Abs(leftPlane.Normal.x))) + Mathf.RadToDeg(Mathf.Acos(Mathf.Abs(rightPlane.Normal.x)));
}
}
public static real_t GetFovy(real_t fovx, real_t aspect)
{
- return Mathf.Rad2Deg(Mathf.Atan(aspect * Mathf.Tan(Mathf.Deg2Rad(fovx) * (real_t)0.5)) * (real_t)2.0);
+ return Mathf.RadToDeg(Mathf.Atan(aspect * Mathf.Tan(Mathf.DegToRad(fovx) * (real_t)0.5)) * (real_t)2.0);
}
public real_t GetLodMultiplier()
@@ -800,11 +800,7 @@ namespace Godot
/// <returns>Whether or not the vector and the object are equal.</returns>
public override bool Equals(object obj)
{
- if (obj is Projection)
- {
- return Equals((Projection)obj);
- }
- return false;
+ return obj is Projection other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
index 658a14ca1d..999500ca13 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quaternion.cs
@@ -580,12 +580,7 @@ namespace Godot
/// <returns>Whether or not the quaternion and the other object are exactly equal.</returns>
public override bool Equals(object obj)
{
- if (obj is Quaternion)
- {
- return Equals((Quaternion)obj);
- }
-
- return false;
+ return obj is Quaternion other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
index d2c9b0ca8b..0b475fec19 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
@@ -426,12 +426,7 @@ namespace Godot
/// <returns>Whether or not the rect and the other object are exactly equal.</returns>
public override bool Equals(object obj)
{
- if (obj is Rect2)
- {
- return Equals((Rect2)obj);
- }
-
- return false;
+ return obj is Rect2 other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
index 5d53b8330e..8a2a98d6ee 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
@@ -426,12 +426,7 @@ namespace Godot
/// <returns>Whether or not the rect and the other object are equal.</returns>
public override bool Equals(object obj)
{
- if (obj is Rect2i)
- {
- return Equals((Rect2i)obj);
- }
-
- return false;
+ return obj is Rect2i other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs
index 10739c02a7..b9ee0bc278 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringName.cs
@@ -59,9 +59,9 @@ namespace Godot
}
/// <summary>
- /// Constructs a <see cref="StringName"/> from the given <paramref name="path"/> string.
+ /// Constructs a <see cref="StringName"/> from the given <paramref name="name"/> string.
/// </summary>
- /// <param name="path">String to construct the <see cref="StringName"/> from.</param>
+ /// <param name="name">String to construct the <see cref="StringName"/> from.</param>
public StringName(string name)
{
if (!string.IsNullOrEmpty(name))
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
index 70cf8bbe22..33b4f11f62 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
@@ -602,7 +602,7 @@ namespace Godot
/// <returns>Whether or not the transform and the object are exactly equal.</returns>
public override bool Equals(object obj)
{
- return obj is Transform2D transform2D && Equals(transform2D);
+ return obj is Transform2D other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
index 5481225e3f..4b739bb86b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
@@ -579,12 +579,7 @@ namespace Godot
/// <returns>Whether or not the transform and the object are exactly equal.</returns>
public override readonly bool Equals(object obj)
{
- if (obj is Transform3D)
- {
- return Equals((Transform3D)obj);
- }
-
- return false;
+ return obj is Transform3D other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
index 04c2ea7eb9..03ee12884b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
@@ -925,11 +925,7 @@ namespace Godot
/// <returns>Whether or not the vector and the object are equal.</returns>
public override bool Equals(object obj)
{
- if (obj is Vector2)
- {
- return Equals((Vector2)obj);
- }
- return false;
+ return obj is Vector2 other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
index a8f42972d7..666616edec 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
@@ -667,12 +667,7 @@ namespace Godot
/// <returns>Whether or not the vector and the object are equal.</returns>
public override bool Equals(object obj)
{
- if (obj is Vector2i)
- {
- return Equals((Vector2i)obj);
- }
-
- return false;
+ return obj is Vector2i other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
index d5941d6b60..cdba06c089 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
@@ -993,12 +993,7 @@ namespace Godot
/// <returns>Whether or not the vector and the object are equal.</returns>
public override bool Equals(object obj)
{
- if (obj is Vector3)
- {
- return Equals((Vector3)obj);
- }
-
- return false;
+ return obj is Vector3 other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
index eb46f36e7c..2947ef94a7 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
@@ -676,12 +676,7 @@ namespace Godot
/// <returns>Whether or not the vector and the object are equal.</returns>
public override bool Equals(object obj)
{
- if (obj is Vector3i)
- {
- return Equals((Vector3i)obj);
- }
-
- return false;
+ return obj is Vector3i other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs
index 20a24616ce..705da04692 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs
@@ -754,12 +754,7 @@ namespace Godot
/// <returns>Whether or not the vector and the object are equal.</returns>
public override bool Equals(object obj)
{
- if (obj is Vector4)
- {
- return Equals((Vector4)obj);
- }
-
- return false;
+ return obj is Vector4 other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs
index 11c2b7234b..73134b0baf 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4i.cs
@@ -629,12 +629,7 @@ namespace Godot
/// <returns>Whether or not the vector and the object are equal.</returns>
public override bool Equals(object obj)
{
- if (obj is Vector4i)
- {
- return Equals((Vector4i)obj);
- }
-
- return false;
+ return obj is Vector4i other && Equals(other);
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
index f0d6748b73..aae7a5ebfa 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
+++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
@@ -56,6 +56,7 @@
<Compile Include="Core\Attributes\ExportCategoryAttribute.cs" />
<Compile Include="Core\Attributes\ExportGroupAttribute.cs" />
<Compile Include="Core\Attributes\ExportSubgroupAttribute.cs" />
+ <Compile Include="Core\Attributes\MustBeVariantAttribute.cs" />
<Compile Include="Core\Attributes\RPCAttribute.cs" />
<Compile Include="Core\Attributes\ScriptPathAttribute.cs" />
<Compile Include="Core\Attributes\SignalAttribute.cs" />
diff --git a/modules/mono/glue/runtime_interop.cpp b/modules/mono/glue/runtime_interop.cpp
index 13d4395a64..0d68cb54b9 100644
--- a/modules/mono/glue/runtime_interop.cpp
+++ b/modules/mono/glue/runtime_interop.cpp
@@ -1233,13 +1233,13 @@ void godotsharp_pushwarning(const godot_string *p_str) {
WARN_PRINT(*reinterpret_cast<const String *>(p_str));
}
-void godotsharp_var2str(const godot_variant *p_var, godot_string *r_ret) {
+void godotsharp_var_to_str(const godot_variant *p_var, godot_string *r_ret) {
const Variant &var = *reinterpret_cast<const Variant *>(p_var);
String &vars = *memnew_placement(r_ret, String);
VariantWriter::write_to_string(var, vars);
}
-void godotsharp_str2var(const godot_string *p_str, godot_variant *r_ret) {
+void godotsharp_str_to_var(const godot_string *p_str, godot_variant *r_ret) {
Variant ret;
VariantParser::StreamString ss;
@@ -1256,7 +1256,7 @@ void godotsharp_str2var(const godot_string *p_str, godot_variant *r_ret) {
memnew_placement(r_ret, Variant(ret));
}
-void godotsharp_var2bytes(const godot_variant *p_var, bool p_full_objects, godot_packed_array *r_bytes) {
+void godotsharp_var_to_bytes(const godot_variant *p_var, bool p_full_objects, godot_packed_array *r_bytes) {
const Variant &var = *reinterpret_cast<const Variant *>(p_var);
PackedByteArray &bytes = *memnew_placement(r_bytes, PackedByteArray);
@@ -1268,7 +1268,7 @@ void godotsharp_var2bytes(const godot_variant *p_var, bool p_full_objects, godot
encode_variant(var, bytes.ptrw(), len, p_full_objects);
}
-void godotsharp_bytes2var(const godot_packed_array *p_bytes, bool p_allow_objects, godot_variant *r_ret) {
+void godotsharp_bytes_to_var(const godot_packed_array *p_bytes, bool p_allow_objects, godot_variant *r_ret) {
const PackedByteArray *bytes = reinterpret_cast<const PackedByteArray *>(p_bytes);
Variant ret;
Error err = decode_variant(ret, bytes->ptr(), bytes->size(), nullptr, p_allow_objects);
@@ -1479,7 +1479,7 @@ static const void *unmanaged_callbacks[]{
(void *)godotsharp_node_path_get_subname,
(void *)godotsharp_node_path_get_subname_count,
(void *)godotsharp_node_path_is_absolute,
- (void *)godotsharp_bytes2var,
+ (void *)godotsharp_bytes_to_var,
(void *)godotsharp_convert,
(void *)godotsharp_hash,
(void *)godotsharp_instance_from_id,
@@ -1499,9 +1499,9 @@ static const void *unmanaged_callbacks[]{
(void *)godotsharp_seed,
(void *)godotsharp_weakref,
(void *)godotsharp_str,
- (void *)godotsharp_str2var,
- (void *)godotsharp_var2bytes,
- (void *)godotsharp_var2str,
+ (void *)godotsharp_str_to_var,
+ (void *)godotsharp_var_to_bytes,
+ (void *)godotsharp_var_to_str,
(void *)godotsharp_pusherror,
(void *)godotsharp_pushwarning,
(void *)godotsharp_object_to_string,
diff --git a/modules/navigation/godot_navigation_server.cpp b/modules/navigation/godot_navigation_server.cpp
index 6bb522cc01..4191e46f62 100644
--- a/modules/navigation/godot_navigation_server.cpp
+++ b/modules/navigation/godot_navigation_server.cpp
@@ -453,11 +453,11 @@ COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) {
}
}
-COMMAND_2(agent_set_neighbor_dist, RID, p_agent, real_t, p_dist) {
+COMMAND_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_distance) {
RvoAgent *agent = agent_owner.get_or_null(p_agent);
ERR_FAIL_COND(agent == nullptr);
- agent->get_agent()->neighborDist_ = p_dist;
+ agent->get_agent()->neighborDist_ = p_distance;
}
COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count) {
diff --git a/modules/navigation/godot_navigation_server.h b/modules/navigation/godot_navigation_server.h
index e5f4b421bc..05ba46ede1 100644
--- a/modules/navigation/godot_navigation_server.h
+++ b/modules/navigation/godot_navigation_server.h
@@ -135,7 +135,7 @@ public:
virtual RID agent_create() const override;
COMMAND_2(agent_set_map, RID, p_agent, RID, p_map);
virtual RID agent_get_map(RID p_agent) const override;
- COMMAND_2(agent_set_neighbor_dist, RID, p_agent, real_t, p_dist);
+ COMMAND_2(agent_set_neighbor_distance, RID, p_agent, real_t, p_distance);
COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count);
COMMAND_2(agent_set_time_horizon, RID, p_agent, real_t, p_time);
COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius);
diff --git a/modules/noise/config.py b/modules/noise/config.py
index 74db20f2a4..2318d28c53 100644
--- a/modules/noise/config.py
+++ b/modules/noise/config.py
@@ -10,7 +10,7 @@ def get_doc_classes():
return [
"FastNoiseLite",
"Noise",
- "NoiseTexture",
+ "NoiseTexture2D",
]
diff --git a/modules/noise/doc_classes/NoiseTexture.xml b/modules/noise/doc_classes/NoiseTexture2D.xml
index 62a223b387..9eea2738c5 100644
--- a/modules/noise/doc_classes/NoiseTexture.xml
+++ b/modules/noise/doc_classes/NoiseTexture2D.xml
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="NoiseTexture" inherits="Texture2D" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
+<class name="NoiseTexture2D" inherits="Texture2D" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd">
<brief_description>
A texture filled with noise generated by a [Noise] object.
</brief_description>
<description>
Uses [FastNoiseLite] or other libraries to fill the texture data of your desired size.
- NoiseTexture can also generate normalmap textures.
+ NoiseTexture2D can also generate normalmap textures.
The class uses [Thread]s to generate the texture data internally, so [method Texture2D.get_image] may return [code]null[/code] if the generation process has not completed yet. In that case, you need to wait for the texture to be generated before accessing the image and the generated byte data:
[codeblock]
- var texture = NoiseTexture.new()
+ var texture = NoiseTexture2D.new()
texture.noise = FastNoiseLite.new()
await texture.changed
var image = texture.get_image()
diff --git a/modules/noise/editor/noise_editor_plugin.cpp b/modules/noise/editor/noise_editor_plugin.cpp
index 27a86f45b5..b6f7cbd2f8 100644
--- a/modules/noise/editor/noise_editor_plugin.cpp
+++ b/modules/noise/editor/noise_editor_plugin.cpp
@@ -35,7 +35,7 @@
#include "editor/editor_scale.h"
#include "modules/noise/noise.h"
-#include "modules/noise/noise_texture.h"
+#include "modules/noise/noise_texture_2d.h"
class NoisePreview : public Control {
GDCLASS(NoisePreview, Control)
@@ -102,7 +102,7 @@ private:
void update_preview() {
if (MIN(_preview_texture_size.width, _preview_texture_size.height) > 0) {
- Ref<NoiseTexture> tex;
+ Ref<NoiseTexture2D> tex;
tex.instantiate();
tex->set_width(_preview_texture_size.width);
tex->set_height(_preview_texture_size.height);
diff --git a/modules/noise/noise_texture.cpp b/modules/noise/noise_texture_2d.cpp
index 923b420581..8d279f9dd3 100644
--- a/modules/noise/noise_texture.cpp
+++ b/modules/noise/noise_texture_2d.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* noise_texture.cpp */
+/* noise_texture_2d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,58 +28,58 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "noise_texture.h"
+#include "noise_texture_2d.h"
#include "core/core_string_names.h"
#include "noise.h"
-NoiseTexture::NoiseTexture() {
+NoiseTexture2D::NoiseTexture2D() {
noise = Ref<Noise>();
_queue_update();
}
-NoiseTexture::~NoiseTexture() {
+NoiseTexture2D::~NoiseTexture2D() {
if (texture.is_valid()) {
RS::get_singleton()->free(texture);
}
noise_thread.wait_to_finish();
}
-void NoiseTexture::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_update_texture"), &NoiseTexture::_update_texture);
- ClassDB::bind_method(D_METHOD("_generate_texture"), &NoiseTexture::_generate_texture);
- ClassDB::bind_method(D_METHOD("_thread_done", "image"), &NoiseTexture::_thread_done);
+void NoiseTexture2D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_update_texture"), &NoiseTexture2D::_update_texture);
+ ClassDB::bind_method(D_METHOD("_generate_texture"), &NoiseTexture2D::_generate_texture);
+ ClassDB::bind_method(D_METHOD("_thread_done", "image"), &NoiseTexture2D::_thread_done);
- ClassDB::bind_method(D_METHOD("set_width", "width"), &NoiseTexture::set_width);
- ClassDB::bind_method(D_METHOD("set_height", "height"), &NoiseTexture::set_height);
+ ClassDB::bind_method(D_METHOD("set_width", "width"), &NoiseTexture2D::set_width);
+ ClassDB::bind_method(D_METHOD("set_height", "height"), &NoiseTexture2D::set_height);
- ClassDB::bind_method(D_METHOD("set_invert", "invert"), &NoiseTexture::set_invert);
- ClassDB::bind_method(D_METHOD("get_invert"), &NoiseTexture::get_invert);
+ ClassDB::bind_method(D_METHOD("set_invert", "invert"), &NoiseTexture2D::set_invert);
+ ClassDB::bind_method(D_METHOD("get_invert"), &NoiseTexture2D::get_invert);
- ClassDB::bind_method(D_METHOD("set_in_3d_space", "enable"), &NoiseTexture::set_in_3d_space);
- ClassDB::bind_method(D_METHOD("is_in_3d_space"), &NoiseTexture::is_in_3d_space);
+ ClassDB::bind_method(D_METHOD("set_in_3d_space", "enable"), &NoiseTexture2D::set_in_3d_space);
+ ClassDB::bind_method(D_METHOD("is_in_3d_space"), &NoiseTexture2D::is_in_3d_space);
- ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "invert"), &NoiseTexture::set_generate_mipmaps);
- ClassDB::bind_method(D_METHOD("is_generating_mipmaps"), &NoiseTexture::is_generating_mipmaps);
+ ClassDB::bind_method(D_METHOD("set_generate_mipmaps", "invert"), &NoiseTexture2D::set_generate_mipmaps);
+ ClassDB::bind_method(D_METHOD("is_generating_mipmaps"), &NoiseTexture2D::is_generating_mipmaps);
- ClassDB::bind_method(D_METHOD("set_seamless", "seamless"), &NoiseTexture::set_seamless);
- ClassDB::bind_method(D_METHOD("get_seamless"), &NoiseTexture::get_seamless);
+ ClassDB::bind_method(D_METHOD("set_seamless", "seamless"), &NoiseTexture2D::set_seamless);
+ ClassDB::bind_method(D_METHOD("get_seamless"), &NoiseTexture2D::get_seamless);
- ClassDB::bind_method(D_METHOD("set_seamless_blend_skirt", "seamless_blend_skirt"), &NoiseTexture::set_seamless_blend_skirt);
- ClassDB::bind_method(D_METHOD("get_seamless_blend_skirt"), &NoiseTexture::get_seamless_blend_skirt);
+ ClassDB::bind_method(D_METHOD("set_seamless_blend_skirt", "seamless_blend_skirt"), &NoiseTexture2D::set_seamless_blend_skirt);
+ ClassDB::bind_method(D_METHOD("get_seamless_blend_skirt"), &NoiseTexture2D::get_seamless_blend_skirt);
- ClassDB::bind_method(D_METHOD("set_as_normal_map", "as_normal_map"), &NoiseTexture::set_as_normal_map);
- ClassDB::bind_method(D_METHOD("is_normal_map"), &NoiseTexture::is_normal_map);
+ ClassDB::bind_method(D_METHOD("set_as_normal_map", "as_normal_map"), &NoiseTexture2D::set_as_normal_map);
+ ClassDB::bind_method(D_METHOD("is_normal_map"), &NoiseTexture2D::is_normal_map);
- ClassDB::bind_method(D_METHOD("set_bump_strength", "bump_strength"), &NoiseTexture::set_bump_strength);
- ClassDB::bind_method(D_METHOD("get_bump_strength"), &NoiseTexture::get_bump_strength);
+ ClassDB::bind_method(D_METHOD("set_bump_strength", "bump_strength"), &NoiseTexture2D::set_bump_strength);
+ ClassDB::bind_method(D_METHOD("get_bump_strength"), &NoiseTexture2D::get_bump_strength);
- ClassDB::bind_method(D_METHOD("set_color_ramp", "gradient"), &NoiseTexture::set_color_ramp);
- ClassDB::bind_method(D_METHOD("get_color_ramp"), &NoiseTexture::get_color_ramp);
+ ClassDB::bind_method(D_METHOD("set_color_ramp", "gradient"), &NoiseTexture2D::set_color_ramp);
+ ClassDB::bind_method(D_METHOD("get_color_ramp"), &NoiseTexture2D::get_color_ramp);
- ClassDB::bind_method(D_METHOD("set_noise", "noise"), &NoiseTexture::set_noise);
- ClassDB::bind_method(D_METHOD("get_noise"), &NoiseTexture::get_noise);
+ ClassDB::bind_method(D_METHOD("set_noise", "noise"), &NoiseTexture2D::set_noise);
+ ClassDB::bind_method(D_METHOD("get_noise"), &NoiseTexture2D::get_noise);
ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,1,or_greater,suffix:px"), "set_width", "get_width");
ADD_PROPERTY(PropertyInfo(Variant::INT, "height", PROPERTY_HINT_RANGE, "1,2048,1,or_greater,suffix:px"), "set_height", "get_height");
@@ -94,7 +94,7 @@ void NoiseTexture::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "Noise"), "set_noise", "get_noise");
}
-void NoiseTexture::_validate_property(PropertyInfo &p_property) const {
+void NoiseTexture2D::_validate_property(PropertyInfo &p_property) const {
if (p_property.name == "bump_strength") {
if (!as_normal_map) {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
@@ -108,7 +108,7 @@ void NoiseTexture::_validate_property(PropertyInfo &p_property) const {
}
}
-void NoiseTexture::_set_texture_image(const Ref<Image> &p_image) {
+void NoiseTexture2D::_set_texture_image(const Ref<Image> &p_image) {
image = p_image;
if (image.is_valid()) {
if (texture.is_valid()) {
@@ -121,7 +121,7 @@ void NoiseTexture::_set_texture_image(const Ref<Image> &p_image) {
emit_changed();
}
-void NoiseTexture::_thread_done(const Ref<Image> &p_image) {
+void NoiseTexture2D::_thread_done(const Ref<Image> &p_image) {
_set_texture_image(p_image);
noise_thread.wait_to_finish();
if (regen_queued) {
@@ -130,12 +130,12 @@ void NoiseTexture::_thread_done(const Ref<Image> &p_image) {
}
}
-void NoiseTexture::_thread_function(void *p_ud) {
- NoiseTexture *tex = static_cast<NoiseTexture *>(p_ud);
+void NoiseTexture2D::_thread_function(void *p_ud) {
+ NoiseTexture2D *tex = static_cast<NoiseTexture2D *>(p_ud);
tex->call_deferred(SNAME("_thread_done"), tex->_generate_texture());
}
-void NoiseTexture::_queue_update() {
+void NoiseTexture2D::_queue_update() {
if (update_queued) {
return;
}
@@ -144,7 +144,7 @@ void NoiseTexture::_queue_update() {
call_deferred(SNAME("_update_texture"));
}
-Ref<Image> NoiseTexture::_generate_texture() {
+Ref<Image> NoiseTexture2D::_generate_texture() {
// Prevent memdelete due to unref() on other thread.
Ref<Noise> ref_noise = noise;
@@ -172,7 +172,7 @@ Ref<Image> NoiseTexture::_generate_texture() {
return image;
}
-Ref<Image> NoiseTexture::_modulate_with_gradient(Ref<Image> p_image, Ref<Gradient> p_gradient) {
+Ref<Image> NoiseTexture2D::_modulate_with_gradient(Ref<Image> p_image, Ref<Gradient> p_gradient) {
int width = p_image->get_width();
int height = p_image->get_height();
@@ -191,7 +191,7 @@ Ref<Image> NoiseTexture::_modulate_with_gradient(Ref<Image> p_image, Ref<Gradien
return new_image;
}
-void NoiseTexture::_update_texture() {
+void NoiseTexture2D::_update_texture() {
bool use_thread = true;
if (first_time) {
use_thread = false;
@@ -215,25 +215,25 @@ void NoiseTexture::_update_texture() {
update_queued = false;
}
-void NoiseTexture::set_noise(Ref<Noise> p_noise) {
+void NoiseTexture2D::set_noise(Ref<Noise> p_noise) {
if (p_noise == noise) {
return;
}
if (noise.is_valid()) {
- noise->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NoiseTexture::_queue_update));
+ noise->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NoiseTexture2D::_queue_update));
}
noise = p_noise;
if (noise.is_valid()) {
- noise->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NoiseTexture::_queue_update));
+ noise->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NoiseTexture2D::_queue_update));
}
_queue_update();
}
-Ref<Noise> NoiseTexture::get_noise() {
+Ref<Noise> NoiseTexture2D::get_noise() {
return noise;
}
-void NoiseTexture::set_width(int p_width) {
+void NoiseTexture2D::set_width(int p_width) {
ERR_FAIL_COND(p_width <= 0);
if (p_width == size.x) {
return;
@@ -242,7 +242,7 @@ void NoiseTexture::set_width(int p_width) {
_queue_update();
}
-void NoiseTexture::set_height(int p_height) {
+void NoiseTexture2D::set_height(int p_height) {
ERR_FAIL_COND(p_height <= 0);
if (p_height == size.y) {
return;
@@ -251,7 +251,7 @@ void NoiseTexture::set_height(int p_height) {
_queue_update();
}
-void NoiseTexture::set_invert(bool p_invert) {
+void NoiseTexture2D::set_invert(bool p_invert) {
if (p_invert == invert) {
return;
}
@@ -259,22 +259,22 @@ void NoiseTexture::set_invert(bool p_invert) {
_queue_update();
}
-bool NoiseTexture::get_invert() const {
+bool NoiseTexture2D::get_invert() const {
return invert;
}
-void NoiseTexture::set_in_3d_space(bool p_enable) {
+void NoiseTexture2D::set_in_3d_space(bool p_enable) {
if (p_enable == in_3d_space) {
return;
}
in_3d_space = p_enable;
_queue_update();
}
-bool NoiseTexture::is_in_3d_space() const {
+bool NoiseTexture2D::is_in_3d_space() const {
return in_3d_space;
}
-void NoiseTexture::set_generate_mipmaps(bool p_enable) {
+void NoiseTexture2D::set_generate_mipmaps(bool p_enable) {
if (p_enable == generate_mipmaps) {
return;
}
@@ -282,11 +282,11 @@ void NoiseTexture::set_generate_mipmaps(bool p_enable) {
_queue_update();
}
-bool NoiseTexture::is_generating_mipmaps() const {
+bool NoiseTexture2D::is_generating_mipmaps() const {
return generate_mipmaps;
}
-void NoiseTexture::set_seamless(bool p_seamless) {
+void NoiseTexture2D::set_seamless(bool p_seamless) {
if (p_seamless == seamless) {
return;
}
@@ -295,11 +295,11 @@ void NoiseTexture::set_seamless(bool p_seamless) {
notify_property_list_changed();
}
-bool NoiseTexture::get_seamless() {
+bool NoiseTexture2D::get_seamless() {
return seamless;
}
-void NoiseTexture::set_seamless_blend_skirt(real_t p_blend_skirt) {
+void NoiseTexture2D::set_seamless_blend_skirt(real_t p_blend_skirt) {
ERR_FAIL_COND(p_blend_skirt < 0.05 || p_blend_skirt > 1);
if (p_blend_skirt == seamless_blend_skirt) {
@@ -308,11 +308,11 @@ void NoiseTexture::set_seamless_blend_skirt(real_t p_blend_skirt) {
seamless_blend_skirt = p_blend_skirt;
_queue_update();
}
-real_t NoiseTexture::get_seamless_blend_skirt() {
+real_t NoiseTexture2D::get_seamless_blend_skirt() {
return seamless_blend_skirt;
}
-void NoiseTexture::set_as_normal_map(bool p_as_normal_map) {
+void NoiseTexture2D::set_as_normal_map(bool p_as_normal_map) {
if (p_as_normal_map == as_normal_map) {
return;
}
@@ -321,11 +321,11 @@ void NoiseTexture::set_as_normal_map(bool p_as_normal_map) {
notify_property_list_changed();
}
-bool NoiseTexture::is_normal_map() {
+bool NoiseTexture2D::is_normal_map() {
return as_normal_map;
}
-void NoiseTexture::set_bump_strength(float p_bump_strength) {
+void NoiseTexture2D::set_bump_strength(float p_bump_strength) {
if (p_bump_strength == bump_strength) {
return;
}
@@ -335,37 +335,37 @@ void NoiseTexture::set_bump_strength(float p_bump_strength) {
}
}
-float NoiseTexture::get_bump_strength() {
+float NoiseTexture2D::get_bump_strength() {
return bump_strength;
}
-void NoiseTexture::set_color_ramp(const Ref<Gradient> &p_gradient) {
+void NoiseTexture2D::set_color_ramp(const Ref<Gradient> &p_gradient) {
if (p_gradient == color_ramp) {
return;
}
if (color_ramp.is_valid()) {
- color_ramp->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NoiseTexture::_queue_update));
+ color_ramp->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NoiseTexture2D::_queue_update));
}
color_ramp = p_gradient;
if (color_ramp.is_valid()) {
- color_ramp->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NoiseTexture::_queue_update));
+ color_ramp->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NoiseTexture2D::_queue_update));
}
_queue_update();
}
-Ref<Gradient> NoiseTexture::get_color_ramp() const {
+Ref<Gradient> NoiseTexture2D::get_color_ramp() const {
return color_ramp;
}
-int NoiseTexture::get_width() const {
+int NoiseTexture2D::get_width() const {
return size.x;
}
-int NoiseTexture::get_height() const {
+int NoiseTexture2D::get_height() const {
return size.y;
}
-RID NoiseTexture::get_rid() const {
+RID NoiseTexture2D::get_rid() const {
if (!texture.is_valid()) {
texture = RS::get_singleton()->texture_2d_placeholder_create();
}
@@ -373,6 +373,6 @@ RID NoiseTexture::get_rid() const {
return texture;
}
-Ref<Image> NoiseTexture::get_image() const {
+Ref<Image> NoiseTexture2D::get_image() const {
return image;
}
diff --git a/modules/noise/noise_texture.h b/modules/noise/noise_texture_2d.h
index 83fbcc2d10..8f8e256fb9 100644
--- a/modules/noise/noise_texture.h
+++ b/modules/noise/noise_texture_2d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* noise_texture.h */
+/* noise_texture_2d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,16 +28,16 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef NOISE_TEXTURE_H
-#define NOISE_TEXTURE_H
+#ifndef NOISE_TEXTURE_2D_H
+#define NOISE_TEXTURE_2D_H
#include "noise.h"
#include "core/object/ref_counted.h"
#include "scene/resources/texture.h"
-class NoiseTexture : public Texture2D {
- GDCLASS(NoiseTexture, Texture2D);
+class NoiseTexture2D : public Texture2D {
+ GDCLASS(NoiseTexture2D, Texture2D);
private:
Ref<Image> image;
@@ -116,8 +116,8 @@ public:
virtual Ref<Image> get_image() const override;
- NoiseTexture();
- virtual ~NoiseTexture();
+ NoiseTexture2D();
+ virtual ~NoiseTexture2D();
};
-#endif // NOISE_TEXTURE_H
+#endif // NOISE_TEXTURE_2D_H
diff --git a/modules/noise/register_types.cpp b/modules/noise/register_types.cpp
index d0cfc4e944..c44bf9828f 100644
--- a/modules/noise/register_types.cpp
+++ b/modules/noise/register_types.cpp
@@ -32,7 +32,7 @@
#include "fastnoise_lite.h"
#include "noise.h"
-#include "noise_texture.h"
+#include "noise_texture_2d.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_plugin.h"
@@ -41,9 +41,10 @@
void initialize_noise_module(ModuleInitializationLevel p_level) {
if (p_level == MODULE_INITIALIZATION_LEVEL_SCENE) {
- GDREGISTER_CLASS(NoiseTexture);
+ GDREGISTER_CLASS(NoiseTexture2D);
GDREGISTER_ABSTRACT_CLASS(Noise);
GDREGISTER_CLASS(FastNoiseLite);
+ ClassDB::add_compatibility_class("NoiseTexture", "NoiseTexture2D");
}
#ifdef TOOLS_ENABLED
diff --git a/modules/raycast/SCsub b/modules/raycast/SCsub
index ef4c598194..074795759a 100644
--- a/modules/raycast/SCsub
+++ b/modules/raycast/SCsub
@@ -66,7 +66,7 @@ if env["builtin_embree"]:
env_raycast.Append(CPPDEFINES=["EMBREE_TARGET_SSE2", "EMBREE_LOWEST_ISA", "TASKING_INTERNAL", "NDEBUG"])
if not env.msvc:
- if env["arch"] in ["x86", "x86_64"]:
+ if env["arch"] == "x86_64":
env_raycast.Append(CPPFLAGS=["-msse2", "-mxsave"])
if env["platform"] == "windows":
@@ -83,7 +83,7 @@ if env["builtin_embree"]:
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources)
- if not env["arch"] in ["x86", "x86_64"] or env.msvc:
+ if env["arch"] == "arm64" or env.msvc:
# Embree needs those, it will automatically use SSE2NEON in ARM
env_thirdparty.Append(CPPDEFINES=["__SSE2__", "__SSE__"])
diff --git a/modules/raycast/config.py b/modules/raycast/config.py
index 7e8b3e9840..438779343e 100644
--- a/modules/raycast/config.py
+++ b/modules/raycast/config.py
@@ -1,18 +1,6 @@
def can_build(env, platform):
- # Depends on Embree library, which only supports x86_64 and aarch64.
- if env["arch"].startswith("rv") or env["arch"].startswith("ppc"):
- return False
-
- if platform == "android":
- return env["android_arch"] in ["arm64v8", "x86_64"]
-
- if platform == "javascript":
- return False # No SIMD support yet
-
- if env["bits"] == "32":
- return False
-
- return True
+ # Depends on Embree library, which only supports x86_64 and arm64.
+ return env["arch"] in ["x86_64", "arm64"]
def configure(env):
diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp
index 4c9302eb0c..5f839bd979 100644
--- a/modules/svg/image_loader_svg.cpp
+++ b/modules/svg/image_loader_svg.cpp
@@ -136,11 +136,11 @@ 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, bool p_force_linear, float p_scale) {
+Error ImageLoaderSVG::load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, uint32_t p_flags, float p_scale) {
String svg = p_fileaccess->get_as_utf8_string();
create_image_from_string(p_image, svg, p_scale, false, HashMap<Color, Color>());
ERR_FAIL_COND_V(p_image->is_empty(), FAILED);
- if (p_force_linear) {
+ if (p_flags & FLAG_FORCE_LINEAR) {
p_image->srgb_to_linear();
}
return OK;
diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h
index f28df60c44..fc89b63edb 100644
--- a/modules/svg/image_loader_svg.h
+++ b/modules/svg/image_loader_svg.h
@@ -39,7 +39,7 @@ class ImageLoaderSVG : public ImageFormatLoader {
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, bool p_force_linear, float p_scale) override;
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, uint32_t p_flags, float p_scale) override;
virtual void get_recognized_extensions(List<String> *p_extensions) const override;
};
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index e80eb43369..366e1ba604 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -29,12 +29,12 @@
/*************************************************************************/
#include "text_server_adv.h"
-#include "core/object/worker_thread_pool.h"
#ifdef GDEXTENSION
// Headers for building as GDExtension plug-in.
#include <godot_cpp/classes/file.hpp>
+#include <godot_cpp/classes/project_settings.hpp>
#include <godot_cpp/classes/rendering_server.hpp>
#include <godot_cpp/classes/translation_server.hpp>
#include <godot_cpp/core/error_macros.hpp>
@@ -44,8 +44,10 @@ using namespace godot;
#else
// 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"
#include "core/string/translation.h"
@@ -791,6 +793,10 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_
for (int i = 0; i < p_data->textures.size(); i++) {
const FontTexture &ct = p_data->textures[i];
+ if (p_image_format != ct.format) {
+ continue;
+ }
+
if (mw > ct.texture_w || mh > ct.texture_h) { // Too big for this texture.
continue;
}
@@ -1082,9 +1088,28 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf(
#endif
#ifdef MODULE_FREETYPE_ENABLED
-_FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitmap(FontForSizeAdvanced *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance) const {
+_FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitmap(FontForSizeAdvanced *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance, bool p_bgra) const {
int w = bitmap.width;
int h = bitmap.rows;
+ int color_size = 2;
+
+ switch (bitmap.pixel_mode) {
+ case FT_PIXEL_MODE_MONO:
+ case FT_PIXEL_MODE_GRAY: {
+ color_size = 2;
+ } break;
+ case FT_PIXEL_MODE_BGRA: {
+ color_size = 4;
+ } break;
+ case FT_PIXEL_MODE_LCD: {
+ color_size = 4;
+ w /= 3;
+ } break;
+ case FT_PIXEL_MODE_LCD_V: {
+ color_size = 4;
+ h /= 3;
+ } break;
+ }
int mw = w + p_rect_margin * 4;
int mh = h + p_rect_margin * 4;
@@ -1092,7 +1117,6 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma
ERR_FAIL_COND_V(mw > 4096, FontGlyph());
ERR_FAIL_COND_V(mh > 4096, FontGlyph());
- int color_size = bitmap.pixel_mode == FT_PIXEL_MODE_BGRA ? 4 : 2;
Image::Format require_format = color_size == 4 ? Image::FORMAT_RGBA8 : Image::FORMAT_LA8;
FontTexturePosition tex_pos = find_texture_pos_for_glyph(p_data, color_size, require_format, mw, mh, false);
@@ -1127,6 +1151,34 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma
wr[ofs + 0] = bitmap.buffer[ofs_color + 2];
wr[ofs + 3] = bitmap.buffer[ofs_color + 3];
} break;
+ case FT_PIXEL_MODE_LCD: {
+ int ofs_color = i * bitmap.pitch + (j * 3);
+ if (p_bgra) {
+ wr[ofs + 0] = bitmap.buffer[ofs_color + 0];
+ wr[ofs + 1] = bitmap.buffer[ofs_color + 1];
+ wr[ofs + 2] = bitmap.buffer[ofs_color + 2];
+ wr[ofs + 3] = 255;
+ } else {
+ wr[ofs + 0] = bitmap.buffer[ofs_color + 2];
+ wr[ofs + 1] = bitmap.buffer[ofs_color + 1];
+ wr[ofs + 2] = bitmap.buffer[ofs_color + 0];
+ wr[ofs + 3] = 255;
+ }
+ } break;
+ case FT_PIXEL_MODE_LCD_V: {
+ int ofs_color = i * bitmap.pitch * 3 + j;
+ if (p_bgra) {
+ wr[ofs + 0] = bitmap.buffer[ofs_color + bitmap.pitch * 2];
+ wr[ofs + 1] = bitmap.buffer[ofs_color + bitmap.pitch];
+ wr[ofs + 2] = bitmap.buffer[ofs_color + 0];
+ wr[ofs + 3] = 255;
+ } else {
+ wr[ofs + 0] = bitmap.buffer[ofs_color + 0];
+ wr[ofs + 1] = bitmap.buffer[ofs_color + bitmap.pitch];
+ wr[ofs + 2] = bitmap.buffer[ofs_color + bitmap.pitch * 2];
+ wr[ofs + 3] = 255;
+ }
+ } break;
default:
ERR_FAIL_V_MSG(FontGlyph(), "Font uses unsupported pixel format: " + String::num_int64(bitmap.pixel_mode) + ".");
break;
@@ -1230,9 +1282,44 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data,
FT_Outline_Transform(&fd->face->glyph->outline, &mat);
}
+ FT_Render_Mode aa_mode = FT_RENDER_MODE_NORMAL;
+ bool bgra = false;
+ switch (p_font_data->antialiasing) {
+ case FONT_ANTIALIASING_NONE: {
+ aa_mode = FT_RENDER_MODE_MONO;
+ } break;
+ case FONT_ANTIALIASING_GRAY: {
+ aa_mode = FT_RENDER_MODE_NORMAL;
+ } break;
+ case FONT_ANTIALIASING_LCD: {
+ int aa_layout = (int)((p_glyph >> 24) & 7);
+ switch (aa_layout) {
+ case FONT_LCD_SUBPIXEL_LAYOUT_HRGB: {
+ aa_mode = FT_RENDER_MODE_LCD;
+ bgra = false;
+ } break;
+ case FONT_LCD_SUBPIXEL_LAYOUT_HBGR: {
+ aa_mode = FT_RENDER_MODE_LCD;
+ bgra = true;
+ } break;
+ case FONT_LCD_SUBPIXEL_LAYOUT_VRGB: {
+ aa_mode = FT_RENDER_MODE_LCD_V;
+ bgra = false;
+ } break;
+ case FONT_LCD_SUBPIXEL_LAYOUT_VBGR: {
+ aa_mode = FT_RENDER_MODE_LCD_V;
+ bgra = true;
+ } break;
+ default: {
+ aa_mode = FT_RENDER_MODE_NORMAL;
+ } break;
+ }
+ } break;
+ }
+
if (!outline) {
if (!p_font_data->msdf) {
- error = FT_Render_Glyph(fd->face->glyph, p_font_data->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
+ error = FT_Render_Glyph(fd->face->glyph, aa_mode);
}
FT_GlyphSlot slot = fd->face->glyph;
if (!error) {
@@ -1244,7 +1331,7 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data,
ERR_FAIL_V_MSG(false, "Compiled without MSDFGEN support!");
#endif
} else {
- gl = rasterize_bitmap(fd, rect_range, slot->bitmap, slot->bitmap_top, slot->bitmap_left, Vector2((h + (1 << 9)) >> 10, (v + (1 << 9)) >> 10) / 64.0);
+ gl = rasterize_bitmap(fd, rect_range, slot->bitmap, slot->bitmap_top, slot->bitmap_left, Vector2((h + (1 << 9)) >> 10, (v + (1 << 9)) >> 10) / 64.0, bgra);
}
}
} else {
@@ -1264,11 +1351,11 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_glyph(FontAdvanced *p_font_data,
if (FT_Glyph_Stroke(&glyph, stroker, 1) != 0) {
goto cleanup_glyph;
}
- if (FT_Glyph_To_Bitmap(&glyph, p_font_data->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, nullptr, 1) != 0) {
+ if (FT_Glyph_To_Bitmap(&glyph, aa_mode, nullptr, 1) != 0) {
goto cleanup_glyph;
}
glyph_bitmap = (FT_BitmapGlyph)glyph;
- gl = rasterize_bitmap(fd, rect_range, glyph_bitmap->bitmap, glyph_bitmap->top, glyph_bitmap->left, Vector2());
+ gl = rasterize_bitmap(fd, rect_range, glyph_bitmap->bitmap, glyph_bitmap->top, glyph_bitmap->left, Vector2(), bgra);
cleanup_glyph:
FT_Done_Glyph(glyph);
@@ -1925,23 +2012,23 @@ String TextServerAdvanced::font_get_name(const RID &p_font_rid) const {
return fd->font_name;
}
-void TextServerAdvanced::font_set_antialiased(const RID &p_font_rid, bool p_antialiased) {
+void TextServerAdvanced::font_set_antialiasing(RID p_font_rid, TextServer::FontAntialiasing p_antialiasing) {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
- if (fd->antialiased != p_antialiased) {
+ if (fd->antialiasing != p_antialiasing) {
_font_clear_cache(fd);
- fd->antialiased = p_antialiased;
+ fd->antialiasing = p_antialiasing;
}
}
-bool TextServerAdvanced::font_is_antialiased(const RID &p_font_rid) const {
+TextServer::FontAntialiasing TextServerAdvanced::font_get_antialiasing(RID p_font_rid) const {
FontAdvanced *fd = font_owner.get_or_null(p_font_rid);
- ERR_FAIL_COND_V(!fd, false);
+ ERR_FAIL_COND_V(!fd, TextServer::FONT_ANTIALIASING_NONE);
MutexLock lock(fd->mutex);
- return fd->antialiased;
+ return fd->antialiasing;
}
void TextServerAdvanced::font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) {
@@ -2514,7 +2601,16 @@ Vector2 TextServerAdvanced::font_get_glyph_advance(const RID &p_font_rid, int64_
Vector2i size = _get_size(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Vector2());
- if (!_ensure_glyph(fd, size, p_glyph)) {
+
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
+ if (!_ensure_glyph(fd, size, p_glyph | mod)) {
return Vector2(); // Invalid or non graphicl glyph, do not display errors.
}
@@ -2557,7 +2653,16 @@ Vector2 TextServerAdvanced::font_get_glyph_offset(const RID &p_font_rid, const V
Vector2i size = _get_size_outline(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Vector2());
- if (!_ensure_glyph(fd, size, p_glyph)) {
+
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
+ if (!_ensure_glyph(fd, size, p_glyph | mod)) {
return Vector2(); // Invalid or non graphicl glyph, do not display errors.
}
@@ -2593,7 +2698,16 @@ Vector2 TextServerAdvanced::font_get_glyph_size(const RID &p_font_rid, const Vec
Vector2i size = _get_size_outline(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Vector2());
- if (!_ensure_glyph(fd, size, p_glyph)) {
+
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
+ if (!_ensure_glyph(fd, size, p_glyph | mod)) {
return Vector2(); // Invalid or non graphicl glyph, do not display errors.
}
@@ -2629,7 +2743,16 @@ Rect2 TextServerAdvanced::font_get_glyph_uv_rect(const RID &p_font_rid, const Ve
Vector2i size = _get_size_outline(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Rect2());
- if (!_ensure_glyph(fd, size, p_glyph)) {
+
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
+ if (!_ensure_glyph(fd, size, p_glyph | mod)) {
return Rect2(); // Invalid or non graphicl glyph, do not display errors.
}
@@ -2660,7 +2783,16 @@ int64_t TextServerAdvanced::font_get_glyph_texture_idx(const RID &p_font_rid, co
Vector2i size = _get_size_outline(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), -1);
- if (!_ensure_glyph(fd, size, p_glyph)) {
+
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
+ if (!_ensure_glyph(fd, size, p_glyph | mod)) {
return -1; // Invalid or non graphicl glyph, do not display errors.
}
@@ -2691,7 +2823,16 @@ RID TextServerAdvanced::font_get_glyph_texture_rid(const RID &p_font_rid, const
Vector2i size = _get_size_outline(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), RID());
- if (!_ensure_glyph(fd, size, p_glyph)) {
+
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
+ if (!_ensure_glyph(fd, size, p_glyph | mod)) {
return RID(); // Invalid or non graphicl glyph, do not display errors.
}
@@ -2730,7 +2871,16 @@ Size2 TextServerAdvanced::font_get_glyph_texture_size(const RID &p_font_rid, con
Vector2i size = _get_size_outline(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Size2());
- if (!_ensure_glyph(fd, size, p_glyph)) {
+
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
+ if (!_ensure_glyph(fd, size, p_glyph | mod)) {
return Size2(); // Invalid or non graphicl glyph, do not display errors.
}
@@ -2986,16 +3136,18 @@ void TextServerAdvanced::font_render_range(const RID &p_font_rid, const Vector2i
if (fd->msdf) {
_ensure_glyph(fd, size, (int32_t)idx);
} else {
- if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
- _ensure_glyph(fd, size, (int32_t)idx | (0 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (1 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (2 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (3 << 27));
- } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
- _ensure_glyph(fd, size, (int32_t)idx | (1 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (0 << 27));
- } else {
- _ensure_glyph(fd, size, (int32_t)idx);
+ for (int aa = 0; aa < ((fd->antialiasing == FONT_ANTIALIASING_LCD) ? FONT_LCD_SUBPIXEL_LAYOUT_MAX : 1); aa++) {
+ if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
+ _ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (2 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (3 << 27) | (aa << 24));
+ } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
+ _ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24));
+ } else {
+ _ensure_glyph(fd, size, (int32_t)idx | (aa << 24));
+ }
}
}
}
@@ -3016,16 +3168,18 @@ void TextServerAdvanced::font_render_glyph(const RID &p_font_rid, const Vector2i
if (fd->msdf) {
_ensure_glyph(fd, size, (int32_t)idx);
} else {
- if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
- _ensure_glyph(fd, size, (int32_t)idx | (0 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (1 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (2 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (3 << 27));
- } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
- _ensure_glyph(fd, size, (int32_t)idx | (1 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (0 << 27));
- } else {
- _ensure_glyph(fd, size, (int32_t)idx);
+ for (int aa = 0; aa < ((fd->antialiasing == FONT_ANTIALIASING_LCD) ? FONT_LCD_SUBPIXEL_LAYOUT_MAX : 1); aa++) {
+ if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
+ _ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (2 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (3 << 27) | (aa << 24));
+ } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
+ _ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24));
+ } else {
+ _ensure_glyph(fd, size, (int32_t)idx | (aa << 24));
+ }
}
}
}
@@ -3041,9 +3195,19 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can
ERR_FAIL_COND(!_ensure_cache_for_size(fd, size));
int32_t index = p_index & 0xffffff; // Remove subpixel shifts.
+ bool lcd_aa = false;
#ifdef MODULE_FREETYPE_ENABLED
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");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ lcd_aa = true;
+ index = index | (layout << 24);
+ }
+ }
+ // Subpixel X-shift, bits 27, 28
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
int xshift = (int)(Math::floor(4 * (p_pos.x + 0.125)) - 4 * Math::floor(p_pos.x + 0.125));
index = index | (xshift << 27);
@@ -3065,7 +3229,7 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can
if (gl.texture_idx != -1) {
Color modulate = p_color;
#ifdef MODULE_FREETYPE_ENABLED
- if (fd->cache[size]->face && fd->cache[size]->textures[gl.texture_idx].format == Image::FORMAT_RGBA8) {
+ if (fd->cache[size]->face && (fd->cache[size]->textures[gl.texture_idx].format == Image::FORMAT_RGBA8) && !lcd_aa) {
modulate.r = modulate.g = modulate.b = 1.0;
}
#endif
@@ -3103,7 +3267,11 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can
}
cpos += gl.rect.position;
Size2 csize = gl.rect.size;
- RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, false, false);
+ if (lcd_aa) {
+ RenderingServer::get_singleton()->canvas_item_add_lcd_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate);
+ } else {
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, false, false);
+ }
}
}
}
@@ -3119,9 +3287,19 @@ void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RI
ERR_FAIL_COND(!_ensure_cache_for_size(fd, size));
int32_t index = p_index & 0xffffff; // Remove subpixel shifts.
+ bool lcd_aa = false;
#ifdef MODULE_FREETYPE_ENABLED
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");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ lcd_aa = true;
+ index = index | (layout << 24);
+ }
+ }
+ // Subpixel X-shift, bits 27, 28
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
int xshift = (int)(Math::floor(4 * (p_pos.x + 0.125)) - 4 * Math::floor(p_pos.x + 0.125));
index = index | (xshift << 27);
@@ -3181,7 +3359,11 @@ void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RI
}
cpos += gl.rect.position;
Size2 csize = gl.rect.size;
- RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, false, false);
+ if (lcd_aa) {
+ RenderingServer::get_singleton()->canvas_item_add_lcd_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate);
+ } else {
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, false, false);
+ }
}
}
}
@@ -4947,6 +5129,14 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(p_sd->hb_buffer, &glyph_count);
hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(p_sd->hb_buffer, &glyph_count);
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
// Process glyphs.
if (glyph_count > 0) {
Glyph *w = (Glyph *)memalloc(glyph_count * sizeof(Glyph));
@@ -5000,7 +5190,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star
gl.index = glyph_info[i].codepoint;
if (gl.index != 0) {
- _ensure_glyph(fd, fss, gl.index);
+ _ensure_glyph(fd, fss, gl.index | mod);
if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
if (subpos) {
gl.advance = glyph_pos[i].x_advance / (64.0 / scale) + ea;
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index 6c3e8dbdcb..02abc31c55 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -223,7 +223,7 @@ class TextServerAdvanced : public TextServerExtension {
struct FontAdvanced {
Mutex mutex;
- bool antialiased = true;
+ TextServer::FontAntialiasing antialiasing = TextServer::FONT_ANTIALIASING_GRAY;
bool mipmaps = false;
bool msdf = false;
int msdf_range = 14;
@@ -271,7 +271,7 @@ class TextServerAdvanced : public TextServerExtension {
_FORCE_INLINE_ FontGlyph rasterize_msdf(FontAdvanced *p_font_data, FontForSizeAdvanced *p_data, int p_pixel_range, int p_rect_margin, FT_Outline *outline, const Vector2 &advance) const;
#endif
#ifdef MODULE_FREETYPE_ENABLED
- _FORCE_INLINE_ FontGlyph rasterize_bitmap(FontForSizeAdvanced *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance) const;
+ _FORCE_INLINE_ FontGlyph rasterize_bitmap(FontForSizeAdvanced *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance, bool p_bgra) const;
#endif
_FORCE_INLINE_ bool _ensure_glyph(FontAdvanced *p_font_data, const Vector2i &p_size, int32_t p_glyph) const;
_FORCE_INLINE_ bool _ensure_cache_for_size(FontAdvanced *p_font_data, const Vector2i &p_size) const;
@@ -498,8 +498,8 @@ public:
virtual void font_set_name(const RID &p_font_rid, const String &p_name) override;
virtual String font_get_name(const RID &p_font_rid) const override;
- virtual void font_set_antialiased(const RID &p_font_rid, bool p_antialiased) override;
- virtual bool font_is_antialiased(const RID &p_font_rid) const override;
+ virtual void font_set_antialiasing(RID p_font_rid, TextServer::FontAntialiasing p_antialiasing) override;
+ virtual TextServer::FontAntialiasing font_get_antialiasing(RID p_font_rid) const override;
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;
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp
index 016bcfc886..53b303cb20 100644
--- a/modules/text_server_fb/text_server_fb.cpp
+++ b/modules/text_server_fb/text_server_fb.cpp
@@ -34,6 +34,7 @@
// Headers for building as GDExtension plug-in.
#include <godot_cpp/classes/file.hpp>
+#include <godot_cpp/classes/project_settings.hpp>
#include <godot_cpp/classes/rendering_server.hpp>
#include <godot_cpp/classes/translation_server.hpp>
#include <godot_cpp/core/error_macros.hpp>
@@ -43,6 +44,7 @@ using namespace godot;
#else
// Headers for building as built-in module.
+#include "core/config/project_settings.h"
#include "core/error/error_macros.h"
#include "core/string/print_string.h"
#include "core/string/ucaps.h"
@@ -209,6 +211,10 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_
for (int i = 0; i < p_data->textures.size(); i++) {
const FontTexture &ct = p_data->textures[i];
+ if (p_image_format != ct.format) {
+ continue;
+ }
+
if (mw > ct.texture_w || mh > ct.texture_h) { // Too big for this texture.
continue;
}
@@ -500,9 +506,28 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf(
#endif
#ifdef MODULE_FREETYPE_ENABLED
-_FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitmap(FontForSizeFallback *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance) const {
+_FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitmap(FontForSizeFallback *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance, bool p_bgra) const {
int w = bitmap.width;
int h = bitmap.rows;
+ int color_size = 2;
+
+ switch (bitmap.pixel_mode) {
+ case FT_PIXEL_MODE_MONO:
+ case FT_PIXEL_MODE_GRAY: {
+ color_size = 2;
+ } break;
+ case FT_PIXEL_MODE_BGRA: {
+ color_size = 4;
+ } break;
+ case FT_PIXEL_MODE_LCD: {
+ color_size = 4;
+ w /= 3;
+ } break;
+ case FT_PIXEL_MODE_LCD_V: {
+ color_size = 4;
+ h /= 3;
+ } break;
+ }
int mw = w + p_rect_margin * 4;
int mh = h + p_rect_margin * 4;
@@ -510,7 +535,6 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitma
ERR_FAIL_COND_V(mw > 4096, FontGlyph());
ERR_FAIL_COND_V(mh > 4096, FontGlyph());
- int color_size = bitmap.pixel_mode == FT_PIXEL_MODE_BGRA ? 4 : 2;
Image::Format require_format = color_size == 4 ? Image::FORMAT_RGBA8 : Image::FORMAT_LA8;
FontTexturePosition tex_pos = find_texture_pos_for_glyph(p_data, color_size, require_format, mw, mh, false);
@@ -545,6 +569,34 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitma
wr[ofs + 0] = bitmap.buffer[ofs_color + 2];
wr[ofs + 3] = bitmap.buffer[ofs_color + 3];
} break;
+ case FT_PIXEL_MODE_LCD: {
+ int ofs_color = i * bitmap.pitch + (j * 3);
+ if (p_bgra) {
+ wr[ofs + 0] = bitmap.buffer[ofs_color + 0];
+ wr[ofs + 1] = bitmap.buffer[ofs_color + 1];
+ wr[ofs + 2] = bitmap.buffer[ofs_color + 2];
+ wr[ofs + 3] = 255;
+ } else {
+ wr[ofs + 0] = bitmap.buffer[ofs_color + 2];
+ wr[ofs + 1] = bitmap.buffer[ofs_color + 1];
+ wr[ofs + 2] = bitmap.buffer[ofs_color + 0];
+ wr[ofs + 3] = 255;
+ }
+ } break;
+ case FT_PIXEL_MODE_LCD_V: {
+ int ofs_color = i * bitmap.pitch * 3 + j;
+ if (p_bgra) {
+ wr[ofs + 0] = bitmap.buffer[ofs_color + bitmap.pitch * 2];
+ wr[ofs + 1] = bitmap.buffer[ofs_color + bitmap.pitch];
+ wr[ofs + 2] = bitmap.buffer[ofs_color + 0];
+ wr[ofs + 3] = 255;
+ } else {
+ wr[ofs + 0] = bitmap.buffer[ofs_color + 0];
+ wr[ofs + 1] = bitmap.buffer[ofs_color + bitmap.pitch];
+ wr[ofs + 2] = bitmap.buffer[ofs_color + bitmap.pitch * 2];
+ wr[ofs + 3] = 255;
+ }
+ } break;
default:
ERR_FAIL_V_MSG(FontGlyph(), "Font uses unsupported pixel format: " + String::num_int64(bitmap.pixel_mode) + ".");
break;
@@ -650,9 +702,44 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontFallback *p_font_data,
FT_Outline_Transform(&fd->face->glyph->outline, &mat);
}
+ FT_Render_Mode aa_mode = FT_RENDER_MODE_NORMAL;
+ bool bgra = false;
+ switch (p_font_data->antialiasing) {
+ case FONT_ANTIALIASING_NONE: {
+ aa_mode = FT_RENDER_MODE_MONO;
+ } break;
+ case FONT_ANTIALIASING_GRAY: {
+ aa_mode = FT_RENDER_MODE_NORMAL;
+ } break;
+ case FONT_ANTIALIASING_LCD: {
+ int aa_layout = (int)((p_glyph >> 24) & 7);
+ switch (aa_layout) {
+ case FONT_LCD_SUBPIXEL_LAYOUT_HRGB: {
+ aa_mode = FT_RENDER_MODE_LCD;
+ bgra = false;
+ } break;
+ case FONT_LCD_SUBPIXEL_LAYOUT_HBGR: {
+ aa_mode = FT_RENDER_MODE_LCD;
+ bgra = true;
+ } break;
+ case FONT_LCD_SUBPIXEL_LAYOUT_VRGB: {
+ aa_mode = FT_RENDER_MODE_LCD_V;
+ bgra = false;
+ } break;
+ case FONT_LCD_SUBPIXEL_LAYOUT_VBGR: {
+ aa_mode = FT_RENDER_MODE_LCD_V;
+ bgra = true;
+ } break;
+ default: {
+ aa_mode = FT_RENDER_MODE_NORMAL;
+ } break;
+ }
+ } break;
+ }
+
if (!outline) {
if (!p_font_data->msdf) {
- error = FT_Render_Glyph(fd->face->glyph, p_font_data->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
+ error = FT_Render_Glyph(fd->face->glyph, aa_mode);
}
FT_GlyphSlot slot = fd->face->glyph;
if (!error) {
@@ -664,7 +751,7 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontFallback *p_font_data,
ERR_FAIL_V_MSG(false, "Compiled without MSDFGEN support!");
#endif
} else {
- gl = rasterize_bitmap(fd, rect_range, slot->bitmap, slot->bitmap_top, slot->bitmap_left, Vector2((h + (1 << 9)) >> 10, (v + (1 << 9)) >> 10) / 64.0);
+ gl = rasterize_bitmap(fd, rect_range, slot->bitmap, slot->bitmap_top, slot->bitmap_left, Vector2((h + (1 << 9)) >> 10, (v + (1 << 9)) >> 10) / 64.0, bgra);
}
}
} else {
@@ -684,11 +771,11 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_glyph(FontFallback *p_font_data,
if (FT_Glyph_Stroke(&glyph, stroker, 1) != 0) {
goto cleanup_glyph;
}
- if (FT_Glyph_To_Bitmap(&glyph, p_font_data->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, nullptr, 1) != 0) {
+ if (FT_Glyph_To_Bitmap(&glyph, aa_mode, nullptr, 1) != 0) {
goto cleanup_glyph;
}
glyph_bitmap = (FT_BitmapGlyph)glyph;
- gl = rasterize_bitmap(fd, rect_range, glyph_bitmap->bitmap, glyph_bitmap->top, glyph_bitmap->left, Vector2());
+ gl = rasterize_bitmap(fd, rect_range, glyph_bitmap->bitmap, glyph_bitmap->top, glyph_bitmap->left, Vector2(), bgra);
cleanup_glyph:
FT_Done_Glyph(glyph);
@@ -1014,23 +1101,23 @@ String TextServerFallback::font_get_name(const RID &p_font_rid) const {
return fd->font_name;
}
-void TextServerFallback::font_set_antialiased(const RID &p_font_rid, bool p_antialiased) {
+void TextServerFallback::font_set_antialiasing(RID p_font_rid, TextServer::FontAntialiasing p_antialiasing) {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
ERR_FAIL_COND(!fd);
MutexLock lock(fd->mutex);
- if (fd->antialiased != p_antialiased) {
+ if (fd->antialiasing != p_antialiasing) {
_font_clear_cache(fd);
- fd->antialiased = p_antialiased;
+ fd->antialiasing = p_antialiasing;
}
}
-bool TextServerFallback::font_is_antialiased(const RID &p_font_rid) const {
+TextServer::FontAntialiasing TextServerFallback::font_get_antialiasing(RID p_font_rid) const {
FontFallback *fd = font_owner.get_or_null(p_font_rid);
- ERR_FAIL_COND_V(!fd, false);
+ ERR_FAIL_COND_V(!fd, TextServer::FONT_ANTIALIASING_NONE);
MutexLock lock(fd->mutex);
- return fd->antialiased;
+ return fd->antialiasing;
}
void TextServerFallback::font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) {
@@ -1589,7 +1676,16 @@ Vector2 TextServerFallback::font_get_glyph_advance(const RID &p_font_rid, int64_
Vector2i size = _get_size(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Vector2());
- if (!_ensure_glyph(fd, size, p_glyph)) {
+
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
+ if (!_ensure_glyph(fd, size, p_glyph | mod)) {
return Vector2(); // Invalid or non graphicl glyph, do not display errors.
}
@@ -1632,7 +1728,16 @@ Vector2 TextServerFallback::font_get_glyph_offset(const RID &p_font_rid, const V
Vector2i size = _get_size_outline(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Vector2());
- if (!_ensure_glyph(fd, size, p_glyph)) {
+
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
+ if (!_ensure_glyph(fd, size, p_glyph | mod)) {
return Vector2(); // Invalid or non graphicl glyph, do not display errors.
}
@@ -1668,7 +1773,16 @@ Vector2 TextServerFallback::font_get_glyph_size(const RID &p_font_rid, const Vec
Vector2i size = _get_size_outline(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Vector2());
- if (!_ensure_glyph(fd, size, p_glyph)) {
+
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
+ if (!_ensure_glyph(fd, size, p_glyph | mod)) {
return Vector2(); // Invalid or non graphicl glyph, do not display errors.
}
@@ -1704,7 +1818,16 @@ Rect2 TextServerFallback::font_get_glyph_uv_rect(const RID &p_font_rid, const Ve
Vector2i size = _get_size_outline(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Rect2());
- if (!_ensure_glyph(fd, size, p_glyph)) {
+
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
+ if (!_ensure_glyph(fd, size, p_glyph | mod)) {
return Rect2(); // Invalid or non graphicl glyph, do not display errors.
}
@@ -1735,7 +1858,16 @@ int64_t TextServerFallback::font_get_glyph_texture_idx(const RID &p_font_rid, co
Vector2i size = _get_size_outline(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), -1);
- if (!_ensure_glyph(fd, size, p_glyph)) {
+
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
+ if (!_ensure_glyph(fd, size, p_glyph | mod)) {
return -1; // Invalid or non graphicl glyph, do not display errors.
}
@@ -1766,7 +1898,16 @@ RID TextServerFallback::font_get_glyph_texture_rid(const RID &p_font_rid, const
Vector2i size = _get_size_outline(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), RID());
- if (!_ensure_glyph(fd, size, p_glyph)) {
+
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
+ if (!_ensure_glyph(fd, size, p_glyph | mod)) {
return RID(); // Invalid or non graphicl glyph, do not display errors.
}
@@ -1805,7 +1946,16 @@ Size2 TextServerFallback::font_get_glyph_texture_size(const RID &p_font_rid, con
Vector2i size = _get_size_outline(fd, p_size);
ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Size2());
- if (!_ensure_glyph(fd, size, p_glyph)) {
+
+ int mod = 0;
+ if (fd->antialiasing == FONT_ANTIALIASING_LCD) {
+ TextServer::FontLCDSubpixelLayout layout = (TextServer::FontLCDSubpixelLayout)(int)GLOBAL_GET("gui/theme/lcd_subpixel_layout");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ mod = (layout << 24);
+ }
+ }
+
+ if (!_ensure_glyph(fd, size, p_glyph | mod)) {
return Size2(); // Invalid or non graphicl glyph, do not display errors.
}
@@ -2043,16 +2193,18 @@ void TextServerFallback::font_render_range(const RID &p_font_rid, const Vector2i
if (fd->msdf) {
_ensure_glyph(fd, size, (int32_t)idx);
} else {
- if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
- _ensure_glyph(fd, size, (int32_t)idx | (0 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (1 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (2 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (3 << 27));
- } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
- _ensure_glyph(fd, size, (int32_t)idx | (1 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (0 << 27));
- } else {
- _ensure_glyph(fd, size, (int32_t)idx);
+ for (int aa = 0; aa < ((fd->antialiasing == FONT_ANTIALIASING_LCD) ? FONT_LCD_SUBPIXEL_LAYOUT_MAX : 1); aa++) {
+ if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
+ _ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (2 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (3 << 27) | (aa << 24));
+ } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
+ _ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24));
+ } else {
+ _ensure_glyph(fd, size, (int32_t)idx | (aa << 24));
+ }
}
}
}
@@ -2073,16 +2225,18 @@ void TextServerFallback::font_render_glyph(const RID &p_font_rid, const Vector2i
if (fd->msdf) {
_ensure_glyph(fd, size, (int32_t)idx);
} else {
- if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
- _ensure_glyph(fd, size, (int32_t)idx | (0 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (1 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (2 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (3 << 27));
- } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
- _ensure_glyph(fd, size, (int32_t)idx | (1 << 27));
- _ensure_glyph(fd, size, (int32_t)idx | (0 << 27));
- } else {
- _ensure_glyph(fd, size, (int32_t)idx);
+ for (int aa = 0; aa < ((fd->antialiasing == FONT_ANTIALIASING_LCD) ? FONT_LCD_SUBPIXEL_LAYOUT_MAX : 1); aa++) {
+ if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
+ _ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (2 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (3 << 27) | (aa << 24));
+ } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_HALF) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) {
+ _ensure_glyph(fd, size, (int32_t)idx | (1 << 27) | (aa << 24));
+ _ensure_glyph(fd, size, (int32_t)idx | (0 << 27) | (aa << 24));
+ } else {
+ _ensure_glyph(fd, size, (int32_t)idx | (aa << 24));
+ }
}
}
}
@@ -2098,9 +2252,19 @@ void TextServerFallback::font_draw_glyph(const RID &p_font_rid, const RID &p_can
ERR_FAIL_COND(!_ensure_cache_for_size(fd, size));
int32_t index = p_index & 0xffffff; // Remove subpixel shifts.
+ bool lcd_aa = false;
#ifdef MODULE_FREETYPE_ENABLED
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");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ lcd_aa = true;
+ index = index | (layout << 24);
+ }
+ }
+ // Subpixel X-shift, bits 27, 28
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
int xshift = (int)(Math::floor(4 * (p_pos.x + 0.125)) - 4 * Math::floor(p_pos.x + 0.125));
index = index | (xshift << 27);
@@ -2122,7 +2286,7 @@ void TextServerFallback::font_draw_glyph(const RID &p_font_rid, const RID &p_can
if (gl.texture_idx != -1) {
Color modulate = p_color;
#ifdef MODULE_FREETYPE_ENABLED
- if (fd->cache[size]->face && fd->cache[size]->textures[gl.texture_idx].format == Image::FORMAT_RGBA8) {
+ if (fd->cache[size]->face && (fd->cache[size]->textures[gl.texture_idx].format == Image::FORMAT_RGBA8) && !lcd_aa) {
modulate.r = modulate.g = modulate.b = 1.0;
}
#endif
@@ -2160,7 +2324,11 @@ void TextServerFallback::font_draw_glyph(const RID &p_font_rid, const RID &p_can
}
cpos += gl.rect.position;
Size2 csize = gl.rect.size;
- RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, false, false);
+ if (lcd_aa) {
+ RenderingServer::get_singleton()->canvas_item_add_lcd_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate);
+ } else {
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, false, false);
+ }
}
}
}
@@ -2176,9 +2344,19 @@ void TextServerFallback::font_draw_glyph_outline(const RID &p_font_rid, const RI
ERR_FAIL_COND(!_ensure_cache_for_size(fd, size));
int32_t index = p_index & 0xffffff; // Remove subpixel shifts.
+ bool lcd_aa = false;
#ifdef MODULE_FREETYPE_ENABLED
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");
+ if (layout != FONT_LCD_SUBPIXEL_LAYOUT_NONE) {
+ lcd_aa = true;
+ index = index | (layout << 24);
+ }
+ }
+ // Subpixel X-shift, bits 27, 28
if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_ONE_QUARTER) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x <= SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE)) {
int xshift = (int)(Math::floor(4 * (p_pos.x + 0.125)) - 4 * Math::floor(p_pos.x + 0.125));
index = index | (xshift << 27);
@@ -2238,7 +2416,11 @@ void TextServerFallback::font_draw_glyph_outline(const RID &p_font_rid, const RI
}
cpos += gl.rect.position;
Size2 csize = gl.rect.size;
- RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, false, false);
+ if (lcd_aa) {
+ RenderingServer::get_singleton()->canvas_item_add_lcd_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate);
+ } else {
+ RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), texture, gl.uv_rect, modulate, false, false);
+ }
}
}
}
diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h
index 8e81433a2a..940c57a354 100644
--- a/modules/text_server_fb/text_server_fb.h
+++ b/modules/text_server_fb/text_server_fb.h
@@ -179,7 +179,7 @@ class TextServerFallback : public TextServerExtension {
struct FontFallback {
Mutex mutex;
- bool antialiased = true;
+ TextServer::FontAntialiasing antialiasing = TextServer::FONT_ANTIALIASING_GRAY;
bool mipmaps = false;
bool msdf = false;
int msdf_range = 14;
@@ -225,7 +225,7 @@ class TextServerFallback : public TextServerExtension {
_FORCE_INLINE_ FontGlyph rasterize_msdf(FontFallback *p_font_data, FontForSizeFallback *p_data, int p_pixel_range, int p_rect_margin, FT_Outline *outline, const Vector2 &advance) const;
#endif
#ifdef MODULE_FREETYPE_ENABLED
- _FORCE_INLINE_ FontGlyph rasterize_bitmap(FontForSizeFallback *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance) const;
+ _FORCE_INLINE_ FontGlyph rasterize_bitmap(FontForSizeFallback *p_data, int p_rect_margin, FT_Bitmap bitmap, int yofs, int xofs, const Vector2 &advance, bool p_bgra) const;
#endif
_FORCE_INLINE_ bool _ensure_glyph(FontFallback *p_font_data, const Vector2i &p_size, int32_t p_glyph) const;
_FORCE_INLINE_ bool _ensure_cache_for_size(FontFallback *p_font_data, const Vector2i &p_size) const;
@@ -378,8 +378,8 @@ public:
virtual void font_set_name(const RID &p_font_rid, const String &p_name) override;
virtual String font_get_name(const RID &p_font_rid) const override;
- virtual void font_set_antialiased(const RID &p_font_rid, bool p_antialiased) override;
- virtual bool font_is_antialiased(const RID &p_font_rid) const override;
+ virtual void font_set_antialiasing(RID p_font_rid, TextServer::FontAntialiasing p_antialiasing) override;
+ virtual TextServer::FontAntialiasing font_get_antialiasing(RID p_font_rid) const override;
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;
diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp
index 08ad1ef9f8..16d9bf7b93 100644
--- a/modules/tga/image_loader_tga.cpp
+++ b/modules/tga/image_loader_tga.cpp
@@ -230,7 +230,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, bool p_force_linear, float p_scale) {
+Error ImageLoaderTGA::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t 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/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h
index 9b7cbbac77..d95c5ff30b 100644
--- a/modules/tga/image_loader_tga.h
+++ b/modules/tga/image_loader_tga.h
@@ -73,7 +73,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, bool p_force_linear, float p_scale);
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderTGA();
};
diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp
index 864df765ee..6f61251f9b 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, bool p_force_linear, float p_scale) {
+Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t 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);
@@ -229,7 +229,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool
color.a = *a_channel++;
}
- if (p_force_linear) {
+ if (p_flags & FLAG_FORCE_LINEAR) {
color = color.srgb_to_linear();
}
@@ -260,7 +260,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool
color.a = *a_channel++;
}
- if (p_force_linear) {
+ if (p_flags & FLAG_FORCE_LINEAR) {
color = color.srgb_to_linear();
}
diff --git a/modules/tinyexr/image_loader_tinyexr.h b/modules/tinyexr/image_loader_tinyexr.h
index 0d3de93956..8da2a0d4af 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, bool p_force_linear, float p_scale);
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderTinyEXR();
};
diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp
index 778d562278..705ab508ab 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, bool p_force_linear, float p_scale) {
+Error ImageLoaderWebP::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t 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 9a5dc6cd7c..d868ae3f7f 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, bool p_force_linear, float p_scale);
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderWebP();
};