summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.clang-tidy7
-rw-r--r--core/config/project_settings.cpp4
-rw-r--r--core/debugger/remote_debugger_peer.cpp7
-rw-r--r--core/debugger/script_debugger.cpp2
-rw-r--r--core/input/input.cpp30
-rw-r--r--core/input/input.h2
-rw-r--r--core/input/input_event.cpp109
-rw-r--r--core/input/input_event.h12
-rw-r--r--core/input/input_map.cpp42
-rw-r--r--core/input/input_map.h4
-rw-r--r--core/io/compression.cpp6
-rw-r--r--core/io/dir_access.cpp8
-rw-r--r--core/io/http_client.cpp11
-rw-r--r--core/io/http_client.h1
-rw-r--r--core/io/http_client_tcp.cpp90
-rw-r--r--core/io/http_client_tcp.h11
-rw-r--r--core/io/ip.cpp42
-rw-r--r--core/io/packet_peer.cpp2
-rw-r--r--core/io/resource.h2
-rw-r--r--core/io/stream_peer.cpp4
-rw-r--r--core/math/convex_hull.cpp8
-rw-r--r--core/math/expression.cpp43
-rw-r--r--core/math/rect2.h12
-rw-r--r--core/object/make_virtuals.py4
-rw-r--r--core/object/object.h3
-rw-r--r--core/string/ustring.cpp32
-rw-r--r--core/string/ustring.h3
-rw-r--r--core/templates/vector.h4
-rw-r--r--core/variant/binder_common.h50
-rw-r--r--core/variant/native_ptr.h46
-rw-r--r--core/variant/variant.cpp20
-rw-r--r--core/variant/variant.h4
-rw-r--r--core/variant/variant_call.cpp3
-rw-r--r--core/variant/variant_parser.cpp44
-rw-r--r--doc/classes/AnimationNodeOneShot.xml15
-rw-r--r--doc/classes/Area2D.xml6
-rw-r--r--doc/classes/Area3D.xml6
-rw-r--r--doc/classes/AudioEffectSpectrumAnalyzer.xml4
-rw-r--r--doc/classes/AudioStreamGenerator.xml2
-rw-r--r--doc/classes/AudioStreamGeneratorPlayback.xml2
-rw-r--r--doc/classes/BitMap.xml13
-rw-r--r--doc/classes/BoxMesh.xml2
-rw-r--r--doc/classes/BoxShape3D.xml2
-rw-r--r--doc/classes/ButtonGroup.xml2
-rw-r--r--doc/classes/CapsuleMesh.xml4
-rw-r--r--doc/classes/CapsuleShape3D.xml4
-rw-r--r--doc/classes/CodeEdit.xml3
-rw-r--r--doc/classes/Control.xml6
-rw-r--r--doc/classes/CurveTexture.xml2
-rw-r--r--doc/classes/CurveXYZTexture.xml2
-rw-r--r--doc/classes/CylinderMesh.xml4
-rw-r--r--doc/classes/CylinderShape3D.xml2
-rw-r--r--doc/classes/DisplayServer.xml26
-rw-r--r--doc/classes/EditorInspector.xml4
-rw-r--r--doc/classes/EditorPlugin.xml4
-rw-r--r--doc/classes/Environment.xml7
-rw-r--r--doc/classes/GradientTexture1D.xml2
-rw-r--r--doc/classes/Input.xml7
-rw-r--r--doc/classes/LineEdit.xml6
-rw-r--r--doc/classes/OS.xml6
-rw-r--r--doc/classes/Object.xml2
-rw-r--r--doc/classes/OptionButton.xml3
-rw-r--r--doc/classes/PhysicsBody2D.xml12
-rw-r--r--doc/classes/PhysicsBody3D.xml10
-rw-r--r--doc/classes/PopupMenu.xml7
-rw-r--r--doc/classes/ProjectSettings.xml12
-rw-r--r--doc/classes/RayCast2D.xml8
-rw-r--r--doc/classes/RayCast3D.xml8
-rw-r--r--doc/classes/Rect2.xml5
-rw-r--r--doc/classes/Rect2i.xml7
-rw-r--r--doc/classes/ReflectionProbe.xml1
-rw-r--r--doc/classes/RenderingServer.xml2
-rw-r--r--doc/classes/RichTextLabel.xml15
-rw-r--r--doc/classes/ShapeCast2D.xml8
-rw-r--r--doc/classes/StreamPeerBuffer.xml10
-rw-r--r--doc/classes/String.xml2
-rw-r--r--doc/classes/TabBar.xml62
-rw-r--r--doc/classes/TextEdit.xml6
-rw-r--r--doc/classes/TextLine.xml1
-rw-r--r--doc/classes/TextParagraph.xml1
-rw-r--r--doc/classes/TextServer.xml27
-rw-r--r--doc/classes/TextServerExtension.xml44
-rw-r--r--doc/classes/TileMap.xml2
-rw-r--r--doc/classes/TileSetAtlasSource.xml2
-rw-r--r--doc/classes/Transform3D.xml8
-rw-r--r--doc/classes/Tree.xml16
-rw-r--r--doc/classes/TreeItem.xml6
-rw-r--r--doc/classes/Tween.xml2
-rw-r--r--doc/classes/Viewport.xml12
-rw-r--r--doc/classes/VisualShaderNode.xml14
-rw-r--r--doc/classes/VisualShaderNodeClamp.xml9
-rw-r--r--doc/classes/VisualShaderNodeCompare.xml13
-rw-r--r--doc/classes/VisualShaderNodeDerivativeFunc.xml45
-rw-r--r--doc/classes/VisualShaderNodeFaceForward.xml2
-rw-r--r--doc/classes/VisualShaderNodeMix.xml18
-rw-r--r--doc/classes/VisualShaderNodeMultiplyAdd.xml11
-rw-r--r--doc/classes/VisualShaderNodeScalarDerivativeFunc.xml30
-rw-r--r--doc/classes/VisualShaderNodeSmoothStep.xml18
-rw-r--r--doc/classes/VisualShaderNodeStep.xml18
-rw-r--r--doc/classes/VisualShaderNodeSwitch.xml13
-rw-r--r--doc/classes/VisualShaderNodeVec2Constant.xml16
-rw-r--r--doc/classes/VisualShaderNodeVec2Uniform.xml19
-rw-r--r--doc/classes/VisualShaderNodeVectorBase.xml26
-rw-r--r--doc/classes/VisualShaderNodeVectorCompose.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorDecompose.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorDerivativeFunc.xml30
-rw-r--r--doc/classes/VisualShaderNodeVectorDistance.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorFunc.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorLen.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorOp.xml2
-rw-r--r--doc/classes/XRInterfaceExtension.xml50
-rw-r--r--doc/classes/XRServer.xml18
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp19
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp56
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp2
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h2
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp64
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h118
-rw-r--r--drivers/gles3/texture_loader_gles3.cpp3
-rw-r--r--drivers/unix/ip_unix.cpp2
-rw-r--r--drivers/vulkan/vulkan_context.cpp4
-rw-r--r--drivers/windows/dir_access_windows.cpp11
-rw-r--r--editor/animation_track_editor.cpp4
-rw-r--r--editor/code_editor.cpp37
-rw-r--r--editor/connections_dialog.cpp26
-rw-r--r--editor/create_dialog.cpp12
-rw-r--r--editor/debugger/editor_debugger_tree.cpp2
-rw-r--r--editor/debugger/editor_profiler.cpp3
-rw-r--r--editor/doc_tools.cpp4
-rw-r--r--editor/editor_command_palette.cpp2
-rw-r--r--editor/editor_export.cpp2
-rw-r--r--editor/editor_file_dialog.cpp16
-rw-r--r--editor/editor_file_dialog.h2
-rw-r--r--editor/editor_help.cpp24
-rw-r--r--editor/editor_help.h2
-rw-r--r--editor/editor_inspector.cpp65
-rw-r--r--editor/editor_node.cpp30
-rw-r--r--editor/editor_node.h6
-rw-r--r--editor/editor_plugin.cpp6
-rw-r--r--editor/editor_plugin.h3
-rw-r--r--editor/editor_properties.cpp472
-rw-r--r--editor/editor_properties.h44
-rw-r--r--editor/editor_settings.cpp2
-rw-r--r--editor/editor_settings_dialog.cpp (renamed from editor/settings_config_dialog.cpp)8
-rw-r--r--editor/editor_settings_dialog.h (renamed from editor/settings_config_dialog.h)8
-rw-r--r--editor/editor_themes.cpp74
-rw-r--r--editor/filesystem_dock.cpp4
-rw-r--r--editor/groups_editor.cpp4
-rw-r--r--editor/icons/AudioBusLayout.svg2
-rw-r--r--editor/icons/AudioListener2D.svg2
-rw-r--r--editor/icons/AudioStreamMP3.svg2
-rw-r--r--editor/icons/AudioStreamOGGVorbis.svg2
-rw-r--r--editor/icons/AudioStreamPlayer.svg2
-rw-r--r--editor/icons/AudioStreamPlayer2D.svg2
-rw-r--r--editor/icons/AudioStreamPlayer3D.svg2
-rw-r--r--editor/icons/AudioStreamSample.svg2
-rw-r--r--editor/icons/BoxMesh.svg2
-rw-r--r--editor/icons/BoxShape3D.svg2
-rw-r--r--editor/icons/Breakpoint.svg2
-rw-r--r--editor/icons/BusVuEmpty.svg2
-rw-r--r--editor/icons/BusVuFull.svg2
-rw-r--r--editor/icons/CPUParticles2D.svg2
-rw-r--r--editor/icons/Callable.svg2
-rw-r--r--editor/icons/CanvasGroup.svg2
-rw-r--r--editor/icons/CanvasModulate.svg2
-rw-r--r--editor/icons/CapsuleShape2D.svg2
-rw-r--r--editor/icons/CapsuleShape3D.svg2
-rw-r--r--editor/icons/CircleShape2D.svg2
-rw-r--r--editor/icons/CodeEdit.svg2
-rw-r--r--editor/icons/ColorRect.svg2
-rw-r--r--editor/icons/ConcavePolygonShape2D.svg2
-rw-r--r--editor/icons/ConcavePolygonShape3D.svg2
-rw-r--r--editor/icons/ConvexPolygonShape2D.svg2
-rw-r--r--editor/icons/ConvexPolygonShape3D.svg2
-rw-r--r--editor/icons/CurveClose.svg2
-rw-r--r--editor/icons/CurveCreate.svg2
-rw-r--r--editor/icons/CurveCurve.svg2
-rw-r--r--editor/icons/CurveDelete.svg2
-rw-r--r--editor/icons/CurveEdit.svg2
-rw-r--r--editor/icons/CylinderShape3D.svg2
-rw-r--r--editor/icons/DebugSkipBreakpointsOff.svg2
-rw-r--r--editor/icons/DebugSkipBreakpointsOn.svg2
-rw-r--r--editor/icons/Decal.svg2
-rw-r--r--editor/icons/DirectionalLight2D.svg2
-rw-r--r--editor/icons/EditorBoneHandle.svg2
-rw-r--r--editor/icons/EditorControlAnchor.svg2
-rw-r--r--editor/icons/EditorCurveHandle.svg2
-rw-r--r--editor/icons/EditorPathSharpHandle.svg2
-rw-r--r--editor/icons/EditorPathSmoothHandle.svg2
-rw-r--r--editor/icons/EditorPositionPrevious.svg2
-rw-r--r--editor/icons/EditorPositionUnselected.svg2
-rw-r--r--editor/icons/Error.svg2
-rw-r--r--editor/icons/ErrorWarning.svg2
-rw-r--r--editor/icons/FileBroken.svg2
-rw-r--r--editor/icons/FileBrokenBigThumb.svg2
-rw-r--r--editor/icons/FileDead.svg2
-rw-r--r--editor/icons/FileDeadBigThumb.svg2
-rw-r--r--editor/icons/FileDeadMediumThumb.svg2
-rw-r--r--editor/icons/GizmoCPUParticles3D.svg2
-rw-r--r--editor/icons/GizmoDirectionalLight.svg2
-rw-r--r--editor/icons/GizmoLight.svg2
-rw-r--r--editor/icons/GizmoSpotLight.svg2
-rw-r--r--editor/icons/GraphEdit.svg2
-rw-r--r--editor/icons/GraphNode.svg2
-rw-r--r--editor/icons/GuiDropdown.svg2
-rw-r--r--editor/icons/GuiScrollGrabber.svg2
-rw-r--r--editor/icons/GuiScrollGrabberHl.svg2
-rw-r--r--editor/icons/GuiScrollGrabberPressed.svg2
-rw-r--r--editor/icons/GuiSliderGrabber.svg2
-rw-r--r--editor/icons/GuiSliderGrabberHl.svg2
-rw-r--r--editor/icons/GuiToggleOn.svg2
-rw-r--r--editor/icons/GuiToggleOnMirrored.svg2
-rw-r--r--editor/icons/GuiTreeArrowDown.svg2
-rw-r--r--editor/icons/GuiTreeArrowLeft.svg2
-rw-r--r--editor/icons/GuiTreeArrowRight.svg2
-rw-r--r--editor/icons/GuiTreeUpdown.svg2
-rw-r--r--editor/icons/HFlowContainer.svg2
-rw-r--r--editor/icons/Heart.svg2
-rw-r--r--editor/icons/HeightMapShape3D.svg2
-rw-r--r--editor/icons/Help.svg2
-rw-r--r--editor/icons/ImmediateMesh.svg2
-rw-r--r--editor/icons/ImportCheck.svg2
-rw-r--r--editor/icons/ImportFail.svg2
-rw-r--r--editor/icons/KeyBlendShape.svg45
-rw-r--r--editor/icons/KeyInvalid.svg2
-rw-r--r--editor/icons/KeyTrackBlendShape.svg46
-rw-r--r--editor/icons/KeyTrackPosition.svg48
-rw-r--r--editor/icons/KeyTrackRotation.svg48
-rw-r--r--editor/icons/KeyTrackScale.svg48
-rw-r--r--editor/icons/KeyXPosition.svg44
-rw-r--r--editor/icons/KeyXRotation.svg45
-rw-r--r--editor/icons/KeyXScale.svg45
-rw-r--r--editor/icons/MaterialPreviewCube.svg2
-rw-r--r--editor/icons/MaterialPreviewCubeOff.svg2
-rw-r--r--editor/icons/MaterialPreviewLight1Off.svg2
-rw-r--r--editor/icons/MaterialPreviewSphereOff.svg2
-rw-r--r--editor/icons/NavigationAgent2D.svg2
-rw-r--r--editor/icons/NavigationAgent3D.svg2
-rw-r--r--editor/icons/NavigationObstacle2D.svg2
-rw-r--r--editor/icons/NavigationObstacle3D.svg2
-rw-r--r--editor/icons/NodeDisabled.svg2
-rw-r--r--editor/icons/OccluderPolygon2D.svg2
-rw-r--r--editor/icons/OverbrightIndicator.svg2
-rw-r--r--editor/icons/PackedByteArray.svg2
-rw-r--r--editor/icons/PackedColorArray.svg2
-rw-r--r--editor/icons/PageFirst.svg48
-rw-r--r--editor/icons/PageLast.svg48
-rw-r--r--editor/icons/PageNext.svg43
-rw-r--r--editor/icons/PagePrevious.svg43
-rw-r--r--editor/icons/ParallaxBackground.svg2
-rw-r--r--editor/icons/ParallaxLayer.svg2
-rw-r--r--editor/icons/PlayOverlay.svg2
-rw-r--r--editor/icons/RectangleShape2D.svg2
-rw-r--r--editor/icons/ReverseGradient.svg2
-rw-r--r--editor/icons/Ruler.svg2
-rw-r--r--editor/icons/Script.svg2
-rw-r--r--editor/icons/ScriptCreate.svg2
-rw-r--r--editor/icons/ScriptExtend.svg2
-rw-r--r--editor/icons/ScriptRemove.svg2
-rw-r--r--editor/icons/SegmentShape2D.svg2
-rw-r--r--editor/icons/SeparationRayShape2D.svg2
-rw-r--r--editor/icons/ShapeCast2D.svg2
-rw-r--r--editor/icons/SphereShape3D.svg2
-rw-r--r--editor/icons/StaticBody2D.svg2
-rw-r--r--editor/icons/StatusError.svg2
-rw-r--r--editor/icons/StatusSuccess.svg2
-rw-r--r--editor/icons/TerrainMatchCorners.svg2
-rw-r--r--editor/icons/TerrainMatchCornersAndSides.svg2
-rw-r--r--editor/icons/TerrainMatchSides.svg2
-rw-r--r--editor/icons/TextEdit.svg2
-rw-r--r--editor/icons/Texture3D.svg2
-rw-r--r--editor/icons/TimelineIndicator.svg2
-rw-r--r--editor/icons/ToolTriangle.svg2
-rw-r--r--editor/icons/TransitionEndAutoBig.svg2
-rw-r--r--editor/icons/TransitionEndBig.svg2
-rw-r--r--editor/icons/TransitionImmediateAutoBig.svg2
-rw-r--r--editor/icons/TransitionImmediateBig.svg2
-rw-r--r--editor/icons/TransitionSyncAutoBig.svg2
-rw-r--r--editor/icons/TransitionSyncBig.svg2
-rw-r--r--editor/icons/VFlowContainer.svg2
-rw-r--r--editor/icons/VisualShaderGraphTextureUniform.svg2
-rw-r--r--editor/icons/VisualShaderNodeColorConstant.svg2
-rw-r--r--editor/icons/VisualShaderNodeColorOp.svg2
-rw-r--r--editor/icons/VisualShaderNodeColorUniform.svg2
-rw-r--r--editor/icons/VisualShaderNodeCurveTexture.svg2
-rw-r--r--editor/icons/VisualShaderNodeCurveXYZTexture.svg2
-rw-r--r--editor/icons/VisualShaderNodeExpression.svg2
-rw-r--r--editor/icons/VisualShaderNodeInput.svg2
-rw-r--r--editor/icons/VisualShaderNodeTexture2DArrayUniform.svg2
-rw-r--r--editor/icons/VisualShaderNodeTexture3DUniform.svg2
-rw-r--r--editor/icons/VisualShaderNodeTextureUniform.svg2
-rw-r--r--editor/icons/VisualShaderNodeTextureUniformTriplanar.svg2
-rw-r--r--editor/icons/VisualShaderNodeTransformCompose.svg2
-rw-r--r--editor/icons/VisualShaderNodeTransformDecompose.svg2
-rw-r--r--editor/icons/VisualShaderNodeTransformVecMult.svg2
-rw-r--r--editor/icons/VisualShaderNodeVec3Uniform.svg2
-rw-r--r--editor/icons/VisualShaderNodeVectorCompose.svg2
-rw-r--r--editor/icons/VisualShaderNodeVectorDecompose.svg2
-rw-r--r--editor/icons/VisualShaderNodeVectorDistance.svg2
-rw-r--r--editor/icons/VisualShaderNodeVectorFunc.svg2
-rw-r--r--editor/icons/VisualShaderNodeVectorLen.svg2
-rw-r--r--editor/icons/WorldBoundaryShape2D.svg2
-rw-r--r--editor/import/collada.cpp3
-rw-r--r--editor/import/resource_importer_layered_texture.cpp2
-rw-r--r--editor/import/resource_importer_scene.cpp5
-rw-r--r--editor/import/resource_importer_texture.cpp2
-rw-r--r--editor/import_dock.cpp2
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp9
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.cpp2
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp3
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.h2
-rw-r--r--editor/plugins/animation_state_machine_editor.cpp2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp73
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp6
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp25
-rw-r--r--editor/plugins/path_3d_editor_plugin.cpp35
-rw-r--r--editor/plugins/path_3d_editor_plugin.h2
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp4
-rw-r--r--editor/plugins/script_editor_plugin.cpp26
-rw-r--r--editor/plugins/script_editor_plugin.h2
-rw-r--r--editor/plugins/script_text_editor.cpp31
-rw-r--r--editor/plugins/script_text_editor.h5
-rw-r--r--editor/plugins/shader_editor_plugin.cpp22
-rw-r--r--editor/plugins/shader_editor_plugin.h2
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp2
-rw-r--r--editor/plugins/theme_editor_plugin.cpp8
-rw-r--r--editor/plugins/tiles/atlas_merging_dialog.cpp2
-rw-r--r--editor/plugins/tiles/tile_atlas_view.cpp6
-rw-r--r--editor/plugins/tiles/tile_data_editors.cpp75
-rw-r--r--editor/plugins/tiles/tile_map_editor.cpp98
-rw-r--r--editor/plugins/tiles/tile_map_editor.h2
-rw-r--r--editor/plugins/tiles/tile_set_atlas_source_editor.cpp12
-rw-r--r--editor/plugins/tiles/tile_set_editor.cpp54
-rw-r--r--editor/plugins/tiles/tile_set_editor.h2
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.cpp101
-rw-r--r--editor/plugins/tiles/tiles_editor_plugin.h23
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp1179
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h29
-rw-r--r--editor/plugins/voxel_gi_editor_plugin.cpp4
-rw-r--r--editor/project_settings_editor.cpp94
-rw-r--r--editor/project_settings_editor.h6
-rw-r--r--editor/property_selector.cpp2
-rw-r--r--editor/quick_open.cpp2
-rw-r--r--editor/rename_dialog.cpp6
-rw-r--r--editor/scene_tree_dock.cpp8
-rw-r--r--editor/scene_tree_dock.h1
-rw-r--r--editor/scene_tree_editor.cpp2
-rw-r--r--editor/script_create_dialog.cpp8
-rw-r--r--gles3_builders.py2
-rw-r--r--main/main.cpp10
-rw-r--r--misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj2
-rwxr-xr-xmisc/scripts/black_format.sh16
-rwxr-xr-xmisc/scripts/clang_format.sh51
-rwxr-xr-xmisc/scripts/clang_tidy.sh31
-rwxr-xr-xmisc/scripts/file_format.sh7
-rw-r--r--modules/bullet/shape_bullet.h10
-rw-r--r--modules/csg/csg_shape.cpp8
-rw-r--r--modules/csg/csg_shape.h2
-rw-r--r--modules/csg/doc_classes/CSGBox3D.xml2
-rw-r--r--modules/csg/doc_classes/CSGCylinder3D.xml4
-rw-r--r--modules/csg/doc_classes/CSGTorus3D.xml4
-rw-r--r--modules/fbx/fbx_parser/FBXAnimation.cpp2
-rw-r--r--modules/fbx/fbx_parser/FBXDeformer.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXParser.cpp2
-rw-r--r--modules/fbx/fbx_parser/FBXProperties.cpp3
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp2
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp66
-rw-r--r--modules/gdscript/language_server/gdscript_workspace.cpp4
-rw-r--r--modules/glslang/glslang_resource_limits.h18
-rw-r--r--modules/gltf/gltf_document.cpp1
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp2
-rw-r--r--modules/mobile_vr/mobile_vr_interface.cpp2
-rw-r--r--modules/mobile_vr/mobile_vr_interface.h2
-rw-r--r--modules/mono/build_scripts/mono_reg_utils.py8
-rw-r--r--modules/mono/csharp_script.h2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs4
-rw-r--r--modules/navigation/navigation_mesh_generator.cpp23
-rw-r--r--modules/navigation/navigation_mesh_generator.h2
-rw-r--r--modules/ogg/ogg_packet_sequence.h2
-rw-r--r--modules/text_server_adv/SCsub1
-rw-r--r--modules/text_server_adv/text_server_adv.cpp492
-rw-r--r--modules/text_server_adv/text_server_adv.h29
-rw-r--r--modules/text_server_fb/text_server_fb.cpp294
-rw-r--r--modules/text_server_fb/text_server_fb.h33
-rw-r--r--modules/theora/video_stream_theora.cpp1
-rw-r--r--modules/visual_script/editor/visual_script_editor.h18
-rw-r--r--modules/visual_script/editor/visual_script_property_selector.cpp2
-rw-r--r--modules/visual_script/editor/visual_script_property_selector.h8
-rw-r--r--modules/visual_script/icons/VisualScript.svg2
-rw-r--r--modules/visual_script/icons/VisualScriptInternal.svg2
-rw-r--r--modules/visual_script/visual_script_expression.cpp43
-rw-r--r--modules/visual_script/visual_script_func_nodes.cpp2
-rw-r--r--modules/webrtc/doc_classes/WebRTCPeerConnection.xml2
-rw-r--r--modules/webrtc/webrtc_peer_connection.cpp2
-rw-r--r--modules/webxr/webxr_interface_js.cpp2
-rw-r--r--modules/webxr/webxr_interface_js.h2
-rw-r--r--platform/android/SCsub1
-rw-r--r--platform/android/display_server_android.cpp18
-rw-r--r--platform/android/display_server_android.h3
-rw-r--r--platform/android/export/export_plugin.cpp14
-rw-r--r--platform/android/export/gradle_export_util.cpp5
-rw-r--r--platform/android/java/app/AndroidManifest.xml11
-rw-r--r--platform/android/plugin/godot_plugin_jni.cpp2
-rw-r--r--platform/iphone/display_server_iphone.h2
-rw-r--r--platform/iphone/display_server_iphone.mm18
-rw-r--r--platform/iphone/export/export_plugin.cpp33
-rw-r--r--platform/javascript/http_client_javascript.cpp5
-rw-r--r--platform/javascript/js/engine/config.js41
-rw-r--r--platform/javascript/js/libs/library_godot_input.js2
-rw-r--r--platform/linuxbsd/display_server_x11.cpp46
-rw-r--r--platform/linuxbsd/display_server_x11.h6
-rw-r--r--platform/linuxbsd/gl_manager_x11.cpp44
-rw-r--r--platform/linuxbsd/os_linuxbsd.cpp8
-rw-r--r--platform/osx/display_server_osx.h4
-rw-r--r--platform/osx/display_server_osx.mm26
-rw-r--r--platform/osx/export/export_plugin.cpp18
-rw-r--r--platform/windows/display_server_windows.cpp44
-rw-r--r--platform/windows/display_server_windows.h2
-rw-r--r--platform/windows/export/export_plugin.cpp48
-rw-r--r--platform/windows/export/export_plugin.h1
-rw-r--r--platform/windows/godot_windows.cpp7
-rw-r--r--platform/windows/os_windows.cpp38
-rw-r--r--scene/2d/animated_sprite_2d.cpp2
-rw-r--r--scene/2d/collision_object_2d.cpp4
-rw-r--r--scene/2d/collision_object_2d.h2
-rw-r--r--scene/2d/line_2d.cpp2
-rw-r--r--scene/2d/navigation_obstacle_2d.cpp7
-rw-r--r--scene/2d/navigation_region_2d.cpp2
-rw-r--r--scene/2d/physics_body_2d.cpp18
-rw-r--r--scene/2d/physics_body_2d.h4
-rw-r--r--scene/2d/ray_cast_2d.cpp20
-rw-r--r--scene/2d/ray_cast_2d.h6
-rw-r--r--scene/2d/shape_cast_2d.cpp20
-rw-r--r--scene/2d/shape_cast_2d.h6
-rw-r--r--scene/2d/tile_map.cpp17
-rw-r--r--scene/3d/collision_object_3d.cpp4
-rw-r--r--scene/3d/collision_object_3d.h2
-rw-r--r--scene/3d/navigation_obstacle_3d.cpp7
-rw-r--r--scene/3d/node_3d.cpp3
-rw-r--r--scene/3d/physics_body_3d.cpp18
-rw-r--r--scene/3d/physics_body_3d.h4
-rw-r--r--scene/3d/ray_cast_3d.cpp20
-rw-r--r--scene/3d/ray_cast_3d.h6
-rw-r--r--scene/3d/sprite_3d.cpp3
-rw-r--r--scene/animation/animation_blend_space_1d.cpp4
-rw-r--r--scene/animation/animation_blend_space_2d.cpp6
-rw-r--r--scene/animation/animation_blend_tree.cpp4
-rw-r--r--scene/animation/animation_tree.cpp32
-rw-r--r--scene/animation/animation_tree.h16
-rw-r--r--scene/animation/tween.cpp13
-rw-r--r--scene/debugger/scene_debugger.h1
-rw-r--r--scene/gui/base_button.cpp13
-rw-r--r--scene/gui/button.cpp5
-rw-r--r--scene/gui/code_edit.cpp45
-rw-r--r--scene/gui/control.cpp14
-rw-r--r--scene/gui/control.h2
-rw-r--r--scene/gui/file_dialog.cpp15
-rw-r--r--scene/gui/file_dialog.h2
-rw-r--r--scene/gui/graph_edit.cpp6
-rw-r--r--scene/gui/label.cpp40
-rw-r--r--scene/gui/label.h1
-rw-r--r--scene/gui/line_edit.cpp17
-rw-r--r--scene/gui/line_edit.h4
-rw-r--r--scene/gui/menu_button.cpp8
-rw-r--r--scene/gui/option_button.cpp57
-rw-r--r--scene/gui/popup_menu.cpp50
-rw-r--r--scene/gui/rich_text_label.cpp141
-rw-r--r--scene/gui/rich_text_label.h15
-rw-r--r--scene/gui/tab_bar.cpp552
-rw-r--r--scene/gui/tab_bar.h16
-rw-r--r--scene/gui/text_edit.cpp97
-rw-r--r--scene/gui/text_edit.h9
-rw-r--r--scene/gui/texture_button.cpp5
-rw-r--r--scene/gui/tree.cpp20
-rw-r--r--scene/gui/tree.h27
-rw-r--r--scene/main/http_request.cpp56
-rw-r--r--scene/main/scene_tree.cpp2
-rw-r--r--scene/main/viewport.cpp81
-rw-r--r--scene/main/viewport.h8
-rw-r--r--scene/register_scene_types.cpp8
-rw-r--r--scene/resources/animation.cpp24
-rw-r--r--scene/resources/bit_map.cpp2
-rw-r--r--scene/resources/box_shape_3d.cpp2
-rw-r--r--scene/resources/capsule_shape_3d.h4
-rw-r--r--scene/resources/curve.cpp14
-rw-r--r--scene/resources/cylinder_shape_3d.h2
-rw-r--r--scene/resources/default_theme/default_theme.cpp8
-rw-r--r--scene/resources/environment.cpp37
-rw-r--r--scene/resources/environment.h6
-rw-r--r--scene/resources/font.cpp3
-rw-r--r--scene/resources/mesh.cpp4
-rw-r--r--scene/resources/mesh_library.cpp33
-rw-r--r--scene/resources/primitive_meshes.h10
-rw-r--r--scene/resources/skeleton_modification_3d.cpp3
-rw-r--r--scene/resources/sky_material.cpp2
-rw-r--r--scene/resources/text_line.cpp6
-rw-r--r--scene/resources/text_line.h2
-rw-r--r--scene/resources/text_paragraph.cpp6
-rw-r--r--scene/resources/text_paragraph.h2
-rw-r--r--scene/resources/texture.cpp4
-rw-r--r--scene/resources/texture.h6
-rw-r--r--scene/resources/tile_set.cpp21
-rw-r--r--scene/resources/tile_set.h2
-rw-r--r--scene/resources/visual_shader.cpp563
-rw-r--r--scene/resources/visual_shader.h8
-rw-r--r--scene/resources/visual_shader_nodes.cpp1310
-rw-r--r--scene/resources/visual_shader_nodes.h257
-rw-r--r--scene/resources/world_2d.cpp4
-rw-r--r--servers/audio/effects/audio_effect_record.cpp2
-rw-r--r--servers/audio_server.cpp6
-rw-r--r--servers/display_server.cpp11
-rw-r--r--servers/display_server.h9
-rw-r--r--servers/physics_3d/godot_soft_body_3d.cpp2
-rw-r--r--servers/register_server_types.cpp4
-rw-r--r--servers/rendering/rasterizer_dummy.h2
-rw-r--r--servers/rendering/renderer_rd/effects_rd.cpp42
-rw-r--r--servers/rendering/renderer_rd/effects_rd.h6
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp4
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp6
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp4
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_environment_rd.h4
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp23
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h2
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp1
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/shaders/tonemap.glsl10
-rw-r--r--servers/rendering/renderer_scene.h2
-rw-r--r--servers/rendering/renderer_scene_cull.h2
-rw-r--r--servers/rendering/renderer_scene_render.h2
-rw-r--r--servers/rendering/renderer_viewport.cpp49
-rw-r--r--servers/rendering/rendering_server_default.cpp6
-rw-r--r--servers/rendering/rendering_server_default.h2
-rw-r--r--servers/rendering/shader_compiler.cpp9
-rw-r--r--servers/rendering/shader_language.cpp140
-rw-r--r--servers/rendering/shader_language.h5
-rw-r--r--servers/rendering_server.cpp2
-rw-r--r--servers/rendering_server.h2
-rw-r--r--servers/text/text_server_extension.cpp60
-rw-r--r--servers/text/text_server_extension.h25
-rw-r--r--servers/text_server.cpp6
-rw-r--r--servers/text_server.h21
-rw-r--r--servers/xr/xr_interface.cpp3
-rw-r--r--servers/xr/xr_interface.h9
-rw-r--r--servers/xr/xr_interface_extension.cpp36
-rw-r--r--servers/xr/xr_interface_extension.h11
-rw-r--r--servers/xr_server.cpp50
-rw-r--r--servers/xr_server.h18
-rw-r--r--tests/core/math/test_rect2.h6
-rw-r--r--tests/core/object/test_method_bind.h16
-rw-r--r--tests/core/string/test_string.h5
-rw-r--r--tests/scene/test_code_edit.h46
-rw-r--r--thirdparty/README.md12
-rw-r--r--thirdparty/harfbuzz/src/hb-aat-layout-common.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-algs.hh32
-rw-r--r--thirdparty/harfbuzz/src/hb-array.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-bimap.hh14
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer.cc185
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer.h92
-rw-r--r--thirdparty/harfbuzz/src/hb-buffer.hh165
-rw-r--r--thirdparty/harfbuzz/src/hb-cff-interp-common.hh14
-rw-r--r--thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh9
-rw-r--r--thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh14
-rw-r--r--thirdparty/harfbuzz/src/hb-common.cc78
-rw-r--r--thirdparty/harfbuzz/src/hb-coretext.cc9
-rw-r--r--thirdparty/harfbuzz/src/hb-directwrite.cc3
-rw-r--r--thirdparty/harfbuzz/src/hb-draw.h2
-rw-r--r--thirdparty/harfbuzz/src/hb-face.cc23
-rw-r--r--thirdparty/harfbuzz/src/hb-font.cc114
-rw-r--r--thirdparty/harfbuzz/src/hb-font.h8
-rw-r--r--thirdparty/harfbuzz/src/hb-font.hh3
-rw-r--r--thirdparty/harfbuzz/src/hb-graphite2.cc3
-rw-r--r--thirdparty/harfbuzz/src/hb-iter.hh6
-rw-r--r--thirdparty/harfbuzz/src/hb-kern.hh9
-rw-r--r--thirdparty/harfbuzz/src/hb-machinery.hh6
-rw-r--r--thirdparty/harfbuzz/src/hb-map.hh71
-rw-r--r--thirdparty/harfbuzz/src/hb-meta.hh39
-rw-r--r--thirdparty/harfbuzz/src/hb-ms-feature-ranges.cc177
-rw-r--r--thirdparty/harfbuzz/src/hb-ms-feature-ranges.hh145
-rw-r--r--thirdparty/harfbuzz/src/hb-object.hh6
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-cff-common.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-cff1-table.hh38
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-cff2-table.hh63
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-cmap-table.hh13
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh24
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh14
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-color-colrv1-closure.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-color-sbix-table.hh9
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-color-svg-table.hh8
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-color.cc12
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-glyf-table.hh17
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh20
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-common.hh21
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh17
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh172
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh22
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh304
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout.cc8
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout.hh5
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-meta-table.hh8
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-metrics.cc45
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-name-table.hh13
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh7
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-post-table.hh17
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh32
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc21
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc4
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.cc2
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-thai.cc2
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc2
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc19
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc7
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-shape.cc29
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-tag-table.hh97
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh2
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh10
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh7
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var.cc3
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-var.h2
-rw-r--r--thirdparty/harfbuzz/src/hb-repacker.hh38
-rw-r--r--thirdparty/harfbuzz/src/hb-serialize.hh14
-rw-r--r--thirdparty/harfbuzz/src/hb-style.cc15
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-cff-common.hh102
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-cff1.cc42
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-cff2.cc43
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-plan.cc26
-rw-r--r--thirdparty/harfbuzz/src/hb-uniscribe.cc3
-rw-r--r--thirdparty/harfbuzz/src/hb-vector.hh200
-rw-r--r--thirdparty/harfbuzz/src/hb-version.h6
-rw-r--r--thirdparty/libwebp/AUTHORS1
-rw-r--r--thirdparty/libwebp/src/dec/vp8_dec.c2
-rw-r--r--thirdparty/libwebp/src/dec/vp8i_dec.h2
-rw-r--r--thirdparty/libwebp/src/dec/vp8l_dec.c2
-rw-r--r--thirdparty/libwebp/src/demux/anim_decode.c40
-rw-r--r--thirdparty/libwebp/src/demux/demux.c2
-rw-r--r--thirdparty/libwebp/src/dsp/dsp.h7
-rw-r--r--thirdparty/libwebp/src/dsp/enc_neon.c2
-rw-r--r--thirdparty/libwebp/src/dsp/lossless.c58
-rw-r--r--thirdparty/libwebp/src/dsp/lossless.h45
-rw-r--r--thirdparty/libwebp/src/dsp/lossless_common.h2
-rw-r--r--thirdparty/libwebp/src/dsp/lossless_enc.c2
-rw-r--r--thirdparty/libwebp/src/dsp/lossless_mips_dsp_r2.c37
-rw-r--r--thirdparty/libwebp/src/dsp/lossless_neon.c20
-rw-r--r--thirdparty/libwebp/src/dsp/lossless_sse2.c41
-rw-r--r--thirdparty/libwebp/src/dsp/msa_macro.h5
-rw-r--r--thirdparty/libwebp/src/dsp/neon.h7
-rw-r--r--thirdparty/libwebp/src/dsp/yuv.h2
-rw-r--r--thirdparty/libwebp/src/enc/frame_enc.c9
-rw-r--r--thirdparty/libwebp/src/enc/predictor_enc.c2
-rw-r--r--thirdparty/libwebp/src/enc/quant_enc.c58
-rw-r--r--thirdparty/libwebp/src/enc/vp8i_enc.h2
-rw-r--r--thirdparty/libwebp/src/mux/muxi.h2
-rw-r--r--thirdparty/libwebp/src/utils/huffman_encode_utils.c2
-rw-r--r--thirdparty/libwebp/src/utils/quant_levels_dec_utils.c2
-rw-r--r--thirdparty/libwebp/src/utils/utils.c2
-rw-r--r--thirdparty/libwebp/src/webp/decode.h2
-rw-r--r--thirdparty/thorvg/AUTHORS2
-rw-r--r--thirdparty/thorvg/inc/config.h2
-rw-r--r--thirdparty/thorvg/patches/thorvg-pr1159-mingw-fix.patch73
-rw-r--r--thirdparty/thorvg/patches/thorvg-pr1166-vs2017-minmax.patch49
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp4
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp36
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h6
-rw-r--r--thirdparty/thorvg/src/lib/tvgMath.h2
-rw-r--r--thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp5
-rw-r--r--thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp5
-rw-r--r--thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h2
-rw-r--r--thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp9
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp224
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp6
-rwxr-xr-xthirdparty/thorvg/update-thorvg.sh2
673 files changed, 9310 insertions, 6027 deletions
diff --git a/.clang-tidy b/.clang-tidy
index 59d0facb96..b623aef133 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,10 +1,9 @@
---
-Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-nullptr,readability-braces-around-statements'
+Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-nullptr,readability-braces-around-statements'
WarningsAsErrors: ''
-HeaderFilterRegex: '.*'
+HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
-FormatStyle: none
-CheckOptions:
+FormatStyle: none
CheckOptions:
- key: cert-dcl16-c.NewSuffixes
value: 'L;LL;LU;LLU'
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 45776c03e4..b5f1015ff5 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -1235,8 +1235,8 @@ ProjectSettings::ProjectSettings() {
// Keep the enum values in sync with the `DisplayServer::VSyncMode` enum.
custom_prop_info["display/window/vsync/vsync_mode"] = PropertyInfo(Variant::INT, "display/window/vsync/vsync_mode", PROPERTY_HINT_ENUM, "Disabled,Enabled,Adaptive,Mailbox");
custom_prop_info["rendering/driver/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/driver/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
- GLOBAL_DEF("physics/2d/run_on_thread", false);
- GLOBAL_DEF("physics/3d/run_on_thread", false);
+ GLOBAL_DEF("physics/2d/run_on_separate_thread", false);
+ GLOBAL_DEF("physics/3d/run_on_separate_thread", false);
GLOBAL_DEF("debug/settings/profiler/max_functions", 16384);
custom_prop_info["debug/settings/profiler/max_functions"] = PropertyInfo(Variant::INT, "debug/settings/profiler/max_functions", PROPERTY_HINT_RANGE, "128,65535,1");
diff --git a/core/debugger/remote_debugger_peer.cpp b/core/debugger/remote_debugger_peer.cpp
index a45430465f..8c6e95e276 100644
--- a/core/debugger/remote_debugger_peer.cpp
+++ b/core/debugger/remote_debugger_peer.cpp
@@ -68,8 +68,8 @@ void RemoteDebuggerPeerTCP::close() {
running = false;
thread.wait_to_finish();
tcp_client->disconnect_from_host();
- out_buf.resize(0);
- in_buf.resize(0);
+ out_buf.clear();
+ in_buf.clear();
}
RemoteDebuggerPeerTCP::RemoteDebuggerPeerTCP(Ref<StreamPeerTCP> p_tcp) {
@@ -190,7 +190,8 @@ Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_po
}
void RemoteDebuggerPeerTCP::_thread_func(void *p_ud) {
- const uint64_t min_tick = 100;
+ // Update in time for 144hz monitors
+ const uint64_t min_tick = 6900;
RemoteDebuggerPeerTCP *peer = (RemoteDebuggerPeerTCP *)p_ud;
while (peer->running && peer->is_peer_connected()) {
uint64_t ticks_usec = OS::get_singleton()->get_ticks_usec();
diff --git a/core/debugger/script_debugger.cpp b/core/debugger/script_debugger.cpp
index 36723e5568..4dd93249ef 100644
--- a/core/debugger/script_debugger.cpp
+++ b/core/debugger/script_debugger.cpp
@@ -104,7 +104,7 @@ void ScriptDebugger::send_error(const String &p_func, const String &p_file, int
// Store stack info, this is ugly, but allows us to separate EngineDebugger and ScriptDebugger. There might be a better way.
error_stack_info.append_array(p_stack_info);
EngineDebugger::get_singleton()->send_error(p_func, p_file, p_line, p_err, p_descr, p_editor_notify, p_type);
- error_stack_info.resize(0);
+ error_stack_info.clear();
}
Vector<ScriptLanguage::StackInfo> ScriptDebugger::get_error_stack_info() const {
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 7106bd0745..d36d0f4da0 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -190,32 +190,37 @@ void Input::VelocityTrack::update(const Vector2 &p_delta_p) {
float delta_t = tdiff / 1000000.0;
last_tick = tick;
+ if (delta_t > max_ref_frame) {
+ // First movement in a long time, reset and start again.
+ velocity = Vector2();
+ accum = p_delta_p;
+ accum_t = 0;
+ return;
+ }
+
accum += p_delta_p;
accum_t += delta_t;
- if (accum_t > max_ref_frame * 10) {
- accum_t = max_ref_frame * 10;
+ if (accum_t < min_ref_frame) {
+ // Not enough time has passed to calculate speed precisely.
+ return;
}
- while (accum_t >= min_ref_frame) {
- float slice_t = min_ref_frame / accum_t;
- Vector2 slice = accum * slice_t;
- accum = accum - slice;
- accum_t -= min_ref_frame;
-
- velocity = (slice / min_ref_frame).lerp(velocity, min_ref_frame / max_ref_frame);
- }
+ velocity = accum / accum_t;
+ accum = Vector2();
+ accum_t = 0;
}
void Input::VelocityTrack::reset() {
last_tick = OS::get_singleton()->get_ticks_usec();
velocity = Vector2();
+ accum = Vector2();
accum_t = 0;
}
Input::VelocityTrack::VelocityTrack() {
min_ref_frame = 0.1;
- max_ref_frame = 0.3;
+ max_ref_frame = 3.0;
reset();
}
@@ -719,7 +724,8 @@ Point2 Input::get_mouse_position() const {
return mouse_pos;
}
-Point2 Input::get_last_mouse_velocity() const {
+Point2 Input::get_last_mouse_velocity() {
+ mouse_velocity_track.update(Vector2());
return mouse_velocity_track.velocity;
}
diff --git a/core/input/input.h b/core/input/input.h
index 80f260f30e..ab2cd377f4 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -270,7 +270,7 @@ public:
Vector3 get_gyroscope() const;
Point2 get_mouse_position() const;
- Vector2 get_last_mouse_velocity() const;
+ Vector2 get_last_mouse_velocity();
MouseButton get_mouse_button_mask() const;
void warp_mouse_position(const Vector2 &p_to);
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index c608076a21..ab0f36132f 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -86,7 +86,7 @@ Ref<InputEvent> InputEvent::xformed_by(const Transform2D &p_xform, const Vector2
return Ref<InputEvent>((InputEvent *)this);
}
-bool InputEvent::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
+bool InputEvent::action_match(const Ref<InputEvent> &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const {
return false;
}
@@ -412,35 +412,32 @@ Ref<InputEventKey> InputEventKey::create_reference(Key p_keycode) {
return ie;
}
-bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
+bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const {
Ref<InputEventKey> key = p_event;
if (key.is_null()) {
return false;
}
- bool match = false;
- if (get_keycode() == Key::NONE) {
- Key code = get_physical_keycode_with_modifiers();
- Key event_code = key->get_physical_keycode_with_modifiers();
-
- match = get_physical_keycode() == key->get_physical_keycode() && (!key->is_pressed() || (code & event_code) == code);
+ bool match;
+ if (keycode != Key::NONE) {
+ match = keycode == key->keycode;
} else {
- Key code = get_keycode_with_modifiers();
- Key event_code = key->get_keycode_with_modifiers();
-
- match = get_keycode() == key->get_keycode() && (!key->is_pressed() || (code & event_code) == code);
+ match = get_physical_keycode() == key->get_physical_keycode();
+ }
+ if (p_exact_match) {
+ match &= get_modifiers_mask() == key->get_modifiers_mask();
}
if (match) {
bool pressed = key->is_pressed();
- if (p_pressed != nullptr) {
- *p_pressed = pressed;
+ if (r_pressed != nullptr) {
+ *r_pressed = pressed;
}
float strength = pressed ? 1.0f : 0.0f;
- if (p_strength != nullptr) {
- *p_strength = strength;
+ if (r_strength != nullptr) {
+ *r_strength = strength;
}
- if (p_raw_strength != nullptr) {
- *p_raw_strength = strength;
+ if (r_raw_strength != nullptr) {
+ *r_raw_strength = strength;
}
}
return match;
@@ -585,24 +582,27 @@ Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, co
return mb;
}
-bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
+bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_null()) {
return false;
}
- bool match = mb->button_index == button_index;
+ bool match = button_index == mb->button_index;
+ if (p_exact_match) {
+ match &= get_modifiers_mask() == mb->get_modifiers_mask();
+ }
if (match) {
bool pressed = mb->is_pressed();
- if (p_pressed != nullptr) {
- *p_pressed = pressed;
+ if (r_pressed != nullptr) {
+ *r_pressed = pressed;
}
float strength = pressed ? 1.0f : 0.0f;
- if (p_strength != nullptr) {
- *p_strength = strength;
+ if (r_strength != nullptr) {
+ *r_strength = strength;
}
- if (p_raw_strength != nullptr) {
- *p_raw_strength = strength;
+ if (r_raw_strength != nullptr) {
+ *r_raw_strength = strength;
}
}
@@ -887,36 +887,40 @@ bool InputEventJoypadMotion::is_pressed() const {
return Math::abs(axis_value) >= 0.5f;
}
-bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
+bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const {
Ref<InputEventJoypadMotion> jm = p_event;
if (jm.is_null()) {
return false;
}
- bool match = (axis == jm->axis); // Matches even if not in the same direction, but returns a "not pressed" event.
+ // Matches even if not in the same direction, but returns a "not pressed" event.
+ bool match = axis == jm->axis;
+ if (p_exact_match) {
+ match &= (axis_value < 0) == (jm->axis_value < 0);
+ }
if (match) {
float jm_abs_axis_value = Math::abs(jm->get_axis_value());
bool same_direction = (((axis_value < 0) == (jm->axis_value < 0)) || jm->axis_value == 0);
bool pressed = same_direction && jm_abs_axis_value >= p_deadzone;
- if (p_pressed != nullptr) {
- *p_pressed = pressed;
+ if (r_pressed != nullptr) {
+ *r_pressed = pressed;
}
- if (p_strength != nullptr) {
+ if (r_strength != nullptr) {
if (pressed) {
if (p_deadzone == 1.0f) {
- *p_strength = 1.0f;
+ *r_strength = 1.0f;
} else {
- *p_strength = CLAMP(Math::inverse_lerp(p_deadzone, 1.0f, jm_abs_axis_value), 0.0f, 1.0f);
+ *r_strength = CLAMP(Math::inverse_lerp(p_deadzone, 1.0f, jm_abs_axis_value), 0.0f, 1.0f);
}
} else {
- *p_strength = 0.0f;
+ *r_strength = 0.0f;
}
}
- if (p_raw_strength != nullptr) {
+ if (r_raw_strength != nullptr) {
if (same_direction) { // NOT pressed, because we want to ignore the deadzone.
- *p_raw_strength = jm_abs_axis_value;
+ *r_raw_strength = jm_abs_axis_value;
} else {
- *p_raw_strength = 0.0f;
+ *r_raw_strength = 0.0f;
}
}
}
@@ -994,7 +998,7 @@ float InputEventJoypadButton::get_pressure() const {
return pressure;
}
-bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
+bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const {
Ref<InputEventJoypadButton> jb = p_event;
if (jb.is_null()) {
return false;
@@ -1003,15 +1007,15 @@ bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *
bool match = button_index == jb->button_index;
if (match) {
bool pressed = jb->is_pressed();
- if (p_pressed != nullptr) {
- *p_pressed = pressed;
+ if (r_pressed != nullptr) {
+ *r_pressed = pressed;
}
float strength = pressed ? 1.0f : 0.0f;
- if (p_strength != nullptr) {
- *p_strength = strength;
+ if (r_strength != nullptr) {
+ *r_strength = strength;
}
- if (p_raw_strength != nullptr) {
- *p_raw_strength = strength;
+ if (r_raw_strength != nullptr) {
+ *r_raw_strength = strength;
}
}
@@ -1217,8 +1221,9 @@ String InputEventScreenDrag::to_string() {
bool InputEventScreenDrag::accumulate(const Ref<InputEvent> &p_event) {
Ref<InputEventScreenDrag> drag = p_event;
- if (drag.is_null())
+ if (drag.is_null()) {
return false;
+ }
if (get_index() != drag->get_index()) {
return false;
@@ -1288,7 +1293,7 @@ bool InputEventAction::is_action(const StringName &p_action) const {
return action == p_action;
}
-bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const {
+bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const {
Ref<InputEventAction> act = p_event;
if (act.is_null()) {
return false;
@@ -1297,15 +1302,15 @@ bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pres
bool match = action == act->action;
if (match) {
bool pressed = act->pressed;
- if (p_pressed != nullptr) {
- *p_pressed = pressed;
+ if (r_pressed != nullptr) {
+ *r_pressed = pressed;
}
float strength = pressed ? 1.0f : 0.0f;
- if (p_strength != nullptr) {
- *p_strength = strength;
+ if (r_strength != nullptr) {
+ *r_strength = strength;
}
- if (p_raw_strength != nullptr) {
- *p_raw_strength = strength;
+ if (r_raw_strength != nullptr) {
+ *r_raw_strength = strength;
}
}
return match;
diff --git a/core/input/input_event.h b/core/input/input_event.h
index 29450dfc52..114db46623 100644
--- a/core/input/input_event.h
+++ b/core/input/input_event.h
@@ -79,7 +79,7 @@ public:
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
- virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const;
+ virtual bool action_match(const Ref<InputEvent> &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const;
virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const;
virtual bool is_action_type() const;
@@ -192,7 +192,7 @@ public:
Key get_keycode_with_modifiers() const;
Key get_physical_keycode_with_modifiers() const;
- virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
+ virtual bool action_match(const Ref<InputEvent> &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const override;
virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override;
virtual bool is_action_type() const override { return true; }
@@ -255,7 +255,7 @@ public:
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
- virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
+ virtual bool action_match(const Ref<InputEvent> &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const override;
virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override;
virtual bool is_action_type() const override { return true; }
@@ -315,7 +315,7 @@ public:
virtual bool is_pressed() const override;
- virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
+ virtual bool action_match(const Ref<InputEvent> &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const override;
virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override;
virtual bool is_action_type() const override { return true; }
@@ -344,7 +344,7 @@ public:
void set_pressure(float p_pressure);
float get_pressure() const;
- virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
+ virtual bool action_match(const Ref<InputEvent> &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const override;
virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override;
virtual bool is_action_type() const override { return true; }
@@ -437,7 +437,7 @@ public:
virtual bool is_action(const StringName &p_action) const;
- virtual bool action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float *p_raw_strength, float p_deadzone) const override;
+ virtual bool action_match(const Ref<InputEvent> &p_event, bool p_exact_match, float p_deadzone, bool *r_pressed, float *r_strength, float *r_raw_strength) const override;
virtual bool is_match(const Ref<InputEvent> &p_event, bool p_exact_match = true) const override;
virtual bool is_action_type() const override { return true; }
diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp
index 753ac72ab6..41083b4c47 100644
--- a/core/input/input_map.cpp
+++ b/core/input/input_map.cpp
@@ -126,15 +126,13 @@ List<StringName> InputMap::get_actions() const {
return actions;
}
-List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength) const {
+List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool p_exact_match, bool *r_pressed, float *r_strength, float *r_raw_strength) const {
ERR_FAIL_COND_V(!p_event.is_valid(), nullptr);
for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) {
int device = E->get()->get_device();
if (device == ALL_DEVICES || device == p_event->get_device()) {
- if (p_exact_match && E->get()->is_match(p_event, true)) {
- return E;
- } else if (!p_exact_match && E->get()->action_match(p_event, p_pressed, p_strength, p_raw_strength, p_action.deadzone)) {
+ if (E->get()->action_match(p_event, p_exact_match, p_action.deadzone, r_pressed, r_strength, r_raw_strength)) {
return E;
}
}
@@ -217,40 +215,28 @@ bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName
return event_get_action_status(p_event, p_action, p_exact_match);
}
-bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength) const {
+bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match, bool *r_pressed, float *r_strength, float *r_raw_strength) const {
OrderedHashMap<StringName, Action>::Element E = input_map.find(p_action);
ERR_FAIL_COND_V_MSG(!E, false, suggest_actions(p_action));
Ref<InputEventAction> input_event_action = p_event;
if (input_event_action.is_valid()) {
- bool pressed = input_event_action->is_pressed();
- if (p_pressed != nullptr) {
- *p_pressed = pressed;
+ const bool pressed = input_event_action->is_pressed();
+ if (r_pressed != nullptr) {
+ *r_pressed = pressed;
+ }
+ const float strength = pressed ? input_event_action->get_strength() : 0.0f;
+ if (r_strength != nullptr) {
+ *r_strength = strength;
}
- if (p_strength != nullptr) {
- *p_strength = pressed ? input_event_action->get_strength() : 0.0f;
+ if (r_raw_strength != nullptr) {
+ *r_raw_strength = strength;
}
return input_event_action->get_action() == p_action;
}
- bool pressed;
- float strength;
- float raw_strength;
- List<Ref<InputEvent>>::Element *event = _find_event(E.get(), p_event, p_exact_match, &pressed, &strength, &raw_strength);
- if (event != nullptr) {
- if (p_pressed != nullptr) {
- *p_pressed = pressed;
- }
- if (p_strength != nullptr) {
- *p_strength = strength;
- }
- if (p_raw_strength != nullptr) {
- *p_raw_strength = raw_strength;
- }
- return true;
- } else {
- return false;
- }
+ List<Ref<InputEvent>>::Element *event = _find_event(E.get(), p_event, p_exact_match, r_pressed, r_strength, r_raw_strength);
+ return event != nullptr;
}
const OrderedHashMap<StringName, InputMap::Action> &InputMap::get_action_map() const {
diff --git a/core/input/input_map.h b/core/input/input_map.h
index e896d1f679..79b4d1038f 100644
--- a/core/input/input_map.h
+++ b/core/input/input_map.h
@@ -58,7 +58,7 @@ private:
OrderedHashMap<String, List<Ref<InputEvent>>> default_builtin_cache;
OrderedHashMap<String, List<Ref<InputEvent>>> default_builtin_with_overrides_cache;
- List<Ref<InputEvent>>::Element *_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool p_exact_match = false, bool *p_pressed = nullptr, float *p_strength = nullptr, float *p_raw_strength = nullptr) const;
+ List<Ref<InputEvent>>::Element *_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool p_exact_match = false, bool *r_pressed = nullptr, float *r_strength = nullptr, float *r_raw_strength = nullptr) const;
Array _action_get_events(const StringName &p_action);
Array _get_actions();
@@ -83,7 +83,7 @@ public:
const List<Ref<InputEvent>> *action_get_events(const StringName &p_action);
bool event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match = false) const;
- bool event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match = false, bool *p_pressed = nullptr, float *p_strength = nullptr, float *p_raw_strength = nullptr) const;
+ bool event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match = false, bool *r_pressed = nullptr, float *r_strength = nullptr, float *r_raw_strength = nullptr) const;
const OrderedHashMap<StringName, Action> &get_action_map() const;
void load_from_project_settings();
diff --git a/core/io/compression.cpp b/core/io/compression.cpp
index d1f915f064..ae5ccf8354 100644
--- a/core/io/compression.cpp
+++ b/core/io/compression.cpp
@@ -212,7 +212,7 @@ int Compression::decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_s
strm.avail_in = p_src_size;
// Ensure the destination buffer is empty
- p_dst_vect->resize(0);
+ p_dst_vect->clear();
// decompress until deflate stream ends or end of file
do {
@@ -244,7 +244,7 @@ int Compression::decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_s
WARN_PRINT(strm.msg);
}
(void)inflateEnd(&strm);
- p_dst_vect->resize(0);
+ p_dst_vect->clear();
return ret;
}
} while (strm.avail_out > 0 && strm.avail_in > 0);
@@ -254,7 +254,7 @@ int Compression::decompress_dynamic(Vector<uint8_t> *p_dst_vect, int p_max_dst_s
// Enforce max output size
if (p_max_dst_size > -1 && strm.total_out > (uint64_t)p_max_dst_size) {
(void)inflateEnd(&strm);
- p_dst_vect->resize(0);
+ p_dst_vect->clear();
return Z_BUF_ERROR;
}
} while (ret != Z_STREAM_END);
diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp
index 3da9288ffd..db0758d7fc 100644
--- a/core/io/dir_access.cpp
+++ b/core/io/dir_access.cpp
@@ -145,14 +145,18 @@ Error DirAccess::make_dir_recursive(String p_dir) {
full_dir = full_dir.replace("\\", "/");
- //int slices = full_dir.get_slice_count("/");
-
String base;
if (full_dir.begins_with("res://")) {
base = "res://";
} else if (full_dir.begins_with("user://")) {
base = "user://";
+ } else if (full_dir.is_network_share_path()) {
+ int pos = full_dir.find("/", 2);
+ ERR_FAIL_COND_V(pos < 0, ERR_INVALID_PARAMETER);
+ pos = full_dir.find("/", pos + 1);
+ ERR_FAIL_COND_V(pos < 0, ERR_INVALID_PARAMETER);
+ base = full_dir.substr(0, pos + 1);
} else if (full_dir.begins_with("/")) {
base = "/";
} else if (full_dir.find(":/") != -1) {
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index 4d0747c591..52b1120b2a 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -96,6 +96,17 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) {
return query.substr(1);
}
+Error HTTPClient::verify_headers(const Vector<String> &p_headers) {
+ for (int i = 0; i < p_headers.size(); i++) {
+ String sanitized = p_headers[i].strip_edges();
+ ERR_FAIL_COND_V_MSG(sanitized.is_empty(), ERR_INVALID_PARAMETER, "Invalid HTTP header at index " + itos(i) + ": empty.");
+ ERR_FAIL_COND_V_MSG(sanitized.find(":") < 1, ERR_INVALID_PARAMETER,
+ "Invalid HTTP header at index " + itos(i) + ": String must contain header-value pair, delimited by ':', but was: " + p_headers[i]);
+ }
+
+ return OK;
+}
+
Dictionary HTTPClient::_get_response_headers_as_dictionary() {
List<String> rh;
get_response_headers(&rh);
diff --git a/core/io/http_client.h b/core/io/http_client.h
index 90c859d685..de6045f647 100644
--- a/core/io/http_client.h
+++ b/core/io/http_client.h
@@ -165,6 +165,7 @@ public:
static HTTPClient *create();
String query_string_from_dict(const Dictionary &p_dict);
+ Error verify_headers(const Vector<String> &p_headers);
virtual Error request(Method p_method, const String &p_url, const Vector<String> &p_headers, const uint8_t *p_body, int p_body_size) = 0;
virtual Error connect_to_host(const String &p_host, int p_port = -1, bool p_ssl = false, bool p_verify_host = true) = 0;
diff --git a/core/io/http_client_tcp.cpp b/core/io/http_client_tcp.cpp
index 6e4417e1ff..e61833ce7c 100644
--- a/core/io/http_client_tcp.cpp
+++ b/core/io/http_client_tcp.cpp
@@ -71,7 +71,7 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, bool p_ss
connection = tcp_connection;
if (ssl && https_proxy_port != -1) {
- proxy_client.instantiate(); // Needs proxy negotiation
+ proxy_client.instantiate(); // Needs proxy negotiation.
server_host = https_proxy_host;
server_port = https_proxy_port;
} else if (!ssl && http_proxy_port != -1) {
@@ -83,7 +83,7 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, bool p_ss
}
if (server_host.is_valid_ip_address()) {
- // Host contains valid IP
+ // Host contains valid IP.
Error err = tcp_connection->connect_to_host(IPAddress(server_host), server_port);
if (err) {
status = STATUS_CANT_CONNECT;
@@ -92,7 +92,7 @@ Error HTTPClientTCP::connect_to_host(const String &p_host, int p_port, bool p_ss
status = STATUS_CONNECTING;
} else {
- // Host contains hostname and needs to be resolved to IP
+ // Host contains hostname and needs to be resolved to IP.
resolving = IP::get_singleton()->resolve_hostname_queue_item(server_host);
status = STATUS_RESOLVING;
}
@@ -124,7 +124,7 @@ Ref<StreamPeer> HTTPClientTCP::get_connection() const {
static bool _check_request_url(HTTPClientTCP::Method p_method, const String &p_url) {
switch (p_method) {
case HTTPClientTCP::METHOD_CONNECT: {
- // Authority in host:port format, as in RFC7231
+ // Authority in host:port format, as in RFC7231.
int pos = p_url.find_char(':');
return 0 < pos && pos < p_url.length() - 1;
}
@@ -135,7 +135,7 @@ static bool _check_request_url(HTTPClientTCP::Method p_method, const String &p_u
[[fallthrough]];
}
default:
- // Absolute path or absolute URL
+ // Absolute path or absolute URL.
return p_url.begins_with("/") || p_url.begins_with("http://") || p_url.begins_with("https://");
}
}
@@ -146,6 +146,11 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector<
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(connection.is_null(), ERR_INVALID_DATA);
+ Error err = verify_headers(p_headers);
+ if (err) {
+ return err;
+ }
+
String uri = p_url;
if (!ssl && http_proxy_port != -1) {
uri = vformat("http://%s:%d%s", conn_host, conn_port, p_url);
@@ -173,7 +178,7 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector<
}
if (add_host) {
if ((ssl && conn_port == PORT_HTTPS) || (!ssl && conn_port == PORT_HTTP)) {
- // Don't append the standard ports
+ // Don't append the standard ports.
request += "Host: " + conn_host + "\r\n";
} else {
request += "Host: " + conn_host + ":" + itos(conn_port) + "\r\n";
@@ -192,21 +197,12 @@ Error HTTPClientTCP::request(Method p_method, const String &p_url, const Vector<
request += "\r\n";
CharString cs = request.utf8();
- Vector<uint8_t> data;
- data.resize(cs.length() + p_body_size);
- memcpy(data.ptrw(), cs.get_data(), cs.length());
+ request_buffer->clear();
+ request_buffer->put_data((const uint8_t *)cs.get_data(), cs.length());
if (p_body_size > 0) {
- memcpy(data.ptrw() + cs.length(), p_body, p_body_size);
- }
-
- // TODO Implement non-blocking requests.
- Error err = connection->put_data(data.ptr(), data.size());
-
- if (err) {
- close();
- status = STATUS_CONNECTION_ERROR;
- return err;
+ request_buffer->put_data(p_body, p_body_size);
}
+ request_buffer->seek(0);
status = STATUS_REQUESTING;
head_request = p_method == METHOD_HEAD;
@@ -257,6 +253,7 @@ void HTTPClientTCP::close() {
ip_candidates.clear();
response_headers.clear();
response_str.clear();
+ request_buffer->clear();
body_size = -1;
body_left = 0;
chunk_left = 0;
@@ -274,7 +271,7 @@ Error HTTPClientTCP::poll() {
IP::ResolverStatus rstatus = IP::get_singleton()->get_resolve_item_status(resolving);
switch (rstatus) {
case IP::RESOLVER_STATUS_WAITING:
- return OK; // Still resolving
+ return OK; // Still resolving.
case IP::RESOLVER_STATUS_DONE: {
ip_candidates = IP::get_singleton()->get_resolve_item_addresses(resolving);
@@ -356,7 +353,7 @@ Error HTTPClientTCP::poll() {
} else if (ssl) {
Ref<StreamPeerSSL> ssl;
if (!handshaking) {
- // Connect the StreamPeerSSL and start handshaking
+ // Connect the StreamPeerSSL and start handshaking.
ssl = Ref<StreamPeerSSL>(StreamPeerSSL::create());
ssl->set_blocking_handshake_enabled(false);
Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, conn_host);
@@ -368,7 +365,7 @@ Error HTTPClientTCP::poll() {
connection = ssl;
handshaking = true;
} else {
- // We are already handshaking, which means we can use your already active SSL connection
+ // We are already handshaking, which means we can use your already active SSL connection.
ssl = static_cast<Ref<StreamPeerSSL>>(connection);
if (ssl.is_null()) {
close();
@@ -376,22 +373,22 @@ Error HTTPClientTCP::poll() {
return ERR_CANT_CONNECT;
}
- ssl->poll(); // Try to finish the handshake
+ ssl->poll(); // Try to finish the handshake.
}
if (ssl->get_status() == StreamPeerSSL::STATUS_CONNECTED) {
- // Handshake has been successful
+ // Handshake has been successful.
handshaking = false;
ip_candidates.clear();
status = STATUS_CONNECTED;
return OK;
} else if (ssl->get_status() != StreamPeerSSL::STATUS_HANDSHAKING) {
- // Handshake has failed
+ // Handshake has failed.
close();
status = STATUS_SSL_HANDSHAKE_ERROR;
return ERR_CANT_CONNECT;
}
- // ... we will need to poll more for handshake to finish
+ // ... we will need to poll more for handshake to finish.
} else {
ip_candidates.clear();
status = STATUS_CONNECTED;
@@ -416,7 +413,7 @@ Error HTTPClientTCP::poll() {
} break;
case STATUS_BODY:
case STATUS_CONNECTED: {
- // Check if we are still connected
+ // Check if we are still connected.
if (ssl) {
Ref<StreamPeerSSL> tmp = connection;
tmp->poll();
@@ -428,10 +425,34 @@ Error HTTPClientTCP::poll() {
status = STATUS_CONNECTION_ERROR;
return ERR_CONNECTION_ERROR;
}
- // Connection established, requests can now be made
+ // Connection established, requests can now be made.
return OK;
} break;
case STATUS_REQUESTING: {
+ if (request_buffer->get_available_bytes()) {
+ int avail = request_buffer->get_available_bytes();
+ int pos = request_buffer->get_position();
+ const Vector<uint8_t> data = request_buffer->get_data_array();
+ int wrote = 0;
+ Error err;
+ if (blocking) {
+ err = connection->put_data(data.ptr() + pos, avail);
+ wrote += avail;
+ } else {
+ err = connection->put_partial_data(data.ptr() + pos, avail, wrote);
+ }
+ if (err != OK) {
+ close();
+ status = STATUS_CONNECTION_ERROR;
+ return ERR_CONNECTION_ERROR;
+ }
+ pos += wrote;
+ request_buffer->seek(pos);
+ if (avail - wrote > 0) {
+ return OK;
+ }
+ request_buffer->clear();
+ }
while (true) {
uint8_t byte;
int rec = 0;
@@ -547,7 +568,7 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() {
if (chunked) {
while (true) {
if (chunk_trailer_part) {
- // We need to consume the trailer part too or keep-alive will break
+ // We need to consume the trailer part too or keep-alive will break.
uint8_t b;
int rec = 0;
err = _get_http_data(&b, 1, rec);
@@ -560,18 +581,18 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() {
int cs = chunk.size();
if ((cs >= 2 && chunk[cs - 2] == '\r' && chunk[cs - 1] == '\n')) {
if (cs == 2) {
- // Finally over
+ // Finally over.
chunk_trailer_part = false;
status = STATUS_CONNECTED;
chunk.clear();
break;
} else {
- // We do not process nor return the trailer data
+ // We do not process nor return the trailer data.
chunk.clear();
}
}
} else if (chunk_left == 0) {
- // Reading length
+ // Reading length.
uint8_t b;
int rec = 0;
err = _get_http_data(&b, 1, rec);
@@ -658,7 +679,7 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() {
uint8_t *w = ret.ptrw();
err = _get_http_data(w + _offset, to_read, rec);
}
- if (rec <= 0) { // Ended up reading less
+ if (rec <= 0) { // Ended up reading less.
ret.resize(_offset);
break;
} else {
@@ -679,7 +700,7 @@ PackedByteArray HTTPClientTCP::read_response_body_chunk() {
close();
if (err == ERR_FILE_EOF) {
- status = STATUS_DISCONNECTED; // Server disconnected
+ status = STATUS_DISCONNECTED; // Server disconnected.
} else {
status = STATUS_CONNECTION_ERROR;
}
@@ -759,6 +780,7 @@ void HTTPClientTCP::set_https_proxy(const String &p_host, int p_port) {
HTTPClientTCP::HTTPClientTCP() {
tcp_connection.instantiate();
+ request_buffer.instantiate();
}
HTTPClient *(*HTTPClient::_create)() = HTTPClientTCP::_create_func;
diff --git a/core/io/http_client_tcp.h b/core/io/http_client_tcp.h
index 3fe8e2c0df..c10e0b1eca 100644
--- a/core/io/http_client_tcp.h
+++ b/core/io/http_client_tcp.h
@@ -38,13 +38,13 @@ private:
Status status = STATUS_DISCONNECTED;
IP::ResolverID resolving = IP::RESOLVER_INVALID_ID;
Array ip_candidates;
- int conn_port = -1; // Server to make requests to
+ int conn_port = -1; // Server to make requests to.
String conn_host;
- int server_port = -1; // Server to connect to (might be a proxy server)
+ int server_port = -1; // Server to connect to (might be a proxy server).
String server_host;
- int http_proxy_port = -1; // Proxy server for http requests
+ int http_proxy_port = -1; // Proxy server for http requests.
String http_proxy_host;
- int https_proxy_port = -1; // Proxy server for https requests
+ int https_proxy_port = -1; // Proxy server for https requests.
String https_proxy_host;
bool ssl = false;
bool ssl_verify_host = false;
@@ -62,9 +62,10 @@ private:
int64_t body_left = 0;
bool read_until_eof = false;
+ Ref<StreamPeerBuffer> request_buffer;
Ref<StreamPeerTCP> tcp_connection;
Ref<StreamPeer> connection;
- Ref<HTTPClientTCP> proxy_client; // Negotiate with proxy server
+ Ref<HTTPClientTCP> proxy_client; // Negotiate with proxy server.
int response_num = 0;
Vector<String> response_headers;
diff --git a/core/io/ip.cpp b/core/io/ip.cpp
index 4970afc1d3..8e0d47e762 100644
--- a/core/io/ip.cpp
+++ b/core/io/ip.cpp
@@ -98,6 +98,11 @@ struct _IP_ResolverPrivate {
if (queue[i].status.get() != IP::RESOLVER_STATUS_WAITING) {
continue;
}
+ // We might be overriding another result, but we don't care as long as the result is valid.
+ if (response.size()) {
+ String key = get_cache_key(hostname, type);
+ cache[key] = response;
+ }
queue[i].response = response;
queue[i].status.set(response.is_empty() ? IP::RESOLVER_STATUS_ERROR : IP::RESOLVER_STATUS_DONE);
}
@@ -120,30 +125,8 @@ struct _IP_ResolverPrivate {
};
IPAddress IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
- List<IPAddress> res;
- String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
-
- resolver->mutex.lock();
- if (resolver->cache.has(key)) {
- res = resolver->cache[key];
- } else {
- // This should be run unlocked so the resolver thread can keep
- // resolving other requests.
- resolver->mutex.unlock();
- _resolve_hostname(res, p_hostname, p_type);
- resolver->mutex.lock();
- // We might be overriding another result, but we don't care (they are the
- // same hostname).
- resolver->cache[key] = res;
- }
- resolver->mutex.unlock();
-
- for (int i = 0; i < res.size(); ++i) {
- if (res[i].is_valid()) {
- return res[i];
- }
- }
- return IPAddress();
+ const Array addresses = resolve_hostname_addresses(p_hostname, p_type);
+ return addresses.size() ? addresses[0].operator IPAddress() : IPAddress();
}
Array IP::resolve_hostname_addresses(const String &p_hostname, Type p_type) {
@@ -159,17 +142,16 @@ Array IP::resolve_hostname_addresses(const String &p_hostname, Type p_type) {
resolver->mutex.unlock();
_resolve_hostname(res, p_hostname, p_type);
resolver->mutex.lock();
- // We might be overriding another result, but we don't care (they are the
- // same hostname).
- resolver->cache[key] = res;
+ // We might be overriding another result, but we don't care as long as the result is valid.
+ if (res.size()) {
+ resolver->cache[key] = res;
+ }
}
resolver->mutex.unlock();
Array result;
for (int i = 0; i < res.size(); ++i) {
- if (res[i].is_valid()) {
- result.push_back(String(res[i]));
- }
+ result.push_back(String(res[i]));
}
return result;
}
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index e90d1695e5..0af236f766 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -39,7 +39,7 @@ void PacketPeer::set_encode_buffer_max_size(int p_max_size) {
ERR_FAIL_COND_MSG(p_max_size < 1024, "Max encode buffer must be at least 1024 bytes");
ERR_FAIL_COND_MSG(p_max_size > 256 * 1024 * 1024, "Max encode buffer cannot exceed 256 MiB");
encode_buffer_max_size = next_power_of_2(p_max_size);
- encode_buffer.resize(0);
+ encode_buffer.clear();
}
int PacketPeer::get_encode_buffer_max_size() const {
diff --git a/core/io/resource.h b/core/io/resource.h
index a0800c57cb..dea2160616 100644
--- a/core/io/resource.h
+++ b/core/io/resource.h
@@ -37,6 +37,8 @@
#include "core/templates/safe_refcount.h"
#include "core/templates/self_list.h"
+class Node;
+
#define RES_BASE_EXTENSION(m_ext) \
public: \
static void register_custom_data_to_otdb() { ClassDB::add_resource_base_extension(m_ext, get_class_static()); } \
diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp
index 28ebe811c9..c65968ef03 100644
--- a/core/io/stream_peer.cpp
+++ b/core/io/stream_peer.cpp
@@ -98,7 +98,7 @@ Array StreamPeer::_get_partial_data(int p_bytes) {
Error err = get_partial_data(&w[0], p_bytes, received);
if (err != OK) {
- data.resize(0);
+ data.clear();
} else if (received != data.size()) {
data.resize(received);
}
@@ -563,7 +563,7 @@ Vector<uint8_t> StreamPeerBuffer::get_data_array() const {
}
void StreamPeerBuffer::clear() {
- data.resize(0);
+ data.clear();
pointer = 0;
}
diff --git a/core/math/convex_hull.cpp b/core/math/convex_hull.cpp
index 912ffb8b16..bd292f4c2a 100644
--- a/core/math/convex_hull.cpp
+++ b/core/math/convex_hull.cpp
@@ -2129,7 +2129,7 @@ bool ConvexHullInternal::shift_face(Face *p_face, real_t p_amount, LocalVector<V
printf("Needed %d iterations to remove part\n", n);
#endif
- p_stack.resize(0);
+ p_stack.clear();
p_face->origin = shifted_origin;
return true;
@@ -2167,9 +2167,9 @@ real_t ConvexHullComputer::compute(const Vector3 *p_coords, int32_t p_count, rea
return shift;
}
- vertices.resize(0);
- edges.resize(0);
- faces.resize(0);
+ vertices.clear();
+ edges.clear();
+ faces.clear();
LocalVector<ConvexHullInternal::Vertex *> old_vertices;
get_vertex_copy(hull.vertex_list, old_vertices);
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index 4f8e79038f..203566579d 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -197,6 +197,7 @@ Error Expression::_get_token(Token &r_token) {
case '\'':
case '"': {
String str;
+ char32_t prev = 0;
while (true) {
char32_t ch = GET_CHAR();
@@ -234,9 +235,11 @@ Error Expression::_get_token(Token &r_token) {
case 'r':
res = 13;
break;
+ case 'U':
case 'u': {
- // hex number
- for (int j = 0; j < 4; j++) {
+ // Hexadecimal sequence.
+ int hex_len = (next == 'U') ? 6 : 4;
+ for (int j = 0; j < hex_len; j++) {
char32_t c = GET_CHAR();
if (c == 0) {
@@ -273,12 +276,46 @@ Error Expression::_get_token(Token &r_token) {
} break;
}
+ // Parse UTF-16 pair.
+ if ((res & 0xfffffc00) == 0xd800) {
+ if (prev == 0) {
+ prev = res;
+ continue;
+ } else {
+ _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ }
+ } else if ((res & 0xfffffc00) == 0xdc00) {
+ if (prev == 0) {
+ _set_error("Invalid UTF-16 sequence in string, unpaired trail surrogate");
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ } else {
+ res = (prev << 10UL) + res - ((0xd800 << 10UL) + 0xdc00 - 0x10000);
+ prev = 0;
+ }
+ }
+ if (prev != 0) {
+ _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ }
str += res;
-
} else {
+ if (prev != 0) {
+ _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ }
str += ch;
}
}
+ if (prev != 0) {
+ _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ }
r_token.type = TK_CONSTANT;
r_token.value = str;
diff --git a/core/math/rect2.h b/core/math/rect2.h
index 4ea24e8f88..b14c69302c 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -382,16 +382,16 @@ struct _NO_DISCARD_ Rect2i {
ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
}
#endif
- if (position.x > (p_rect.position.x + p_rect.size.width)) {
+ if (position.x >= (p_rect.position.x + p_rect.size.width)) {
return false;
}
- if ((position.x + size.width) < p_rect.position.x) {
+ if ((position.x + size.width) <= p_rect.position.x) {
return false;
}
- if (position.y > (p_rect.position.y + p_rect.size.height)) {
+ if (position.y >= (p_rect.position.y + p_rect.size.height)) {
return false;
}
- if ((position.y + size.height) < p_rect.position.y) {
+ if ((position.y + size.height) <= p_rect.position.y) {
return false;
}
@@ -405,8 +405,8 @@ struct _NO_DISCARD_ Rect2i {
}
#endif
return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) &&
- ((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) &&
- ((p_rect.position.y + p_rect.size.y) < (position.y + size.y));
+ ((p_rect.position.x + p_rect.size.x) <= (position.x + size.x)) &&
+ ((p_rect.position.y + p_rect.size.y) <= (position.y + size.y));
}
_FORCE_INLINE_ bool has_no_area() const {
diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py
index e961745d96..5de1b49026 100644
--- a/core/object/make_virtuals.py
+++ b/core/object/make_virtuals.py
@@ -123,9 +123,9 @@ def generate_version(argcount, const=False, returns=False):
callargtext += ","
callargtext += " m_ret& r_ret"
s = s.replace("$CALLSIBEGIN", "Variant ret = ")
- s = s.replace("$CALLSIRET", "r_ret = ret;")
+ s = s.replace("$CALLSIRET", "r_ret = VariantCaster<m_ret>::cast(ret);")
s = s.replace("$CALLPTRRETPASS", "&ret")
- s = s.replace("$CALLPTRRET", "r_ret = ret;")
+ s = s.replace("$CALLPTRRET", "r_ret = (m_ret)ret;")
else:
s = s.replace("$CALLSIBEGIN", "")
s = s.replace("$CALLSIRET", "")
diff --git a/core/object/object.h b/core/object/object.h
index 63130a1aef..1a0a81581d 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -700,8 +700,9 @@ public:
static String get_category_static() { return String(); }
virtual String get_class() const {
- if (_extension)
+ if (_extension) {
return _extension->class_name.operator String();
+ }
return "Object";
}
virtual String get_save_class() const { return get_class(); } //class stored when saving
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index 93b2060155..6e0a7c7022 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -3080,7 +3080,7 @@ bool String::is_subsequence_of(const String &p_string) const {
return _base_is_subsequence_of(p_string, false);
}
-bool String::is_subsequence_ofi(const String &p_string) const {
+bool String::is_subsequence_ofn(const String &p_string) const {
return _base_is_subsequence_of(p_string, true);
}
@@ -3558,6 +3558,10 @@ String String::rstrip(const String &p_chars) const {
return substr(0, end + 1);
}
+bool String::is_network_share_path() const {
+ return begins_with("//") || begins_with("\\\\");
+}
+
String String::simplify_path() const {
String s = *this;
String drive;
@@ -3570,6 +3574,9 @@ String String::simplify_path() const {
} else if (s.begins_with("user://")) {
drive = "user://";
s = s.substr(7, s.length());
+ } else if (is_network_share_path()) {
+ drive = s.substr(0, 2);
+ s = s.substr(2, s.length() - 2);
} else if (s.begins_with("/") || s.begins_with("\\")) {
drive = s.substr(0, 1);
s = s.substr(1, s.length() - 1);
@@ -4271,13 +4278,13 @@ bool String::is_relative_path() const {
String String::get_base_dir() const {
int end = 0;
- // url scheme style base
+ // URL scheme style base.
int basepos = find("://");
if (basepos != -1) {
end = basepos + 3;
}
- // windows top level directory base
+ // Windows top level directory base.
if (end == 0) {
basepos = find(":/");
if (basepos == -1) {
@@ -4288,7 +4295,24 @@ String String::get_base_dir() const {
}
}
- // unix root directory base
+ // Windows UNC network share path.
+ if (end == 0) {
+ if (is_network_share_path()) {
+ basepos = find("/", 2);
+ if (basepos == -1) {
+ basepos = find("\\", 2);
+ }
+ int servpos = find("/", basepos + 1);
+ if (servpos == -1) {
+ servpos = find("\\", basepos + 1);
+ }
+ if (servpos != -1) {
+ end = servpos + 1;
+ }
+ }
+ }
+
+ // Unix root directory base.
if (end == 0) {
if (begins_with("/")) {
end = 1;
diff --git a/core/string/ustring.h b/core/string/ustring.h
index 4840c236c0..6df87280a4 100644
--- a/core/string/ustring.h
+++ b/core/string/ustring.h
@@ -285,7 +285,7 @@ public:
bool ends_with(const String &p_string) const;
bool is_enclosed_in(const String &p_string) const;
bool is_subsequence_of(const String &p_string) const;
- bool is_subsequence_ofi(const String &p_string) const;
+ bool is_subsequence_ofn(const String &p_string) const;
bool is_quoted() const;
Vector<String> bigrams() const;
float similarity(const String &p_string) const;
@@ -405,6 +405,7 @@ public:
String get_file() const;
static String humanize_size(uint64_t p_size);
String simplify_path() const;
+ bool is_network_share_path() const;
String xml_escape(bool p_escape_quotes = false) const;
String xml_unescape() const;
diff --git a/core/templates/vector.h b/core/templates/vector.h
index bd4c6ade86..0877e04e01 100644
--- a/core/templates/vector.h
+++ b/core/templates/vector.h
@@ -95,9 +95,7 @@ public:
void append_array(Vector<T> p_other);
- bool has(const T &p_val) const {
- return find(p_val, 0) != -1;
- }
+ _FORCE_INLINE_ bool has(const T &p_val) const { return find(p_val) != -1; }
template <class C>
void sort_custom() {
diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h
index 14f49d530c..b6fdb4d902 100644
--- a/core/variant/binder_common.h
+++ b/core/variant/binder_common.h
@@ -44,24 +44,42 @@
#include <stdio.h>
+// Variant cannot define an implicit cast operator for every Object subclass, so the
+// casting is done here, to allow binding methods with parameters more specific than Object *
+
template <class T>
struct VariantCaster {
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
- return p_variant;
+ using TStripped = std::remove_pointer_t<T>;
+ if constexpr (std::is_base_of<Object, TStripped>::value) {
+ return Object::cast_to<TStripped>(p_variant);
+ } else {
+ return p_variant;
+ }
}
};
template <class T>
struct VariantCaster<T &> {
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
- return p_variant;
+ using TStripped = std::remove_pointer_t<T>;
+ if constexpr (std::is_base_of<Object, TStripped>::value) {
+ return Object::cast_to<TStripped>(p_variant);
+ } else {
+ return p_variant;
+ }
}
};
template <class T>
struct VariantCaster<const T &> {
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
- return p_variant;
+ using TStripped = std::remove_pointer_t<T>;
+ if constexpr (std::is_base_of<Object, TStripped>::value) {
+ return Object::cast_to<TStripped>(p_variant);
+ } else {
+ return p_variant;
+ }
}
};
@@ -135,7 +153,13 @@ struct PtrToArg<char32_t> {
template <typename T>
struct VariantObjectClassChecker {
static _FORCE_INLINE_ bool check(const Variant &p_variant) {
- return true;
+ using TStripped = std::remove_pointer_t<T>;
+ if constexpr (std::is_base_of<Object, TStripped>::value) {
+ Object *obj = p_variant;
+ return Object::cast_to<TStripped>(p_variant) || !obj;
+ } else {
+ return true;
+ }
}
};
@@ -151,24 +175,6 @@ struct VariantObjectClassChecker<const Ref<T> &> {
}
};
-template <>
-struct VariantObjectClassChecker<Node *> {
- static _FORCE_INLINE_ bool check(const Variant &p_variant) {
- Object *obj = p_variant;
- Node *node = p_variant;
- return node || !obj;
- }
-};
-
-template <>
-struct VariantObjectClassChecker<Control *> {
- static _FORCE_INLINE_ bool check(const Variant &p_variant) {
- Object *obj = p_variant;
- Control *control = p_variant;
- return control || !obj;
- }
-};
-
#ifdef DEBUG_METHODS_ENABLED
template <class T>
diff --git a/core/variant/native_ptr.h b/core/variant/native_ptr.h
index fe541c8d4b..8e9fbbc0a4 100644
--- a/core/variant/native_ptr.h
+++ b/core/variant/native_ptr.h
@@ -53,22 +53,36 @@ struct GDNativePtr {
operator Variant() const { return uint64_t(data); }
};
-#define GDVIRTUAL_NATIVE_PTR(m_type) \
- template <> \
- struct GDNativeConstPtr<const m_type> { \
- const m_type *data = nullptr; \
- GDNativeConstPtr(const m_type *p_assign) { data = p_assign; } \
- static const char *get_name() { return "const " #m_type; } \
- operator const m_type *() const { return data; } \
- operator Variant() const { return uint64_t(data); } \
- }; \
- template <> \
- struct GDNativePtr<m_type> { \
- m_type *data = nullptr; \
- GDNativePtr(m_type *p_assign) { data = p_assign; } \
- static const char *get_name() { return #m_type; } \
- operator m_type *() const { return data; } \
- operator Variant() const { return uint64_t(data); } \
+#define GDVIRTUAL_NATIVE_PTR(m_type) \
+ template <> \
+ struct GDNativeConstPtr<const m_type> { \
+ const m_type *data = nullptr; \
+ GDNativeConstPtr() {} \
+ GDNativeConstPtr(const m_type *p_assign) { data = p_assign; } \
+ static const char *get_name() { return "const " #m_type; } \
+ operator const m_type *() const { return data; } \
+ operator Variant() const { return uint64_t(data); } \
+ }; \
+ template <> \
+ struct VariantCaster<GDNativeConstPtr<const m_type>> { \
+ static _FORCE_INLINE_ GDNativeConstPtr<const m_type> cast(const Variant &p_variant) { \
+ return GDNativeConstPtr<const m_type>((const m_type *)p_variant.operator uint64_t()); \
+ } \
+ }; \
+ template <> \
+ struct GDNativePtr<m_type> { \
+ m_type *data = nullptr; \
+ GDNativePtr() {} \
+ GDNativePtr(m_type *p_assign) { data = p_assign; } \
+ static const char *get_name() { return #m_type; } \
+ operator m_type *() const { return data; } \
+ operator Variant() const { return uint64_t(data); } \
+ }; \
+ template <> \
+ struct VariantCaster<GDNativePtr<m_type>> { \
+ static _FORCE_INLINE_ GDNativePtr<m_type> cast(const Variant &p_variant) { \
+ return GDNativePtr<m_type>((m_type *)p_variant.operator uint64_t()); \
+ } \
};
template <class T>
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index 38610c4f29..fcfa530388 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -38,8 +38,6 @@
#include "core/math/math_funcs.h"
#include "core/string/print_string.h"
#include "core/variant/variant_parser.h"
-#include "scene/gui/control.h"
-#include "scene/main/node.h"
String Variant::get_type_name(Variant::Type p_type) {
switch (p_type) {
@@ -2004,22 +2002,6 @@ Object *Variant::get_validated_object() const {
}
}
-Variant::operator Node *() const {
- if (type == OBJECT) {
- return Object::cast_to<Node>(_get_obj().obj);
- } else {
- return nullptr;
- }
-}
-
-Variant::operator Control *() const {
- if (type == OBJECT) {
- return Object::cast_to<Control>(_get_obj().obj);
- } else {
- return nullptr;
- }
-}
-
Variant::operator Dictionary() const {
if (type == DICTIONARY) {
return *reinterpret_cast<const Dictionary *>(_data._mem);
@@ -3414,7 +3396,7 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method,
}
String class_name = p_base->get_class();
- Ref<Script> script = p_base->get_script();
+ Ref<Resource> script = p_base->get_script();
if (script.is_valid() && script->get_path().is_resource_file()) {
class_name += "(" + script->get_path().get_file() + ")";
}
diff --git a/core/variant/variant.h b/core/variant/variant.h
index 17988a46d7..36fa755647 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -53,8 +53,6 @@
#include "core/variant/dictionary.h"
class Object;
-class Node; // helper
-class Control; // helper
struct PropertyInfo;
struct MethodInfo;
@@ -339,8 +337,6 @@ public:
operator ::RID() const;
operator Object *() const;
- operator Node *() const;
- operator Control *() const;
operator Callable() const;
operator Signal() const;
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 8dd48a4c28..aecc6e9a26 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1382,7 +1382,7 @@ static void _register_variant_builtin_methods() {
bind_methodv(String, begins_with, static_cast<bool (String::*)(const String &) const>(&String::begins_with), sarray("text"), varray());
bind_method(String, ends_with, sarray("text"), varray());
bind_method(String, is_subsequence_of, sarray("text"), varray());
- bind_method(String, is_subsequence_ofi, sarray("text"), varray());
+ bind_method(String, is_subsequence_ofn, sarray("text"), varray());
bind_method(String, bigrams, sarray(), varray());
bind_method(String, similarity, sarray("text"), varray());
@@ -1789,6 +1789,7 @@ static void _register_variant_builtin_methods() {
bind_method(Transform3D, scaled, sarray("scale"), varray());
bind_method(Transform3D, translated, sarray("offset"), varray());
bind_method(Transform3D, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0)));
+ bind_method(Transform3D, sphere_interpolate_with, sarray("xform", "weight"), varray());
bind_method(Transform3D, interpolate_with, sarray("xform", "weight"), varray());
bind_method(Transform3D, is_equal_approx, sarray("xform"), varray());
diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp
index 57875bf50f..96cdc0678e 100644
--- a/core/variant/variant_parser.cpp
+++ b/core/variant/variant_parser.cpp
@@ -217,6 +217,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
}
case '"': {
String str;
+ char32_t prev = 0;
while (true) {
char32_t ch = p_stream->get_char();
@@ -252,10 +253,13 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
case 'r':
res = 13;
break;
+ case 'U':
case 'u': {
- //hex number
- for (int j = 0; j < 4; j++) {
+ // Hexadecimal sequence.
+ int hex_len = (next == 'U') ? 6 : 4;
+ for (int j = 0; j < hex_len; j++) {
char32_t c = p_stream->get_char();
+
if (c == 0) {
r_err_str = "Unterminated String";
r_token.type = TK_ERROR;
@@ -290,15 +294,49 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
} break;
}
+ // Parse UTF-16 pair.
+ if ((res & 0xfffffc00) == 0xd800) {
+ if (prev == 0) {
+ prev = res;
+ continue;
+ } else {
+ r_err_str = "Invalid UTF-16 sequence in string, unpaired lead surrogate";
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ }
+ } else if ((res & 0xfffffc00) == 0xdc00) {
+ if (prev == 0) {
+ r_err_str = "Invalid UTF-16 sequence in string, unpaired trail surrogate";
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ } else {
+ res = (prev << 10UL) + res - ((0xd800 << 10UL) + 0xdc00 - 0x10000);
+ prev = 0;
+ }
+ }
+ if (prev != 0) {
+ r_err_str = "Invalid UTF-16 sequence in string, unpaired lead surrogate";
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ }
str += res;
-
} else {
+ if (prev != 0) {
+ r_err_str = "Invalid UTF-16 sequence in string, unpaired lead surrogate";
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ }
if (ch == '\n') {
line++;
}
str += ch;
}
}
+ if (prev != 0) {
+ r_err_str = "Invalid UTF-16 sequence in string, unpaired lead surrogate";
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ }
if (p_stream->is_utf8()) {
str.parse_utf8(str.ascii(true).get_data());
diff --git a/doc/classes/AnimationNodeOneShot.xml b/doc/classes/AnimationNodeOneShot.xml
index 116b54e39e..71ed82cf46 100644
--- a/doc/classes/AnimationNodeOneShot.xml
+++ b/doc/classes/AnimationNodeOneShot.xml
@@ -10,19 +10,6 @@
<link title="AnimationTree">$DOCS_URL/tutorials/animation/animation_tree.html</link>
<link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link>
</tutorials>
- <methods>
- <method name="get_mix_mode" qualifiers="const">
- <return type="int" enum="AnimationNodeOneShot.MixMode" />
- <description>
- </description>
- </method>
- <method name="set_mix_mode">
- <return type="void" />
- <argument index="0" name="mode" type="int" enum="AnimationNodeOneShot.MixMode" />
- <description>
- </description>
- </method>
- </methods>
<members>
<member name="autorestart" type="bool" setter="set_autorestart" getter="has_autorestart" default="false">
If [code]true[/code], the sub-animation will restart automatically after finishing.
@@ -37,6 +24,8 @@
</member>
<member name="fadeout_time" type="float" setter="set_fadeout_time" getter="get_fadeout_time" default="0.1">
</member>
+ <member name="mix_mode" type="int" setter="set_mix_mode" getter="get_mix_mode" enum="AnimationNodeOneShot.MixMode" default="0">
+ </member>
<member name="sync" type="bool" setter="set_use_sync" getter="is_using_sync" default="false">
</member>
</members>
diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml
index 0f7e6799be..5280b7445d 100644
--- a/doc/classes/Area2D.xml
+++ b/doc/classes/Area2D.xml
@@ -31,7 +31,7 @@
<return type="bool" />
<argument index="0" name="area" type="Node" />
<description>
- If [code]true[/code], the given area overlaps the Area2D.
+ Returns [code]true[/code] if the given [Area2D] intersects or overlaps this [Area2D], [code]false[/code] otherwise.
[b]Note:[/b] The result of this test is not immediate after moving objects. For performance, the list of overlaps is updated once per frame and before the physics step. Consider using signals instead.
</description>
</method>
@@ -39,9 +39,9 @@
<return type="bool" />
<argument index="0" name="body" type="Node" />
<description>
- If [code]true[/code], the given physics body overlaps the Area2D.
+ Returns [code]true[/code] if the given physics body intersects or overlaps this [Area2D], [code]false[/code] otherwise.
[b]Note:[/b] The result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead.
- The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance (while TileMaps are not physics bodies themselves, they register their tiles with collision shapes as a virtual physics body).
+ The [code]body[/code] argument can either be a [PhysicsBody2D] or a [TileMap] instance. While TileMaps are not physics bodies themselves, they register their tiles with collision shapes as a virtual physics body.
</description>
</method>
</methods>
diff --git a/doc/classes/Area3D.xml b/doc/classes/Area3D.xml
index 450ed44307..4f456cb56d 100644
--- a/doc/classes/Area3D.xml
+++ b/doc/classes/Area3D.xml
@@ -29,7 +29,7 @@
<return type="bool" />
<argument index="0" name="area" type="Node" />
<description>
- If [code]true[/code], the given area overlaps the Area3D.
+ Returns [code]true[/code] if the given [Area3D] intersects or overlaps this [Area3D], [code]false[/code] otherwise.
[b]Note:[/b] The result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead.
</description>
</method>
@@ -37,9 +37,9 @@
<return type="bool" />
<argument index="0" name="body" type="Node" />
<description>
- If [code]true[/code], the given physics body overlaps the Area3D.
+ Returns [code]true[/code] if the given physics body intersects or overlaps this [Area3D], [code]false[/code] otherwise.
[b]Note:[/b] The result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead.
- The [code]body[/code] argument can either be a [PhysicsBody3D] or a [GridMap] instance (while GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body).
+ The [code]body[/code] argument can either be a [PhysicsBody3D] or a [GridMap] instance. While GridMaps are not physics body themselves, they register their tiles with collision shapes as a virtual physics body.
</description>
</method>
</methods>
diff --git a/doc/classes/AudioEffectSpectrumAnalyzer.xml b/doc/classes/AudioEffectSpectrumAnalyzer.xml
index b2f2c55aa2..50e38d5d1e 100644
--- a/doc/classes/AudioEffectSpectrumAnalyzer.xml
+++ b/doc/classes/AudioEffectSpectrumAnalyzer.xml
@@ -8,8 +8,8 @@
See also [AudioStreamGenerator] for procedurally generating sounds.
</description>
<tutorials>
- <link title="https://godotengine.org/asset-library/asset/528">Audio Spectrum Demo</link>
- <link title="https://godotengine.org/article/godot-32-will-get-new-audio-features">Godot 3.2 will get new audio features</link>
+ <link title="Audio Spectrum Demo">https://godotengine.org/asset-library/asset/528</link>
+ <link title="Godot 3.2 will get new audio features">https://godotengine.org/article/godot-32-will-get-new-audio-features</link>
</tutorials>
<members>
<member name="buffer_length" type="float" setter="set_buffer_length" getter="get_buffer_length" default="2.0">
diff --git a/doc/classes/AudioStreamGenerator.xml b/doc/classes/AudioStreamGenerator.xml
index 05406846ce..e54ce27a83 100644
--- a/doc/classes/AudioStreamGenerator.xml
+++ b/doc/classes/AudioStreamGenerator.xml
@@ -10,7 +10,7 @@
</description>
<tutorials>
<link title="Audio Generator Demo">https://godotengine.org/asset-library/asset/526</link>
- <link title="https://godotengine.org/article/godot-32-will-get-new-audio-features">Godot 3.2 will get new audio features</link>
+ <link title="Godot 3.2 will get new audio features">https://godotengine.org/article/godot-32-will-get-new-audio-features</link>
</tutorials>
<members>
<member name="buffer_length" type="float" setter="set_buffer_length" getter="get_buffer_length" default="0.5">
diff --git a/doc/classes/AudioStreamGeneratorPlayback.xml b/doc/classes/AudioStreamGeneratorPlayback.xml
index 7520d5d97a..42caa23763 100644
--- a/doc/classes/AudioStreamGeneratorPlayback.xml
+++ b/doc/classes/AudioStreamGeneratorPlayback.xml
@@ -8,7 +8,7 @@
</description>
<tutorials>
<link title="Audio Generator Demo">https://godotengine.org/asset-library/asset/526</link>
- <link title="https://godotengine.org/article/godot-32-will-get-new-audio-features">Godot 3.2 will get new audio features</link>
+ <link title="Godot 3.2 will get new audio features">https://godotengine.org/article/godot-32-will-get-new-audio-features</link>
</tutorials>
<methods>
<method name="can_push_buffer" qualifiers="const">
diff --git a/doc/classes/BitMap.xml b/doc/classes/BitMap.xml
index dc655ee3b0..ebcdcab75e 100644
--- a/doc/classes/BitMap.xml
+++ b/doc/classes/BitMap.xml
@@ -9,6 +9,12 @@
<tutorials>
</tutorials>
<methods>
+ <method name="convert_to_image" qualifiers="const">
+ <return type="Image" />
+ <description>
+ Returns an image of the same size as the bitmap and with a [enum Image.Format] of type [code]FORMAT_L8[/code]. [code]true[/code] bits of the bitmap are being converted into white pixels, and [code]false[/code] bits into black.
+ </description>
+ </method>
<method name="create">
<return type="void" />
<argument index="0" name="size" type="Vector2" />
@@ -64,6 +70,13 @@
[code]epsilon[/code] is passed to RDP to control how accurately the polygons cover the bitmap: a lower [code]epsilon[/code] corresponds to more points in the polygons.
</description>
</method>
+ <method name="resize">
+ <return type="void" />
+ <argument index="0" name="new_size" type="Vector2" />
+ <description>
+ Resizes the image to [code]new_size[/code].
+ </description>
+ </method>
<method name="set_bit">
<return type="void" />
<argument index="0" name="position" type="Vector2" />
diff --git a/doc/classes/BoxMesh.xml b/doc/classes/BoxMesh.xml
index af3365b6ea..bf499c8971 100644
--- a/doc/classes/BoxMesh.xml
+++ b/doc/classes/BoxMesh.xml
@@ -11,7 +11,7 @@
<tutorials>
</tutorials>
<members>
- <member name="size" type="Vector3" setter="set_size" getter="get_size" default="Vector3(2, 2, 2)">
+ <member name="size" type="Vector3" setter="set_size" getter="get_size" default="Vector3(1, 1, 1)">
The box's width, height and depth.
</member>
<member name="subdivide_depth" type="int" setter="set_subdivide_depth" getter="get_subdivide_depth" default="0">
diff --git a/doc/classes/BoxShape3D.xml b/doc/classes/BoxShape3D.xml
index 3bfded6512..cf2bf2338b 100644
--- a/doc/classes/BoxShape3D.xml
+++ b/doc/classes/BoxShape3D.xml
@@ -12,7 +12,7 @@
<link title="3D Platformer Demo">https://godotengine.org/asset-library/asset/125</link>
</tutorials>
<members>
- <member name="size" type="Vector3" setter="set_size" getter="get_size" default="Vector3(2, 2, 2)">
+ <member name="size" type="Vector3" setter="set_size" getter="get_size" default="Vector3(1, 1, 1)">
The box's width, height and depth.
</member>
</members>
diff --git a/doc/classes/ButtonGroup.xml b/doc/classes/ButtonGroup.xml
index e3e781ac10..24bdc95baf 100644
--- a/doc/classes/ButtonGroup.xml
+++ b/doc/classes/ButtonGroup.xml
@@ -28,7 +28,7 @@
</members>
<signals>
<signal name="pressed">
- <argument index="0" name="button" type="Object" />
+ <argument index="0" name="button" type="BaseButton" />
<description>
Emitted when one of the buttons of the group is pressed.
</description>
diff --git a/doc/classes/CapsuleMesh.xml b/doc/classes/CapsuleMesh.xml
index 3b4e60ce93..45dd64c174 100644
--- a/doc/classes/CapsuleMesh.xml
+++ b/doc/classes/CapsuleMesh.xml
@@ -9,13 +9,13 @@
<tutorials>
</tutorials>
<members>
- <member name="height" type="float" setter="set_height" getter="get_height" default="3.0">
+ <member name="height" type="float" setter="set_height" getter="get_height" default="2.0">
Total height of the capsule mesh (including the hemispherical ends).
</member>
<member name="radial_segments" type="int" setter="set_radial_segments" getter="get_radial_segments" default="64">
Number of radial segments on the capsule mesh.
</member>
- <member name="radius" type="float" setter="set_radius" getter="get_radius" default="1.0">
+ <member name="radius" type="float" setter="set_radius" getter="get_radius" default="0.5">
Radius of the capsule mesh.
</member>
<member name="rings" type="int" setter="set_rings" getter="get_rings" default="8">
diff --git a/doc/classes/CapsuleShape3D.xml b/doc/classes/CapsuleShape3D.xml
index 8856ec3779..ba4ead4930 100644
--- a/doc/classes/CapsuleShape3D.xml
+++ b/doc/classes/CapsuleShape3D.xml
@@ -10,10 +10,10 @@
<link title="3D Physics Tests Demo">https://godotengine.org/asset-library/asset/675</link>
</tutorials>
<members>
- <member name="height" type="float" setter="set_height" getter="get_height" default="3.0">
+ <member name="height" type="float" setter="set_height" getter="get_height" default="2.0">
The capsule's height.
</member>
- <member name="radius" type="float" setter="set_radius" getter="get_radius" default="1.0">
+ <member name="radius" type="float" setter="set_radius" getter="get_radius" default="0.5">
The capsule's radius.
</member>
</members>
diff --git a/doc/classes/CodeEdit.xml b/doc/classes/CodeEdit.xml
index b3add6cfa2..09696d4d2a 100644
--- a/doc/classes/CodeEdit.xml
+++ b/doc/classes/CodeEdit.xml
@@ -607,6 +607,9 @@
<theme_item name="font_outline_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
The tint of text outline of the [CodeEdit].
</theme_item>
+ <theme_item name="font_placeholder_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 0.6)">
+ Font color for [member TextEdit.placeholder_text].
+ </theme_item>
<theme_item name="font_readonly_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 0.5)">
Sets the font [Color] when [member TextEdit.editable] is disabled.
</theme_item>
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index d5551e1e04..b6c2dac33c 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -380,12 +380,6 @@
Returns the focus neighbor for the specified [enum Side]. A getter method for [member focus_neighbor_bottom], [member focus_neighbor_left], [member focus_neighbor_right] and [member focus_neighbor_top].
</description>
</method>
- <method name="get_focus_owner" qualifiers="const">
- <return type="Control" />
- <description>
- Returns the control that has the keyboard focus or [code]null[/code] if none.
- </description>
- </method>
<method name="get_global_rect" qualifiers="const">
<return type="Rect2" />
<description>
diff --git a/doc/classes/CurveTexture.xml b/doc/classes/CurveTexture.xml
index fe75f029f0..99b5ef2f4f 100644
--- a/doc/classes/CurveTexture.xml
+++ b/doc/classes/CurveTexture.xml
@@ -14,7 +14,7 @@
</member>
<member name="texture_mode" type="int" setter="set_texture_mode" getter="get_texture_mode" enum="CurveTexture.TextureMode" default="0">
</member>
- <member name="width" type="int" setter="set_width" getter="get_width" default="2048">
+ <member name="width" type="int" setter="set_width" getter="get_width" default="256">
The width of the texture.
</member>
</members>
diff --git a/doc/classes/CurveXYZTexture.xml b/doc/classes/CurveXYZTexture.xml
index 815653e987..b6dd90c7d3 100644
--- a/doc/classes/CurveXYZTexture.xml
+++ b/doc/classes/CurveXYZTexture.xml
@@ -13,7 +13,7 @@
</member>
<member name="curve_z" type="Curve" setter="set_curve_z" getter="get_curve_z">
</member>
- <member name="width" type="int" setter="set_width" getter="get_width" default="2048">
+ <member name="width" type="int" setter="set_width" getter="get_width" default="256">
</member>
</members>
</class>
diff --git a/doc/classes/CylinderMesh.xml b/doc/classes/CylinderMesh.xml
index 077435990b..ce34cc91ad 100644
--- a/doc/classes/CylinderMesh.xml
+++ b/doc/classes/CylinderMesh.xml
@@ -9,7 +9,7 @@
<tutorials>
</tutorials>
<members>
- <member name="bottom_radius" type="float" setter="set_bottom_radius" getter="get_bottom_radius" default="1.0">
+ <member name="bottom_radius" type="float" setter="set_bottom_radius" getter="get_bottom_radius" default="0.5">
Bottom radius of the cylinder. If set to [code]0.0[/code], the bottom faces will not be generated, resulting in a conic shape.
</member>
<member name="height" type="float" setter="set_height" getter="get_height" default="2.0">
@@ -21,7 +21,7 @@
<member name="rings" type="int" setter="set_rings" getter="get_rings" default="4">
Number of edge rings along the height of the cylinder. Changing [member rings] does not have any visual impact unless a shader or procedural mesh tool is used to alter the vertex data. Higher values result in more subdivisions, which can be used to create smoother-looking effects with shaders or procedural mesh tools (at the cost of performance). When not altering the vertex data using a shader or procedural mesh tool, [member rings] should be kept to its default value.
</member>
- <member name="top_radius" type="float" setter="set_top_radius" getter="get_top_radius" default="1.0">
+ <member name="top_radius" type="float" setter="set_top_radius" getter="get_top_radius" default="0.5">
Top radius of the cylinder. If set to [code]0.0[/code], the top faces will not be generated, resulting in a conic shape.
</member>
</members>
diff --git a/doc/classes/CylinderShape3D.xml b/doc/classes/CylinderShape3D.xml
index d40b96710b..6fa6c4d75e 100644
--- a/doc/classes/CylinderShape3D.xml
+++ b/doc/classes/CylinderShape3D.xml
@@ -15,7 +15,7 @@
<member name="height" type="float" setter="set_height" getter="get_height" default="2.0">
The cylinder's height.
</member>
- <member name="radius" type="float" setter="set_radius" getter="get_radius" default="1.0">
+ <member name="radius" type="float" setter="set_radius" getter="get_radius" default="0.5">
The cylinder's radius.
</member>
</members>
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index 6e06bf454c..8be944b105 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -569,6 +569,15 @@
Returns the mode of the given window.
</description>
</method>
+ <method name="window_get_native_handle" qualifiers="const">
+ <return type="int" />
+ <argument index="0" name="handle_type" type="int" enum="DisplayServer.HandleType" />
+ <argument index="1" name="window_id" type="int" default="0" />
+ <description>
+ Returns internal structure pointers for use in plugins.
+ [b]Note:[/b] This method is implemented on Android, Linux, macOS and Windows.
+ </description>
+ </method>
<method name="window_get_position" qualifiers="const">
<return type="Vector2i" />
<argument index="0" name="window_id" type="int" default="0" />
@@ -930,5 +939,22 @@
Displays the most recent image in the queue on vertical blanking intervals, while rendering to the other images (no tearing is visible).
Although not guaranteed, the images can be rendered as fast as possible, which may reduce input lag.
</constant>
+ <constant name="DISPLAY_HANDLE" value="0" enum="HandleType">
+ Display handle:
+ - Linux: [code]X11::Display*[/code] for the display.
+ </constant>
+ <constant name="WINDOW_HANDLE" value="1" enum="HandleType">
+ Window handle:
+ - Windows: [code]HWND[/code] for the window.
+ - Linux: [code]X11::Window*[/code] for the window.
+ - MacOS: [code]NSWindow*[/code] for the window.
+ - iOS: [code]UIViewController*[/code] for the view controller.
+ - Android: [code]jObject[/code] for the activity.
+ </constant>
+ <constant name="WINDOW_VIEW" value="2" enum="HandleType">
+ Window view:
+ - MacOS: [code]NSView*[/code] for the window main view.
+ - iOS: [code]UIView*[/code] for the window main view.
+ </constant>
</constants>
</class>
diff --git a/doc/classes/EditorInspector.xml b/doc/classes/EditorInspector.xml
index 27dab3d422..de122cb8bb 100644
--- a/doc/classes/EditorInspector.xml
+++ b/doc/classes/EditorInspector.xml
@@ -59,8 +59,8 @@
</description>
</signal>
<signal name="resource_selected">
- <argument index="0" name="res" type="Object" />
- <argument index="1" name="prop" type="String" />
+ <argument index="0" name="resource" type="Resource" />
+ <argument index="1" name="path" type="String" />
<description>
Emitted when a resource is selected in the inspector.
</description>
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index 7b0a300782..cc1243898f 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -438,9 +438,9 @@
<method name="add_tool_submenu_item">
<return type="void" />
<argument index="0" name="name" type="String" />
- <argument index="1" name="submenu" type="Object" />
+ <argument index="1" name="submenu" type="PopupMenu" />
<description>
- Adds a custom submenu under [b]Project &gt; Tools &gt;[/b] [code]name[/code]. [code]submenu[/code] should be an object of class [PopupMenu]. Use [code]remove_tool_menu_item(name)[/code] on plugin clean up to remove the menu.
+ Adds a custom [PopupMenu] submenu under [b]Project &gt; Tools &gt;[/b] [code]name[/code]. Use [code]remove_tool_menu_item(name)[/code] on plugin clean up to remove the menu.
</description>
</method>
<method name="add_translation_parser_plugin">
diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml
index b31162f10f..c8c0494378 100644
--- a/doc/classes/Environment.xml
+++ b/doc/classes/Environment.xml
@@ -154,6 +154,13 @@
<member name="glow_levels/7" type="float" setter="set_glow_level" getter="get_glow_level" default="0.0">
The intensity of the 7th level of glow. This is the most "global" level (blurriest).
</member>
+ <member name="glow_map" type="Texture" setter="set_glow_map" getter="get_glow_map">
+ The texture that should be used as a glow map to [i]multiply[/i] the resulting glow color according to [member glow_map_strength]. This can be used to create a "lens dirt" effect. The texture's RGB color channels are used for modulation, but the alpha channel is ignored.
+ [b]Note:[/b] The texture will be stretched to fit the screen. Therefore, it's recommended to use a texture with an aspect ratio that matches your project's base aspect ratio (typically 16:9).
+ </member>
+ <member name="glow_map_strength" type="float" setter="set_glow_map_strength" getter="get_glow_map_strength" default="0.8">
+ How strong of an impact the [member glow_map] should have on the overall glow effect. A strength of [code]0.0[/code] means the glow map has no effect on the overall glow effect. A strength of [code]1.0[/code] means the glow has a full effect on the overall glow effect (and can turn off glow entirely in specific areas of the screen if the glow map has black areas).
+ </member>
<member name="glow_mix" type="float" setter="set_glow_mix" getter="get_glow_mix" default="0.05">
</member>
<member name="glow_normalized" type="bool" setter="set_glow_normalized" getter="is_glow_normalized" default="false">
diff --git a/doc/classes/GradientTexture1D.xml b/doc/classes/GradientTexture1D.xml
index 223439956c..4730410ea9 100644
--- a/doc/classes/GradientTexture1D.xml
+++ b/doc/classes/GradientTexture1D.xml
@@ -15,7 +15,7 @@
<member name="use_hdr" type="bool" setter="set_use_hdr" getter="is_using_hdr" default="false">
If [code]true[/code], the generated texture will support high dynamic range ([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/code], the generated texture will use low dynamic range; overbright colors will be clamped ([constant Image.FORMAT_RGBA8] format).
</member>
- <member name="width" type="int" setter="set_width" getter="get_width" default="2048">
+ <member name="width" type="int" setter="set_width" getter="get_width" default="256">
The number of color samples that will be obtained from the [Gradient].
</member>
</members>
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index 423e58f5c6..b5468755c1 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -141,10 +141,10 @@
Returns the strength of the joypad vibration: x is the strength of the weak motor, and y is the strength of the strong motor.
</description>
</method>
- <method name="get_last_mouse_velocity" qualifiers="const">
+ <method name="get_last_mouse_velocity">
<return type="Vector2" />
<description>
- Returns the mouse velocity for the last time the cursor was moved, and this until the next frame where the mouse moves. This means that even if the mouse is not moving, this function will still return the value of the last motion.
+ Returns the last mouse velocity. To provide a precise and jitter-free velocity, mouse velocity is only calculated every 0.1s. Therefore, mouse velocity will lag mouse movements.
</description>
</method>
<method name="get_magnetometer" qualifiers="const">
@@ -383,7 +383,8 @@
<return type="void" />
<argument index="0" name="to" type="Vector2" />
<description>
- Sets the mouse position to the specified vector.
+ Sets the mouse position to the specified vector, provided in pixels and relative to an origin at the upper left corner of the game window.
+ Mouse position is clipped to the limits of the screen resolution, or to the limits of the game window if [enum MouseMode] is set to [code]MOUSE_MODE_CONFINED[/code] or [code]MOUSE_MODE_CONFINED_HIDDEN[/code].
</description>
</method>
</methods>
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml
index 224579e8c5..0b97865770 100644
--- a/doc/classes/LineEdit.xml
+++ b/doc/classes/LineEdit.xml
@@ -233,9 +233,6 @@
[b]Note:[/b] This method is only implemented on Linux.
</member>
<member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" overrides="Control" enum="Control.CursorShape" default="1" />
- <member name="placeholder_alpha" type="float" setter="set_placeholder_alpha" getter="get_placeholder_alpha" default="0.6">
- Opacity of the [member placeholder_text]. From [code]0[/code] to [code]1[/code].
- </member>
<member name="placeholder_text" type="String" setter="set_placeholder" getter="get_placeholder" default="&quot;&quot;">
Text shown when the [LineEdit] is empty. It is [b]not[/b] the [LineEdit]'s default value (see [member text]).
</member>
@@ -397,6 +394,9 @@
<theme_item name="font_outline_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
The tint of text outline of the [LineEdit].
</theme_item>
+ <theme_item name="font_placeholder_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 0.6)">
+ Font color for [member placeholder_text].
+ </theme_item>
<theme_item name="font_selected_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
Font color for selected text (inside the selection rectangle).
</theme_item>
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index 1c44967aba..c752291588 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -54,7 +54,7 @@
<argument index="2" name="open_console" type="bool" default="false" />
<description>
Creates a new process that runs independently of Godot. It will not terminate if Godot terminates. The path specified in [code]path[/code] must exist and be executable file or macOS .app bundle. Platform path resolution will be used. The [code]arguments[/code] are used in the given order and separated by a space.
- On Windows, if [code]open_console[/code] is [code]true[/code] and process is console app, new terminal window will be opened, it's ignored on other platforms.
+ On Windows, if [code]open_console[/code] is [code]true[/code] and the process is a console app, a new terminal window will be opened. This is ignored on other platforms.
If the process creation succeeds, the method will return the new process ID, which you can use to monitor the process (and potentially terminate it with [method kill]). If the process creation fails, the method will return [code]-1[/code].
For example, running another instance of the project:
[codeblocks]
@@ -114,7 +114,7 @@
<argument index="4" name="open_console" type="bool" default="false" />
<description>
Executes a command. The file specified in [code]path[/code] must exist and be executable. Platform path resolution will be used. The [code]arguments[/code] are used in the given order and separated by a space. If an [code]output[/code] [Array] is provided, the complete shell output of the process will be appended as a single [String] element in [code]output[/code]. If [code]read_stderr[/code] is [code]true[/code], the output to the standard error stream will be included too.
- On Windows, if [code]open_console[/code] is [code]true[/code] and process is console app, new terminal window will be opened, it's ignored on other platforms.
+ On Windows, if [code]open_console[/code] is [code]true[/code] and the process is a console app, a new terminal window will be opened. This is ignored on other platforms.
If the command is successfully executed, the method will return the exit code of the command, or [code]-1[/code] if it fails.
[b]Note:[/b] The Godot thread will pause its execution until the executed command terminates. Use [Thread] to create a separate thread that will not pause the Godot thread, or use [method create_process] to create a completely independent process.
For example, to retrieve a list of the working directory's contents:
@@ -128,7 +128,7 @@
int exitCode = OS.Execute("ls", new string[] {"-l", "/tmp"}, output);
[/csharp]
[/codeblocks]
- If you wish to access a shell built-in or perform a composite command, a platform-specific shell can be invoked. For example:
+ If you wish to access a shell built-in or execute a composite command, a platform-specific shell can be invoked. For example:
[codeblocks]
[gdscript]
var output = []
diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml
index f5f6ba8b6d..bdc3a09322 100644
--- a/doc/classes/Object.xml
+++ b/doc/classes/Object.xml
@@ -490,7 +490,7 @@
<argument index="0" name="property" type="String" />
<argument index="1" name="value" type="Variant" />
<description>
- Assigns a new value to the given property. If the [code]property[/code] does not exist, nothing will happen.
+ Assigns a new value to the given property. If the [code]property[/code] does not exist or the given value's type doesn't match, nothing will happen.
[b]Note:[/b] In C#, the property name must be specified as snake_case if it is defined by a built-in Godot node. This doesn't apply to user-defined properties where you should use the same convention as in the C# source (typically PascalCase).
</description>
</method>
diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml
index 7bb67be4c4..02226df46b 100644
--- a/doc/classes/OptionButton.xml
+++ b/doc/classes/OptionButton.xml
@@ -84,7 +84,7 @@
<method name="get_selected_id" qualifiers="const">
<return type="int" />
<description>
- Returns the ID of the selected item, or [code]0[/code] if no item is selected.
+ Returns the ID of the selected item, or [code]-1[/code] if no item is selected.
</description>
</method>
<method name="get_selected_metadata" qualifiers="const">
@@ -112,6 +112,7 @@
<argument index="0" name="idx" type="int" />
<description>
Selects an item by index and makes it the current item. This will work even if the item is disabled.
+ Passing [code]-1[/code] as the index deselects any currently selected item.
</description>
</method>
<method name="set_item_disabled">
diff --git a/doc/classes/PhysicsBody2D.xml b/doc/classes/PhysicsBody2D.xml
index 43e27ea437..68f7b94551 100644
--- a/doc/classes/PhysicsBody2D.xml
+++ b/doc/classes/PhysicsBody2D.xml
@@ -25,12 +25,12 @@
</method>
<method name="move_and_collide">
<return type="KinematicCollision2D" />
- <argument index="0" name="linear_velocity" type="Vector2" />
+ <argument index="0" name="distance" type="Vector2" />
<argument index="1" name="test_only" type="bool" default="false" />
<argument index="2" name="safe_margin" type="float" default="0.08" />
<description>
- Moves the body along the vector [code]linear_velocity[/code]. This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed.
- The body will stop if it collides. Returns a [KinematicCollision2D], which contains information about the collision when stopped, or when touching another body along the motion.
+ Moves the body along the vector [code]distance[/code]. In order to be frame rate independent in [method Node._physics_process] or [method Node._process], [code]distance[/code] should be computed using [code]delta[/code].
+ Returns a [KinematicCollision2D], which contains information about the collision when stopped, or when touching another body along the motion.
If [code]test_only[/code] is [code]true[/code], the body does not move but the would-be collision information is given.
[code]safe_margin[/code] is the extra margin used for collision recovery (see [member CharacterBody2D.collision/safe_margin] for more details).
</description>
@@ -45,12 +45,12 @@
<method name="test_move">
<return type="bool" />
<argument index="0" name="from" type="Transform2D" />
- <argument index="1" name="linear_velocity" type="Vector2" />
+ <argument index="1" name="distance" type="Vector2" />
<argument index="2" name="collision" type="KinematicCollision2D" default="null" />
<argument index="3" name="safe_margin" type="float" default="0.08" />
<description>
- Checks for collisions without moving the body. This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed.
- Virtually sets the node's position, scale and rotation to that of the given [Transform2D], then tries to move the body along the vector [code]linear_velocity[/code]. Returns [code]true[/code] if a collision would stop the body from moving along the whole path.
+ Checks for collisions without moving the body. In order to be frame rate independent in [method Node._physics_process] or [method Node._process], [code]distance[/code] should be computed using [code]delta[/code].
+ Virtually sets the node's position, scale and rotation to that of the given [Transform2D], then tries to move the body along the vector [code]distance[/code]. Returns [code]true[/code] if a collision would stop the body from moving along the whole path.
[code]collision[/code] is an optional object of type [KinematicCollision2D], which contains additional information about the collision when stopped, or when touching another body along the motion.
[code]safe_margin[/code] is the extra margin used for collision recovery (see [member CharacterBody2D.collision/safe_margin] for more details).
</description>
diff --git a/doc/classes/PhysicsBody3D.xml b/doc/classes/PhysicsBody3D.xml
index 3c52850eec..4ea93d9f54 100644
--- a/doc/classes/PhysicsBody3D.xml
+++ b/doc/classes/PhysicsBody3D.xml
@@ -32,12 +32,12 @@
</method>
<method name="move_and_collide">
<return type="KinematicCollision3D" />
- <argument index="0" name="linear_velocity" type="Vector3" />
+ <argument index="0" name="distance" type="Vector3" />
<argument index="1" name="test_only" type="bool" default="false" />
<argument index="2" name="safe_margin" type="float" default="0.001" />
<argument index="3" name="max_collisions" type="int" default="1" />
<description>
- Moves the body along the vector [code]linear_velocity[/code]. This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed.
+ Moves the body along the vector [code]distance[/code]. In order to be frame rate independent in [method Node._physics_process] or [method Node._process], [code]distance[/code] should be computed using [code]delta[/code].
The body will stop if it collides. Returns a [KinematicCollision3D], which contains information about the collision when stopped, or when touching another body along the motion.
If [code]test_only[/code] is [code]true[/code], the body does not move but the would-be collision information is given.
[code]safe_margin[/code] is the extra margin used for collision recovery (see [member CharacterBody3D.collision/safe_margin] for more details).
@@ -62,13 +62,13 @@
<method name="test_move">
<return type="bool" />
<argument index="0" name="from" type="Transform3D" />
- <argument index="1" name="linear_velocity" type="Vector3" />
+ <argument index="1" name="distance" type="Vector3" />
<argument index="2" name="collision" type="KinematicCollision3D" default="null" />
<argument index="3" name="safe_margin" type="float" default="0.001" />
<argument index="4" name="max_collisions" type="int" default="1" />
<description>
- Checks for collisions without moving the body. This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed.
- Virtually sets the node's position, scale and rotation to that of the given [Transform3D], then tries to move the body along the vector [code]linear_velocity[/code]. Returns [code]true[/code] if a collision would stop the body from moving along the whole path.
+ Checks for collisions without moving the body. In order to be frame rate independent in [method Node._physics_process] or [method Node._process], [code]distance[/code] should be computed using [code]delta[/code].
+ Virtually sets the node's position, scale and rotation to that of the given [Transform3D], then tries to move the body along the vector [code]distance[/code]. Returns [code]true[/code] if a collision would stop the body from moving along the whole path.
[code]collision[/code] is an optional object of type [KinematicCollision3D], which contains additional information about the collision when stopped, or when touching another body along the motion.
[code]safe_margin[/code] is the extra margin used for collision recovery (see [member CharacterBody3D.collision/safe_margin] for more details).
[code]max_collisions[/code] allows to retrieve more than one collision result.
diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml
index 108c674ef7..eb1b0aada7 100644
--- a/doc/classes/PopupMenu.xml
+++ b/doc/classes/PopupMenu.xml
@@ -331,6 +331,13 @@
[b]Note:[/b] The indices of items after the removed item will be shifted by one.
</description>
</method>
+ <method name="set_current_index">
+ <return type="void" />
+ <argument index="0" name="index" type="int" />
+ <description>
+ Sets the currently focused item as the given [code]index[/code].
+ </description>
+ </method>
<method name="set_item_accelerator">
<return type="void" />
<argument index="0" name="index" type="int" />
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index a92afb7ea7..dc40d2fd1b 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -1329,10 +1329,10 @@
The policy to use for unhandled Mono (C#) exceptions. The default "Terminate Application" exits the project as soon as an unhandled exception is thrown. "Log Error" logs an error message to the console instead, and will not interrupt the project execution when an unhandled exception is thrown.
[b]Note:[/b] The unhandled exception policy is always set to "Log Error" in the editor, which also includes C# [code]tool[/code] scripts running within the editor as well as editor plugin code.
</member>
- <member name="navigation/2d/default_cell_size" type="int" setter="" getter="" default="10">
+ <member name="navigation/2d/default_cell_size" type="int" setter="" getter="" default="1">
Default cell size for 2D navigation maps. See [method NavigationServer2D.map_set_cell_size].
</member>
- <member name="navigation/2d/default_edge_connection_margin" type="int" setter="" getter="" default="5">
+ <member name="navigation/2d/default_edge_connection_margin" type="int" setter="" getter="" default="1">
Default edge connection margin for 2D navigation maps. See [method NavigationServer2D.map_set_edge_connection_margin].
</member>
<member name="navigation/3d/default_cell_size" type="float" setter="" getter="" default="0.3">
@@ -1412,8 +1412,8 @@
Sets which physics engine to use for 2D physics.
"DEFAULT" and "GodotPhysics2D" are the same, as there is currently no alternative 2D physics server implemented.
</member>
- <member name="physics/2d/run_on_thread" type="bool" setter="" getter="" default="false">
- Sets whether 2D physics is run on the main thread or a separate one. Running the server on a thread increases performance, but restricts API access to only physics process.
+ <member name="physics/2d/run_on_separate_thread" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], the 2D physics server runs on a separate thread, making better use of multi-core CPUs. If [code]false[/code], the 2D physics server runs on the main thread. Running the physics server on a separate thread can increase performance, but restricts API access to only physics process.
</member>
<member name="physics/2d/sleep_threshold_angular" type="float" setter="" getter="" default="0.139626">
Threshold angular velocity under which a 2D physics body will be considered inactive. See [constant PhysicsServer2D.SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD].
@@ -1484,8 +1484,8 @@
Sets which physics engine to use for 3D physics.
"DEFAULT" is currently the [url=https://bulletphysics.org]Bullet[/url] physics engine. The "GodotPhysics3D" engine is still supported as an alternative.
</member>
- <member name="physics/3d/run_on_thread" type="bool" setter="" getter="" default="false">
- Sets whether 3D physics is run on the main thread or a separate one. Running the server on a thread increases performance, but restricts API access to only physics process.
+ <member name="physics/3d/run_on_separate_thread" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], the 3D physics server runs on a separate thread, making better use of multi-core CPUs. If [code]false[/code], the 3D physics server runs on the main thread. Running the physics server on a separate thread can increase performance, but restricts API access to only physics process.
</member>
<member name="physics/3d/sleep_threshold_angular" type="float" setter="" getter="" default="0.139626">
Threshold angular velocity under which a 3D physics body will be considered inactive. See [constant PhysicsServer3D.SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD].
diff --git a/doc/classes/RayCast2D.xml b/doc/classes/RayCast2D.xml
index fe2885378a..27e02d0ee5 100644
--- a/doc/classes/RayCast2D.xml
+++ b/doc/classes/RayCast2D.xml
@@ -16,9 +16,9 @@
<methods>
<method name="add_exception">
<return type="void" />
- <argument index="0" name="node" type="Object" />
+ <argument index="0" name="node" type="CollisionObject2D" />
<description>
- Adds a collision exception so the ray does not report collisions with the specified node.
+ Adds a collision exception so the ray does not report collisions with the specified [CollisionObject2D] node.
</description>
</method>
<method name="add_exception_rid">
@@ -81,9 +81,9 @@
</method>
<method name="remove_exception">
<return type="void" />
- <argument index="0" name="node" type="Object" />
+ <argument index="0" name="node" type="CollisionObject2D" />
<description>
- Removes a collision exception so the ray does report collisions with the specified node.
+ Removes a collision exception so the ray does report collisions with the specified [CollisionObject2D] node.
</description>
</method>
<method name="remove_exception_rid">
diff --git a/doc/classes/RayCast3D.xml b/doc/classes/RayCast3D.xml
index 8973857ace..6be5861b84 100644
--- a/doc/classes/RayCast3D.xml
+++ b/doc/classes/RayCast3D.xml
@@ -17,9 +17,9 @@
<methods>
<method name="add_exception">
<return type="void" />
- <argument index="0" name="node" type="Object" />
+ <argument index="0" name="node" type="CollisionObject3D" />
<description>
- Adds a collision exception so the ray does not report collisions with the specified node.
+ Adds a collision exception so the ray does not report collisions with the specified [CollisionObject3D] node.
</description>
</method>
<method name="add_exception_rid">
@@ -82,9 +82,9 @@
</method>
<method name="remove_exception">
<return type="void" />
- <argument index="0" name="node" type="Object" />
+ <argument index="0" name="node" type="CollisionObject3D" />
<description>
- Removes a collision exception so the ray does report collisions with the specified node.
+ Removes a collision exception so the ray does report collisions with the specified [CollisionObject3D] node.
</description>
</method>
<method name="remove_exception_rid">
diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml
index 65d1654c21..6285b1d155 100644
--- a/doc/classes/Rect2.xml
+++ b/doc/classes/Rect2.xml
@@ -93,7 +93,7 @@
<method name="get_area" qualifiers="const">
<return type="float" />
<description>
- Returns the area of the [Rect2].
+ Returns the area of the [Rect2]. See also [method has_no_area].
</description>
</method>
<method name="get_center" qualifiers="const">
@@ -130,7 +130,8 @@
<method name="has_no_area" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the [Rect2] is flat or empty.
+ Returns [code]true[/code] if the [Rect2] is flat or empty, [code]false[/code] otherwise. See also [method get_area].
+ [b]Note:[/b] If the [Rect2] has a negative size and is not flat or empty, [method has_no_area] will return [code]true[/code].
</description>
</method>
<method name="has_point" qualifiers="const">
diff --git a/doc/classes/Rect2i.xml b/doc/classes/Rect2i.xml
index 5909784135..a542bad82b 100644
--- a/doc/classes/Rect2i.xml
+++ b/doc/classes/Rect2i.xml
@@ -70,7 +70,7 @@
<return type="Rect2i" />
<argument index="0" name="to" type="Vector2i" />
<description>
- Returns a copy of this [Rect2i] expanded to include a given point.
+ Returns a copy of this [Rect2i] expanded so that the borders align with the given point.
[codeblocks]
[gdscript]
# position (-3, 2), size (1, 1)
@@ -90,7 +90,7 @@
<method name="get_area" qualifiers="const">
<return type="int" />
<description>
- Returns the area of the [Rect2i].
+ Returns the area of the [Rect2i]. See also [method has_no_area].
</description>
</method>
<method name="get_center" qualifiers="const">
@@ -128,7 +128,8 @@
<method name="has_no_area" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the [Rect2i] is flat or empty.
+ Returns [code]true[/code] if the [Rect2i] is flat or empty, [code]false[/code] otherwise. See also [method get_area].
+ [b]Note:[/b] If the [Rect2i] has a negative size and is not flat or empty, [method has_no_area] will return [code]true[/code].
</description>
</method>
<method name="has_point" qualifiers="const">
diff --git a/doc/classes/ReflectionProbe.xml b/doc/classes/ReflectionProbe.xml
index 5d207c0db7..63f436fa03 100644
--- a/doc/classes/ReflectionProbe.xml
+++ b/doc/classes/ReflectionProbe.xml
@@ -43,6 +43,7 @@
</member>
<member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" default="0.0">
The maximum distance away from the [ReflectionProbe] an object can be before it is culled. Decrease this to improve performance, especially when using the [constant UPDATE_ALWAYS] [member update_mode].
+ [b]Note:[/b] The maximum reflection distance is always at least equal to the [member extents]. This means that decreasing [member max_distance] will not always cull objects from reflections, especially if the reflection probe's [member extents] are already large.
</member>
<member name="mesh_lod_threshold" type="float" setter="set_mesh_lod_threshold" getter="get_mesh_lod_threshold" default="1.0">
The automatic LOD bias to use for meshes rendered within the [ReflectionProbe] (this is analog to [member Viewport.mesh_lod_threshold]). Higher values will use less detailed versions of meshes that have LOD variations generated. If set to [code]0.0[/code], automatic LOD is disabled. Increase [member mesh_lod_threshold] to improve performance at the cost of geometry detail, especially when using the [constant UPDATE_ALWAYS] [member update_mode].
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index ff370bd953..446db40dd8 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -994,6 +994,8 @@
<argument index="8" name="hdr_bleed_threshold" type="float" />
<argument index="9" name="hdr_bleed_scale" type="float" />
<argument index="10" name="hdr_luminance_cap" type="float" />
+ <argument index="11" name="glow_map_strength" type="float" />
+ <argument index="12" name="glow_map" type="RID" />
<description>
</description>
</method>
diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml
index 6f5135459f..95dffd3e28 100644
--- a/doc/classes/RichTextLabel.xml
+++ b/doc/classes/RichTextLabel.xml
@@ -372,6 +372,9 @@
</method>
</methods>
<members>
+ <member name="autowrap_mode" type="int" setter="set_autowrap_mode" getter="get_autowrap_mode" enum="RichTextLabel.AutowrapMode" default="3">
+ If set to something other than [constant AUTOWRAP_OFF], the text gets wrapped inside the node's bounding rectangle. To see how each mode behaves, see [enum AutowrapMode].
+ </member>
<member name="bbcode_enabled" type="bool" setter="set_use_bbcode" getter="is_using_bbcode" default="false">
If [code]true[/code], the label uses BBCode formatting.
</member>
@@ -454,6 +457,18 @@
</signal>
</signals>
<constants>
+ <constant name="AUTOWRAP_OFF" value="0" enum="AutowrapMode">
+ Autowrap is disabled.
+ </constant>
+ <constant name="AUTOWRAP_ARBITRARY" value="1" enum="AutowrapMode">
+ Wraps the text inside the node's bounding rectangle by allowing to break lines at arbitrary positions, which is useful when very limited space is available.
+ </constant>
+ <constant name="AUTOWRAP_WORD" value="2" enum="AutowrapMode">
+ Wraps the text inside the node's bounding rectangle by soft-breaking between words.
+ </constant>
+ <constant name="AUTOWRAP_WORD_SMART" value="3" enum="AutowrapMode">
+ Behaves similarly to [constant AUTOWRAP_WORD], but force-breaks a word if that single word does not fit in one line.
+ </constant>
<constant name="LIST_NUMBERS" value="0" enum="ListType">
Each list item has a number marker.
</constant>
diff --git a/doc/classes/ShapeCast2D.xml b/doc/classes/ShapeCast2D.xml
index 74ebafe069..7229d6f72a 100644
--- a/doc/classes/ShapeCast2D.xml
+++ b/doc/classes/ShapeCast2D.xml
@@ -14,9 +14,9 @@
<methods>
<method name="add_exception">
<return type="void" />
- <argument index="0" name="node" type="Object" />
+ <argument index="0" name="node" type="CollisionObject2D" />
<description>
- Adds a collision exception so the shape does not report collisions with the specified node.
+ Adds a collision exception so the shape does not report collisions with the specified [CollisionObject2D] node.
</description>
</method>
<method name="add_exception_rid">
@@ -101,9 +101,9 @@
</method>
<method name="remove_exception">
<return type="void" />
- <argument index="0" name="node" type="Object" />
+ <argument index="0" name="node" type="CollisionObject2D" />
<description>
- Removes a collision exception so the shape does report collisions with the specified node.
+ Removes a collision exception so the shape does report collisions with the specified [CollisionObject2D] node.
</description>
</method>
<method name="remove_exception_rid">
diff --git a/doc/classes/StreamPeerBuffer.xml b/doc/classes/StreamPeerBuffer.xml
index 989864760f..e335987ff5 100644
--- a/doc/classes/StreamPeerBuffer.xml
+++ b/doc/classes/StreamPeerBuffer.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="StreamPeerBuffer" inherits="StreamPeer" version="4.0">
<brief_description>
+ Data buffer stream peer.
</brief_description>
<description>
+ Data buffer stream peer that uses a byte array as the stream. This object can be used to handle binary data from network sessions. To handle binary data stored in files, [File] can be used directly.
+ A [StreamPeerBuffer] object keeps an internal cursor which is the offset in bytes to the start of the buffer. Get and put operations are performed at the cursor position and will move the cursor accordingly.
</description>
<tutorials>
</tutorials>
@@ -10,38 +13,45 @@
<method name="clear">
<return type="void" />
<description>
+ Clears the [member data_array] and resets the cursor.
</description>
</method>
<method name="duplicate" qualifiers="const">
<return type="StreamPeerBuffer" />
<description>
+ Returns a new [StreamPeerBuffer] with the same [member data_array] content.
</description>
</method>
<method name="get_position" qualifiers="const">
<return type="int" />
<description>
+ Returns the current cursor position.
</description>
</method>
<method name="get_size" qualifiers="const">
<return type="int" />
<description>
+ Returns the size of [member data_array].
</description>
</method>
<method name="resize">
<return type="void" />
<argument index="0" name="size" type="int" />
<description>
+ Resizes the [member data_array]. This [i]doesn't[/i] update the cursor.
</description>
</method>
<method name="seek">
<return type="void" />
<argument index="0" name="position" type="int" />
<description>
+ Moves the cursor to the specified position. [code]position[/code] must be a valid index of [member data_array].
</description>
</method>
</methods>
<members>
<member name="data_array" type="PackedByteArray" setter="set_data_array" getter="get_data_array" default="PackedByteArray()">
+ The underlying data buffer. Setting this value resets the cursor.
</member>
</members>
</class>
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index c8e835f0f1..1a9b9ccdcc 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -285,7 +285,7 @@
Returns [code]true[/code] if this string is a subsequence of the given string.
</description>
</method>
- <method name="is_subsequence_ofi" qualifiers="const">
+ <method name="is_subsequence_ofn" qualifiers="const">
<return type="bool" />
<argument index="0" name="text" type="String" />
<description>
diff --git a/doc/classes/TabBar.xml b/doc/classes/TabBar.xml
index 59a4743d80..c286629395 100644
--- a/doc/classes/TabBar.xml
+++ b/doc/classes/TabBar.xml
@@ -43,10 +43,11 @@
Returns the previously active tab index.
</description>
</method>
- <method name="get_select_with_rmb" qualifiers="const">
- <return type="bool" />
+ <method name="get_tab_button_icon" qualifiers="const">
+ <return type="Texture2D" />
+ <argument index="0" name="tab_idx" type="int" />
<description>
- Returns [code]true[/code] if select with right mouse button is enabled.
+ Returns the [Texture2D] for the right button of the tab at index [code]tab_idx[/code] or [code]null[/code] if the button has no [Texture2D].
</description>
</method>
<method name="get_tab_icon" qualifiers="const">
@@ -111,6 +112,13 @@
Returns [code]true[/code] if the tab at index [code]tab_idx[/code] is disabled.
</description>
</method>
+ <method name="is_tab_hidden" qualifiers="const">
+ <return type="bool" />
+ <argument index="0" name="tab_idx" type="int" />
+ <description>
+ Returns [code]true[/code] if the tab at index [code]tab_idx[/code] is hidden.
+ </description>
+ </method>
<method name="move_tab">
<return type="void" />
<argument index="0" name="from" type="int" />
@@ -126,11 +134,12 @@
Removes the tab at index [code]tab_idx[/code].
</description>
</method>
- <method name="set_select_with_rmb">
+ <method name="set_tab_button_icon">
<return type="void" />
- <argument index="0" name="enabled" type="bool" />
+ <argument index="0" name="tab_idx" type="int" />
+ <argument index="1" name="icon" type="Texture2D" />
<description>
- If [code]true[/code], enables selecting a tab with the right mouse button.
+ Sets an [code]icon[/code] for the button of the tab at index [code]tab_idx[/code] (located to the right, before the close button), making it visible and clickable (See [signal tab_button_pressed]). Giving it a [code]null[/code] value will hide the button.
</description>
</method>
<method name="set_tab_disabled">
@@ -141,6 +150,14 @@
If [code]disabled[/code] is [code]true[/code], disables the tab at index [code]tab_idx[/code], making it non-interactable.
</description>
</method>
+ <method name="set_tab_hidden">
+ <return type="void" />
+ <argument index="0" name="tab_idx" type="int" />
+ <argument index="1" name="hidden" type="bool" />
+ <description>
+ If [code]hidden[/code] is [code]true[/code], hides the tab at index [code]tab_idx[/code], making it disappear from the tab area.
+ </description>
+ </method>
<method name="set_tab_icon">
<return type="void" />
<argument index="0" name="tab_idx" type="int" />
@@ -200,10 +217,17 @@
<member name="drag_to_rearrange_enabled" type="bool" setter="set_drag_to_rearrange_enabled" getter="get_drag_to_rearrange_enabled" default="false">
If [code]true[/code], tabs can be rearranged with mouse drag.
</member>
+ <member name="scroll_to_selected" type="bool" setter="set_scroll_to_selected" getter="get_scroll_to_selected" default="true">
+ If [code]true[/code], the tab offset will be changed to keep the the currently selected tab visible.
+ </member>
<member name="scrolling_enabled" type="bool" setter="set_scrolling_enabled" getter="get_scrolling_enabled" default="true">
if [code]true[/code], the mouse's scroll wheel can be used to navigate the scroll view.
</member>
+ <member name="select_with_rmb" type="bool" setter="set_select_with_rmb" getter="get_select_with_rmb" default="false">
+ If [code]true[/code], enables selecting a tab with the right mouse button.
+ </member>
<member name="tab_alignment" type="int" setter="set_tab_alignment" getter="get_tab_alignment" enum="TabBar.AlignmentMode" default="1">
+ Sets the position at which tabs will be placed. See [enum AlignmentMode] for details.
</member>
<member name="tab_close_display_policy" type="int" setter="set_tab_close_display_policy" getter="get_tab_close_display_policy" enum="TabBar.CloseButtonDisplayPolicy" default="0">
Sets when the close button will appear on the tabs. See [enum CloseButtonDisplayPolicy] for details.
@@ -219,6 +243,12 @@
Emitted when the active tab is rearranged via mouse drag. See [member drag_to_rearrange_enabled].
</description>
</signal>
+ <signal name="tab_button_pressed">
+ <argument index="0" name="tab" type="int" />
+ <description>
+ Emitted when a tab's right button is pressed. See [method set_tab_button_icon].
+ </description>
+ </signal>
<signal name="tab_changed">
<argument index="0" name="tab" type="int" />
<description>
@@ -255,18 +285,28 @@
<signal name="tab_rmb_clicked">
<argument index="0" name="tab" type="int" />
<description>
- Emitted when a tab is right-clicked.
+ Emitted when a tab is right-clicked. [member select_with_rmb] must be enabled.
+ </description>
+ </signal>
+ <signal name="tab_selected">
+ <argument index="0" name="tab" type="int" />
+ <description>
+ Emitted when a tab is selected via click or script, even if it is the current tab.
</description>
</signal>
</signals>
<constants>
<constant name="ALIGNMENT_LEFT" value="0" enum="AlignmentMode">
+ Places tabs to the left.
</constant>
<constant name="ALIGNMENT_CENTER" value="1" enum="AlignmentMode">
+ Places tabs in the middle.
</constant>
<constant name="ALIGNMENT_RIGHT" value="2" enum="AlignmentMode">
+ Places tabs to the right.
</constant>
<constant name="ALIGNMENT_MAX" value="3" enum="AlignmentMode">
+ Represents the size of the [enum AlignmentMode] enum.
</constant>
<constant name="CLOSE_BUTTON_SHOW_NEVER" value="0" enum="CloseButtonDisplayPolicy">
Never show the close buttons.
@@ -321,11 +361,11 @@
<theme_item name="increment_highlight" data_type="icon" type="Texture2D">
Icon for the right arrow button that appears when there are too many tabs to fit in the container width. Used when the button is being hovered with the cursor.
</theme_item>
- <theme_item name="close_bg_highlight" data_type="style" type="StyleBox">
- Background of the close button when it's being hovered with the cursor.
+ <theme_item name="button_highlight" data_type="style" type="StyleBox">
+ Background of the tab and close buttons when they're being hovered with the cursor.
</theme_item>
- <theme_item name="close_bg_pressed" data_type="style" type="StyleBox">
- Background of the close button when it's being pressed.
+ <theme_item name="button_pressed" data_type="style" type="StyleBox">
+ Background of the tab and close buttons when it's being pressed.
</theme_item>
<theme_item name="tab_disabled" data_type="style" type="StyleBox">
The style of disabled tabs.
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 6d602d58ee..6b9eb6efc3 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -992,9 +992,6 @@
<member name="override_selected_font_color" type="bool" setter="set_override_selected_font_color" getter="is_overriding_selected_font_color" default="false">
If [code]true[/code], custom [code]font_selected_color[/code] will be used for selected text.
</member>
- <member name="placeholder_alpha" type="float" setter="set_placeholder_alpha" getter="get_placeholder_alpha" default="0.6">
- Opacity of the [member placeholder_text]. From [code]0[/code] to [code]1[/code].
- </member>
<member name="placeholder_text" type="String" setter="set_placeholder" getter="get_placeholder" default="&quot;&quot;">
Text shown when the [TextEdit] is empty. It is [b]not[/b] the [TextEdit]'s default value (see [member text]).
</member>
@@ -1237,6 +1234,9 @@
<theme_item name="font_outline_color" data_type="color" type="Color" default="Color(1, 1, 1, 1)">
The tint of text outline of the [TextEdit].
</theme_item>
+ <theme_item name="font_placeholder_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 0.6)">
+ Font color for [member placeholder_text].
+ </theme_item>
<theme_item name="font_readonly_color" data_type="color" type="Color" default="Color(0.875, 0.875, 0.875, 0.5)">
Sets the font [Color] when [member editable] is disabled.
</theme_item>
diff --git a/doc/classes/TextLine.xml b/doc/classes/TextLine.xml
index bf1abf86ae..7bfc7eed7e 100644
--- a/doc/classes/TextLine.xml
+++ b/doc/classes/TextLine.xml
@@ -26,6 +26,7 @@
<argument index="2" name="size" type="int" />
<argument index="3" name="opentype_features" type="Dictionary" default="{}" />
<argument index="4" name="language" type="String" default="&quot;&quot;" />
+ <argument index="5" name="meta" type="Variant" default="null" />
<description>
Adds text span and font to draw it.
</description>
diff --git a/doc/classes/TextParagraph.xml b/doc/classes/TextParagraph.xml
index 3d3c0dd6ff..acf3dcd43b 100644
--- a/doc/classes/TextParagraph.xml
+++ b/doc/classes/TextParagraph.xml
@@ -26,6 +26,7 @@
<argument index="2" name="size" type="int" />
<argument index="3" name="opentype_features" type="Dictionary" default="{}" />
<argument index="4" name="language" type="String" default="&quot;&quot;" />
+ <argument index="5" name="meta" type="Variant" default="null" />
<description>
Adds text span and font to draw it.
</description>
diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml
index 61024ef0c8..9025e4ff2a 100644
--- a/doc/classes/TextServer.xml
+++ b/doc/classes/TextServer.xml
@@ -896,6 +896,32 @@
[b]Note:[/b] This function is used by during project export, to include TextServer database.
</description>
</method>
+ <method name="shaped_get_span_count" qualifiers="const">
+ <return type="int" />
+ <argument index="0" name="shaped" type="RID" />
+ <description>
+ Returns number of text spans added using [method shaped_text_add_string] or [method shaped_text_add_object].
+ </description>
+ </method>
+ <method name="shaped_get_span_meta" qualifiers="const">
+ <return type="Variant" />
+ <argument index="0" name="shaped" type="RID" />
+ <argument index="1" name="index" type="int" />
+ <description>
+ Returns text span metadata.
+ </description>
+ </method>
+ <method name="shaped_set_span_update_font">
+ <return type="void" />
+ <argument index="0" name="shaped" type="RID" />
+ <argument index="1" name="index" type="int" />
+ <argument index="2" name="fonts" type="Array" />
+ <argument index="3" name="size" type="int" />
+ <argument index="4" name="opentype_features" type="Dictionary" default="{}" />
+ <description>
+ Changes text span font, font size and OpenType features, without changing the text.
+ </description>
+ </method>
<method name="shaped_text_add_object">
<return type="bool" />
<argument index="0" name="shaped" type="RID" />
@@ -915,6 +941,7 @@
<argument index="3" name="size" type="int" />
<argument index="4" name="opentype_features" type="Dictionary" default="{}" />
<argument index="5" name="language" type="String" default="&quot;&quot;" />
+ <argument index="6" name="meta" type="Variant" default="null" />
<description>
Adds text span and font to draw it to the text buffer.
</description>
diff --git a/doc/classes/TextServerExtension.xml b/doc/classes/TextServerExtension.xml
index 8b4825026d..b500bd5658 100644
--- a/doc/classes/TextServerExtension.xml
+++ b/doc/classes/TextServerExtension.xml
@@ -202,7 +202,7 @@
</description>
</method>
<method name="_font_get_hinting" qualifiers="virtual const">
- <return type="int" />
+ <return type="int" enum="TextServer.Hinting" />
<argument index="0" name="font_rid" type="RID" />
<description>
Returns the font hinting mode. Used by dynamic fonts only.
@@ -904,6 +904,32 @@
[b]Note:[/b] This function is used by during project export, to include TextServer database.
</description>
</method>
+ <method name="_shaped_get_span_count" qualifiers="virtual const">
+ <return type="int" />
+ <argument index="0" name="shaped" type="RID" />
+ <description>
+ Returns number of text spans added using [method _shaped_text_add_string] or [method _shaped_text_add_object].
+ </description>
+ </method>
+ <method name="_shaped_get_span_meta" qualifiers="virtual const">
+ <return type="Variant" />
+ <argument index="0" name="shaped" type="RID" />
+ <argument index="1" name="index" type="int" />
+ <description>
+ Returns text span metadata.
+ </description>
+ </method>
+ <method name="_shaped_set_span_update_font" qualifiers="virtual">
+ <return type="void" />
+ <argument index="0" name="shaped" type="RID" />
+ <argument index="1" name="index" type="int" />
+ <argument index="2" name="fonts" type="Array" />
+ <argument index="3" name="size" type="int" />
+ <argument index="4" name="opentype_features" type="Dictionary" />
+ <description>
+ Changes text span font, font size and OpenType features, without changing the text.
+ </description>
+ </method>
<method name="_shaped_text_add_object" qualifiers="virtual">
<return type="bool" />
<argument index="0" name="shaped" type="RID" />
@@ -923,6 +949,7 @@
<argument index="3" name="size" type="int" />
<argument index="4" name="opentype_features" type="Dictionary" />
<argument index="5" name="language" type="String" />
+ <argument index="6" name="meta" type="Variant" />
<description>
Adds text span and font to draw it to the text buffer.
</description>
@@ -1001,7 +1028,7 @@
</description>
</method>
<method name="_shaped_text_get_direction" qualifiers="virtual const">
- <return type="int" />
+ <return type="int" enum="TextServer.Direction" />
<argument index="0" name="shaped" type="RID" />
<description>
Returns direction of the text.
@@ -1024,9 +1051,8 @@
</description>
</method>
<method name="_shaped_text_get_ellipsis_glyphs" qualifiers="virtual const">
- <return type="void" />
+ <return type="Glyph*" />
<argument index="0" name="shaped" type="RID" />
- <argument index="1" name="r_glyphs" type="void*" />
<description>
Returns array of the glyphs in the ellipsis.
</description>
@@ -1046,9 +1072,8 @@
</description>
</method>
<method name="_shaped_text_get_glyphs" qualifiers="virtual const">
- <return type="void" />
+ <return type="Glyph*" />
<argument index="0" name="shaped" type="RID" />
- <argument index="1" name="r_glyphs" type="void*" />
<description>
Copies text glyphs in the visual order, into preallocated array of the size returned by [method _shaped_text_get_glyph_count].
</description>
@@ -1062,7 +1087,7 @@
</description>
</method>
<method name="_shaped_text_get_inferred_direction" qualifiers="virtual const">
- <return type="int" />
+ <return type="int" enum="TextServer.Direction" />
<argument index="0" name="shaped" type="RID" />
<description>
Returns direction of the text, inferred by the BiDi algorithm.
@@ -1105,7 +1130,7 @@
</description>
</method>
<method name="_shaped_text_get_orientation" qualifiers="virtual const">
- <return type="int" />
+ <return type="int" enum="TextServer.Orientation" />
<argument index="0" name="shaped" type="RID" />
<description>
Returns text orientation.
@@ -1310,9 +1335,8 @@
</description>
</method>
<method name="_shaped_text_sort_logical" qualifiers="virtual">
- <return type="void" />
+ <return type="Glyph*" />
<argument index="0" name="shaped" type="RID" />
- <argument index="1" name="r_glyphs" type="void*" />
<description>
Copies text glyphs in the logical order, into preallocated array of the size returned by [method _shaped_text_get_glyph_count].
</description>
diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml
index 07b9543823..80a6458cec 100644
--- a/doc/classes/TileMap.xml
+++ b/doc/classes/TileMap.xml
@@ -218,7 +218,7 @@
<return type="void" />
<argument index="0" name="layer" type="int" />
<description>
- Moves the layer at index [code]layer_index[/code] to the given position [code]to_position[/code] in the array.
+ Removes the layer at index [code]layer[/code].
</description>
</method>
<method name="set_cell">
diff --git a/doc/classes/TileSetAtlasSource.xml b/doc/classes/TileSetAtlasSource.xml
index 6580c6bd4c..f984d33098 100644
--- a/doc/classes/TileSetAtlasSource.xml
+++ b/doc/classes/TileSetAtlasSource.xml
@@ -111,7 +111,7 @@
</description>
</method>
<method name="get_tile_data" qualifiers="const">
- <return type="Object" />
+ <return type="TileData" />
<argument index="0" name="atlas_coords" type="Vector2i" />
<argument index="1" name="alternative_tile" type="int" />
<description>
diff --git a/doc/classes/Transform3D.xml b/doc/classes/Transform3D.xml
index e679a8cfeb..ccecaaa6ac 100644
--- a/doc/classes/Transform3D.xml
+++ b/doc/classes/Transform3D.xml
@@ -106,6 +106,14 @@
Scales basis and origin of the transform by the given scale factor, using matrix multiplication.
</description>
</method>
+ <method name="sphere_interpolate_with" qualifiers="const">
+ <return type="Transform3D" />
+ <argument index="0" name="xform" type="Transform3D" />
+ <argument index="1" name="weight" type="float" />
+ <description>
+ Returns a transform spherically interpolated between this transform and another by a given [code]weight[/code] (on the range of 0.0 to 1.0).
+ </description>
+ </method>
<method name="translated" qualifiers="const">
<return type="Transform3D" />
<argument index="0" name="offset" type="Vector3" />
diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml
index 106bcf9d37..766c740a2c 100644
--- a/doc/classes/Tree.xml
+++ b/doc/classes/Tree.xml
@@ -50,10 +50,10 @@
</method>
<method name="create_item">
<return type="TreeItem" />
- <argument index="0" name="parent" type="Object" default="null" />
+ <argument index="0" name="parent" type="TreeItem" default="null" />
<argument index="1" name="idx" type="int" default="-1" />
<description>
- Creates an item in the tree and adds it as a child of [code]parent[/code].
+ Creates an item in the tree and adds it as a child of [code]parent[/code], which can be either a valid [TreeItem] or [code]null[/code].
If [code]parent[/code] is [code]null[/code], the root item will be the parent, or the new item will be the root itself if the tree is empty.
The new item will be the [code]idx[/code]th child of parent, or it will be the last child if there are not enough siblings.
</description>
@@ -170,10 +170,10 @@
</method>
<method name="get_item_area_rect" qualifiers="const">
<return type="Rect2" />
- <argument index="0" name="item" type="Object" />
+ <argument index="0" name="item" type="TreeItem" />
<argument index="1" name="column" type="int" default="-1" />
<description>
- Returns the rectangle area for the specified item. If [code]column[/code] is specified, only get the position and size of that column, otherwise get the rectangle containing all columns.
+ Returns the rectangle area for the specified [TreeItem]. If [code]column[/code] is specified, only get the position and size of that column, otherwise get the rectangle containing all columns.
</description>
</method>
<method name="get_item_at_position" qualifiers="const">
@@ -185,9 +185,9 @@
</method>
<method name="get_next_selected">
<return type="TreeItem" />
- <argument index="0" name="from" type="Object" />
+ <argument index="0" name="from" type="TreeItem" />
<description>
- Returns the next selected item after the given one, or [code]null[/code] if the end is reached.
+ Returns the next selected [TreeItem] after the given one, or [code]null[/code] if the end is reached.
If [code]from[/code] is [code]null[/code], this returns the first selected item.
</description>
</method>
@@ -239,9 +239,9 @@
</method>
<method name="scroll_to_item">
<return type="void" />
- <argument index="0" name="item" type="Object" />
+ <argument index="0" name="item" type="TreeItem" />
<description>
- Causes the [Tree] to jump to the specified item.
+ Causes the [Tree] to jump to the specified [TreeItem].
</description>
</method>
<method name="set_column_clip_content">
diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml
index 13f2c7120c..12c91cdd10 100644
--- a/doc/classes/TreeItem.xml
+++ b/doc/classes/TreeItem.xml
@@ -371,7 +371,7 @@
</method>
<method name="move_after">
<return type="void" />
- <argument index="0" name="item" type="Object" />
+ <argument index="0" name="item" type="TreeItem" />
<description>
Moves this TreeItem right after the given [code]item[/code].
[b]Note:[/b] You can't move to the root or move the root.
@@ -379,7 +379,7 @@
</method>
<method name="move_before">
<return type="void" />
- <argument index="0" name="item" type="Object" />
+ <argument index="0" name="item" type="TreeItem" />
<description>
Moves this TreeItem right before the given [code]item[/code].
[b]Note:[/b] You can't move to the root or move the root.
@@ -395,7 +395,7 @@
</method>
<method name="remove_child">
<return type="void" />
- <argument index="0" name="child" type="Object" />
+ <argument index="0" name="child" type="TreeItem" />
<description>
Removes the given child [TreeItem] and all its children from the [Tree]. Note that it doesn't free the item from memory, so it can be reused later. To completely remove a [TreeItem] use [method Object.free].
</description>
diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml
index 1cba995366..a1b53346d8 100644
--- a/doc/classes/Tween.xml
+++ b/doc/classes/Tween.xml
@@ -146,7 +146,7 @@
<description>
Sets the number of times the tweening sequence will be repeated, i.e. [code]set_loops(2)[/code] will run the animation twice.
Calling this method without arguments will make the [Tween] run infinitely, until it is either killed by [method kill] or by freeing bound node, or all the animated objects have been freed (which makes further animation impossible).
- [b]Warning:[/b] Make sure to always add some duration/delay when using infinite loops. 0-duration looped animations (e.g. single [CallbackTweener] with no delay) are equivalent to infinite [code]while[/code] loops and will freeze your game.
+ [b]Warning:[/b] Make sure to always add some duration/delay when using infinite loops. 0-duration looped animations (e.g. single [CallbackTweener] with no delay or [PropertyTweener] with invalid node) are equivalent to infinite [code]while[/code] loops and will freeze your game. If a [Tween]'s lifetime depends on some node, always use [method bind_node].
</description>
</method>
<method name="set_parallel">
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 4a11fbb489..1b37cab68e 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -107,6 +107,12 @@
Returns the drag data from the GUI, that was previously returned by [method Control._get_drag_data].
</description>
</method>
+ <method name="gui_get_focus_owner">
+ <return type="Control" />
+ <description>
+ Returns the [Control] having the focus within this viewport. If no [Control] has the focus, returns null.
+ </description>
+ </method>
<method name="gui_is_drag_successful" qualifiers="const">
<return type="bool" />
<description>
@@ -119,6 +125,12 @@
Returns [code]true[/code] if the viewport is currently performing a drag operation.
</description>
</method>
+ <method name="gui_release_focus">
+ <return type="void" />
+ <description>
+ Removes the focus from the currently focussed [Control] within this viewport. If no [Control] has the focus, does nothing.
+ </description>
+ </method>
<method name="is_embedding_subwindows" qualifiers="const">
<return type="bool" />
<description>
diff --git a/doc/classes/VisualShaderNode.xml b/doc/classes/VisualShaderNode.xml
index cebe7f215f..0067240820 100644
--- a/doc/classes/VisualShaderNode.xml
+++ b/doc/classes/VisualShaderNode.xml
@@ -47,6 +47,7 @@
<return type="void" />
<argument index="0" name="port" type="int" />
<argument index="1" name="value" type="Variant" />
+ <argument index="2" name="prev_value" type="Variant" default="null" />
<description>
Sets the default value for the selected input [code]port[/code].
</description>
@@ -71,19 +72,22 @@
<constant name="PORT_TYPE_SCALAR_INT" value="1" enum="PortType">
Integer scalar. Translated to [code]int[/code] type in shader code.
</constant>
- <constant name="PORT_TYPE_VECTOR" value="2" enum="PortType">
+ <constant name="PORT_TYPE_VECTOR_2D" value="2" enum="PortType">
+ 2D vector of floating-point values. Translated to [code]vec2[/code] type in shader code.
+ </constant>
+ <constant name="PORT_TYPE_VECTOR" value="3" enum="PortType">
3D vector of floating-point values. Translated to [code]vec3[/code] type in shader code.
</constant>
- <constant name="PORT_TYPE_BOOLEAN" value="3" enum="PortType">
+ <constant name="PORT_TYPE_BOOLEAN" value="4" enum="PortType">
Boolean type. Translated to [code]bool[/code] type in shader code.
</constant>
- <constant name="PORT_TYPE_TRANSFORM" value="4" enum="PortType">
+ <constant name="PORT_TYPE_TRANSFORM" value="5" enum="PortType">
Transform type. Translated to [code]mat4[/code] type in shader code.
</constant>
- <constant name="PORT_TYPE_SAMPLER" value="5" enum="PortType">
+ <constant name="PORT_TYPE_SAMPLER" value="6" enum="PortType">
Sampler type. Translated to reference of sampler uniform in shader code. Can only be used for input ports in non-uniform nodes.
</constant>
- <constant name="PORT_TYPE_MAX" value="6" enum="PortType">
+ <constant name="PORT_TYPE_MAX" value="7" enum="PortType">
Represents the size of the [enum PortType] enum.
</constant>
</constants>
diff --git a/doc/classes/VisualShaderNodeClamp.xml b/doc/classes/VisualShaderNodeClamp.xml
index a68cbbec49..7219ba14b7 100644
--- a/doc/classes/VisualShaderNodeClamp.xml
+++ b/doc/classes/VisualShaderNodeClamp.xml
@@ -20,10 +20,13 @@
<constant name="OP_TYPE_INT" value="1" enum="OpType">
An integer scalar.
</constant>
- <constant name="OP_TYPE_VECTOR" value="2" enum="OpType">
- A vector type.
+ <constant name="OP_TYPE_VECTOR_2D" value="2" enum="OpType">
+ A 2D vector type.
</constant>
- <constant name="OP_TYPE_MAX" value="3" enum="OpType">
+ <constant name="OP_TYPE_VECTOR_3D" value="3" enum="OpType">
+ A 3D vector type.
+ </constant>
+ <constant name="OP_TYPE_MAX" value="4" enum="OpType">
Represents the size of the [enum OpType] enum.
</constant>
</constants>
diff --git a/doc/classes/VisualShaderNodeCompare.xml b/doc/classes/VisualShaderNodeCompare.xml
index 49bf952b31..ddd7f87cb8 100644
--- a/doc/classes/VisualShaderNodeCompare.xml
+++ b/doc/classes/VisualShaderNodeCompare.xml
@@ -10,7 +10,7 @@
</tutorials>
<members>
<member name="condition" type="int" setter="set_condition" getter="get_condition" enum="VisualShaderNodeCompare.Condition" default="0">
- Extra condition which is applied if [member type] is set to [constant CTYPE_VECTOR].
+ Extra condition which is applied if [member type] is set to [constant CTYPE_VECTOR_3D].
</member>
<member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeCompare.Function" default="0">
A comparison function. See [enum Function] for options.
@@ -26,16 +26,19 @@
<constant name="CTYPE_SCALAR_INT" value="1" enum="ComparisonType">
An integer scalar.
</constant>
- <constant name="CTYPE_VECTOR" value="2" enum="ComparisonType">
+ <constant name="CTYPE_VECTOR_2D" value="2" enum="ComparisonType">
+ A 2D vector type.
+ </constant>
+ <constant name="CTYPE_VECTOR_3D" value="3" enum="ComparisonType">
A 3D vector type.
</constant>
- <constant name="CTYPE_BOOLEAN" value="3" enum="ComparisonType">
+ <constant name="CTYPE_BOOLEAN" value="4" enum="ComparisonType">
A boolean type.
</constant>
- <constant name="CTYPE_TRANSFORM" value="4" enum="ComparisonType">
+ <constant name="CTYPE_TRANSFORM" value="5" enum="ComparisonType">
A transform ([code]mat4[/code]) type.
</constant>
- <constant name="CTYPE_MAX" value="5" enum="ComparisonType">
+ <constant name="CTYPE_MAX" value="6" enum="ComparisonType">
Represents the size of the [enum ComparisonType] enum.
</constant>
<constant name="FUNC_EQUAL" value="0" enum="Function">
diff --git a/doc/classes/VisualShaderNodeDerivativeFunc.xml b/doc/classes/VisualShaderNodeDerivativeFunc.xml
new file mode 100644
index 0000000000..704af44d04
--- /dev/null
+++ b/doc/classes/VisualShaderNodeDerivativeFunc.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeDerivativeFunc" inherits="VisualShaderNode" version="4.0">
+ <brief_description>
+ Calculates a derivative within the visual shader graph.
+ </brief_description>
+ <description>
+ This node is only available in [code]Fragment[/code] and [code]Light[/code] visual shaders.
+ </description>
+ <tutorials>
+ </tutorials>
+ <members>
+ <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeDerivativeFunc.Function" default="0">
+ A derivative function type. See [enum Function] for options.
+ </member>
+ <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeDerivativeFunc.OpType" default="0">
+ A type of operands and returned value. See [enum OpType] for options.
+ </member>
+ </members>
+ <constants>
+ <constant name="OP_TYPE_SCALAR" value="0" enum="OpType">
+ A floating-point scalar.
+ </constant>
+ <constant name="OP_TYPE_VECTOR_2D" value="1" enum="OpType">
+ A 2D vector type.
+ </constant>
+ <constant name="OP_TYPE_VECTOR_3D" value="2" enum="OpType">
+ A 3D vector type.
+ </constant>
+ <constant name="OP_TYPE_MAX" value="3" enum="OpType">
+ Represents the size of the [enum OpType] enum.
+ </constant>
+ <constant name="FUNC_SUM" value="0" enum="Function">
+ Sum of absolute derivative in [code]x[/code] and [code]y[/code].
+ </constant>
+ <constant name="FUNC_X" value="1" enum="Function">
+ Derivative in [code]x[/code] using local differencing.
+ </constant>
+ <constant name="FUNC_Y" value="2" enum="Function">
+ Derivative in [code]y[/code] using local differencing.
+ </constant>
+ <constant name="FUNC_MAX" value="3" enum="Function">
+ Represents the size of the [enum Function] enum.
+ </constant>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeFaceForward.xml b/doc/classes/VisualShaderNodeFaceForward.xml
index 80cb8aea4e..cd2b3972b7 100644
--- a/doc/classes/VisualShaderNodeFaceForward.xml
+++ b/doc/classes/VisualShaderNodeFaceForward.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeFaceForward" inherits="VisualShaderNode" version="4.0">
+<class name="VisualShaderNodeFaceForward" inherits="VisualShaderNodeVectorBase" version="4.0">
<brief_description>
Returns the vector that points in the same direction as a reference vector within the visual shader graph.
</brief_description>
diff --git a/doc/classes/VisualShaderNodeMix.xml b/doc/classes/VisualShaderNodeMix.xml
index 1ef580a983..8a2f289a11 100644
--- a/doc/classes/VisualShaderNodeMix.xml
+++ b/doc/classes/VisualShaderNodeMix.xml
@@ -15,15 +15,21 @@
</members>
<constants>
<constant name="OP_TYPE_SCALAR" value="0" enum="OpType">
- A scalar type.
+ A floating-point scalar.
</constant>
- <constant name="OP_TYPE_VECTOR" value="1" enum="OpType">
- A vector type.
+ <constant name="OP_TYPE_VECTOR_2D" value="1" enum="OpType">
+ A 2D vector type.
</constant>
- <constant name="OP_TYPE_VECTOR_SCALAR" value="2" enum="OpType">
- A vector type. [code]weight[/code] port is using a scalar type.
+ <constant name="OP_TYPE_VECTOR_2D_SCALAR" value="2" enum="OpType">
+ The [code]a[/code] and [code]b[/code] ports use a 2D vector type. The [code]weight[/code] port uses a scalar type.
</constant>
- <constant name="OP_TYPE_MAX" value="3" enum="OpType">
+ <constant name="OP_TYPE_VECTOR_3D" value="3" enum="OpType">
+ A 3D vector type.
+ </constant>
+ <constant name="OP_TYPE_VECTOR_3D_SCALAR" value="4" enum="OpType">
+ The [code]a[/code] and [code]b[/code] ports use a 3D vector type. The [code]weight[/code] port uses a scalar type.
+ </constant>
+ <constant name="OP_TYPE_MAX" value="5" enum="OpType">
Represents the size of the [enum OpType] enum.
</constant>
</constants>
diff --git a/doc/classes/VisualShaderNodeMultiplyAdd.xml b/doc/classes/VisualShaderNodeMultiplyAdd.xml
index a0e9aef703..a6168e4df1 100644
--- a/doc/classes/VisualShaderNodeMultiplyAdd.xml
+++ b/doc/classes/VisualShaderNodeMultiplyAdd.xml
@@ -15,12 +15,15 @@
</members>
<constants>
<constant name="OP_TYPE_SCALAR" value="0" enum="OpType">
- A scalar type.
+ A floating-point scalar type.
</constant>
- <constant name="OP_TYPE_VECTOR" value="1" enum="OpType">
- A vector type.
+ <constant name="OP_TYPE_VECTOR_2D" value="1" enum="OpType">
+ A 2D vector type.
</constant>
- <constant name="OP_TYPE_MAX" value="2" enum="OpType">
+ <constant name="OP_TYPE_VECTOR_3D" value="2" enum="OpType">
+ A 3D vector type.
+ </constant>
+ <constant name="OP_TYPE_MAX" value="3" enum="OpType">
Represents the size of the [enum OpType] enum.
</constant>
</constants>
diff --git a/doc/classes/VisualShaderNodeScalarDerivativeFunc.xml b/doc/classes/VisualShaderNodeScalarDerivativeFunc.xml
deleted file mode 100644
index 8d108a5d28..0000000000
--- a/doc/classes/VisualShaderNodeScalarDerivativeFunc.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeScalarDerivativeFunc" inherits="VisualShaderNode" version="4.0">
- <brief_description>
- Calculates a scalar derivative within the visual shader graph.
- </brief_description>
- <description>
- This node is only available in [code]Fragment[/code] and [code]Light[/code] visual shaders.
- </description>
- <tutorials>
- </tutorials>
- <members>
- <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeScalarDerivativeFunc.Function" default="0">
- The derivative type. See [enum Function] for options.
- </member>
- </members>
- <constants>
- <constant name="FUNC_SUM" value="0" enum="Function">
- Sum of absolute derivative in [code]x[/code] and [code]y[/code].
- </constant>
- <constant name="FUNC_X" value="1" enum="Function">
- Derivative in [code]x[/code] using local differencing.
- </constant>
- <constant name="FUNC_Y" value="2" enum="Function">
- Derivative in [code]y[/code] using local differencing.
- </constant>
- <constant name="FUNC_MAX" value="3" enum="Function">
- Represents the size of the [enum Function] enum.
- </constant>
- </constants>
-</class>
diff --git a/doc/classes/VisualShaderNodeSmoothStep.xml b/doc/classes/VisualShaderNodeSmoothStep.xml
index 2f8c7e0f33..714b9d8267 100644
--- a/doc/classes/VisualShaderNodeSmoothStep.xml
+++ b/doc/classes/VisualShaderNodeSmoothStep.xml
@@ -16,15 +16,21 @@
</members>
<constants>
<constant name="OP_TYPE_SCALAR" value="0" enum="OpType">
- A scalar type.
+ A floating-point scalar type.
</constant>
- <constant name="OP_TYPE_VECTOR" value="1" enum="OpType">
- A vector type.
+ <constant name="OP_TYPE_VECTOR_2D" value="1" enum="OpType">
+ A 2D vector type.
</constant>
- <constant name="OP_TYPE_VECTOR_SCALAR" value="2" enum="OpType">
- A vector type. [code]edge0[/code] and [code]edge1[/code] are using a scalar type.
+ <constant name="OP_TYPE_VECTOR_2D_SCALAR" value="2" enum="OpType">
+ The [code]x[/code] port uses a 2D vector type. The first two ports use a floating-point scalar type.
</constant>
- <constant name="OP_TYPE_MAX" value="3" enum="OpType">
+ <constant name="OP_TYPE_VECTOR_3D" value="3" enum="OpType">
+ A 3D vector type.
+ </constant>
+ <constant name="OP_TYPE_VECTOR_3D_SCALAR" value="4" enum="OpType">
+ The [code]x[/code] port uses a 3D vector type. The first two ports use a floating-point scalar type.
+ </constant>
+ <constant name="OP_TYPE_MAX" value="5" enum="OpType">
Represents the size of the [enum OpType] enum.
</constant>
</constants>
diff --git a/doc/classes/VisualShaderNodeStep.xml b/doc/classes/VisualShaderNodeStep.xml
index 5d8b464814..f65c95ea9e 100644
--- a/doc/classes/VisualShaderNodeStep.xml
+++ b/doc/classes/VisualShaderNodeStep.xml
@@ -16,15 +16,21 @@
</members>
<constants>
<constant name="OP_TYPE_SCALAR" value="0" enum="OpType">
- A scalar type.
+ A floating-point scalar type.
</constant>
- <constant name="OP_TYPE_VECTOR" value="1" enum="OpType">
- A vector type.
+ <constant name="OP_TYPE_VECTOR_2D" value="1" enum="OpType">
+ A 2D vector type.
</constant>
- <constant name="OP_TYPE_VECTOR_SCALAR" value="2" enum="OpType">
- A vector type. [code]edge[/code] port is using a scalar type.
+ <constant name="OP_TYPE_VECTOR_2D_SCALAR" value="2" enum="OpType">
+ The [code]x[/code] port uses a 2D vector type, while the [code]edge[/code] port uses a floating-point scalar type.
</constant>
- <constant name="OP_TYPE_MAX" value="3" enum="OpType">
+ <constant name="OP_TYPE_VECTOR_3D" value="3" enum="OpType">
+ A 3D vector type.
+ </constant>
+ <constant name="OP_TYPE_VECTOR_3D_SCALAR" value="4" enum="OpType">
+ The [code]x[/code] port uses a 3D vector type, while the [code]edge[/code] port uses a floating-point scalar type.
+ </constant>
+ <constant name="OP_TYPE_MAX" value="5" enum="OpType">
Represents the size of the [enum OpType] enum.
</constant>
</constants>
diff --git a/doc/classes/VisualShaderNodeSwitch.xml b/doc/classes/VisualShaderNodeSwitch.xml
index 921092cd07..71888ec2c3 100644
--- a/doc/classes/VisualShaderNodeSwitch.xml
+++ b/doc/classes/VisualShaderNodeSwitch.xml
@@ -20,16 +20,19 @@
<constant name="OP_TYPE_INT" value="1" enum="OpType">
An integer scalar.
</constant>
- <constant name="OP_TYPE_VECTOR" value="2" enum="OpType">
- A vector type.
+ <constant name="OP_TYPE_VECTOR_2D" value="2" enum="OpType">
+ A 2D vector type.
</constant>
- <constant name="OP_TYPE_BOOLEAN" value="3" enum="OpType">
+ <constant name="OP_TYPE_VECTOR_3D" value="3" enum="OpType">
+ A 3D vector type.
+ </constant>
+ <constant name="OP_TYPE_BOOLEAN" value="4" enum="OpType">
A boolean type.
</constant>
- <constant name="OP_TYPE_TRANSFORM" value="4" enum="OpType">
+ <constant name="OP_TYPE_TRANSFORM" value="5" enum="OpType">
A transform type.
</constant>
- <constant name="OP_TYPE_MAX" value="5" enum="OpType">
+ <constant name="OP_TYPE_MAX" value="6" enum="OpType">
Represents the size of the [enum OpType] enum.
</constant>
</constants>
diff --git a/doc/classes/VisualShaderNodeVec2Constant.xml b/doc/classes/VisualShaderNodeVec2Constant.xml
new file mode 100644
index 0000000000..f897ab4091
--- /dev/null
+++ b/doc/classes/VisualShaderNodeVec2Constant.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeVec2Constant" inherits="VisualShaderNodeConstant" version="4.0">
+ <brief_description>
+ A [Vector2] constant to be used within the visual shader graph.
+ </brief_description>
+ <description>
+ A constant [Vector2], which can be used as an input node.
+ </description>
+ <tutorials>
+ </tutorials>
+ <members>
+ <member name="constant" type="Vector2" setter="set_constant" getter="get_constant" default="Vector2(0, 0)">
+ A [Vector2] constant which represents the state of this node.
+ </member>
+ </members>
+</class>
diff --git a/doc/classes/VisualShaderNodeVec2Uniform.xml b/doc/classes/VisualShaderNodeVec2Uniform.xml
new file mode 100644
index 0000000000..d5cf7e57c8
--- /dev/null
+++ b/doc/classes/VisualShaderNodeVec2Uniform.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeVec2Uniform" inherits="VisualShaderNodeUniform" version="4.0">
+ <brief_description>
+ A [Vector2] uniform to be used within the visual shader graph.
+ </brief_description>
+ <description>
+ Translated to [code]uniform vec2[/code] in the shader language.
+ </description>
+ <tutorials>
+ </tutorials>
+ <members>
+ <member name="default_value" type="Vector2" setter="set_default_value" getter="get_default_value" default="Vector2(0, 0)">
+ A default value to be assigned within the shader.
+ </member>
+ <member name="default_value_enabled" type="bool" setter="set_default_value_enabled" getter="is_default_value_enabled" default="false">
+ Enables usage of the [member default_value].
+ </member>
+ </members>
+</class>
diff --git a/doc/classes/VisualShaderNodeVectorBase.xml b/doc/classes/VisualShaderNodeVectorBase.xml
new file mode 100644
index 0000000000..8a560c1951
--- /dev/null
+++ b/doc/classes/VisualShaderNodeVectorBase.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeVectorBase" inherits="VisualShaderNode" version="4.0">
+ <brief_description>
+ A base type for the nodes using different vector types within the visual shader graph.
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <members>
+ <member name="op_type" type="int" setter="set_op_type" getter="get_op_type" enum="VisualShaderNodeVectorBase.OpType" default="1">
+ A base type.
+ </member>
+ </members>
+ <constants>
+ <constant name="OP_TYPE_VECTOR_2D" value="0" enum="OpType">
+ A 2D vector type.
+ </constant>
+ <constant name="OP_TYPE_VECTOR_3D" value="1" enum="OpType">
+ A 3D vector type.
+ </constant>
+ <constant name="OP_TYPE_MAX" value="2" enum="OpType">
+ Represents the size of the [enum OpType] enum.
+ </constant>
+ </constants>
+</class>
diff --git a/doc/classes/VisualShaderNodeVectorCompose.xml b/doc/classes/VisualShaderNodeVectorCompose.xml
index ebc30d03f4..b8caf154f9 100644
--- a/doc/classes/VisualShaderNodeVectorCompose.xml
+++ b/doc/classes/VisualShaderNodeVectorCompose.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeVectorCompose" inherits="VisualShaderNode" version="4.0">
+<class name="VisualShaderNodeVectorCompose" inherits="VisualShaderNodeVectorBase" version="4.0">
<brief_description>
Composes a [Vector3] from three scalars within the visual shader graph.
</brief_description>
diff --git a/doc/classes/VisualShaderNodeVectorDecompose.xml b/doc/classes/VisualShaderNodeVectorDecompose.xml
index 09986bf969..9ef9db0cfb 100644
--- a/doc/classes/VisualShaderNodeVectorDecompose.xml
+++ b/doc/classes/VisualShaderNodeVectorDecompose.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeVectorDecompose" inherits="VisualShaderNode" version="4.0">
+<class name="VisualShaderNodeVectorDecompose" inherits="VisualShaderNodeVectorBase" version="4.0">
<brief_description>
Decomposes a [Vector3] into three scalars within the visual shader graph.
</brief_description>
diff --git a/doc/classes/VisualShaderNodeVectorDerivativeFunc.xml b/doc/classes/VisualShaderNodeVectorDerivativeFunc.xml
deleted file mode 100644
index e0c7c8618c..0000000000
--- a/doc/classes/VisualShaderNodeVectorDerivativeFunc.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeVectorDerivativeFunc" inherits="VisualShaderNode" version="4.0">
- <brief_description>
- Calculates a vector derivative within the visual shader graph.
- </brief_description>
- <description>
- This node is only available in [code]Fragment[/code] and [code]Light[/code] visual shaders.
- </description>
- <tutorials>
- </tutorials>
- <members>
- <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeVectorDerivativeFunc.Function" default="0">
- A derivative type. See [enum Function] for options.
- </member>
- </members>
- <constants>
- <constant name="FUNC_SUM" value="0" enum="Function">
- Sum of absolute derivative in [code]x[/code] and [code]y[/code].
- </constant>
- <constant name="FUNC_X" value="1" enum="Function">
- Derivative in [code]x[/code] using local differencing.
- </constant>
- <constant name="FUNC_Y" value="2" enum="Function">
- Derivative in [code]y[/code] using local differencing.
- </constant>
- <constant name="FUNC_MAX" value="3" enum="Function">
- Represents the size of the [enum Function] enum.
- </constant>
- </constants>
-</class>
diff --git a/doc/classes/VisualShaderNodeVectorDistance.xml b/doc/classes/VisualShaderNodeVectorDistance.xml
index 098787e583..c0d8ffe943 100644
--- a/doc/classes/VisualShaderNodeVectorDistance.xml
+++ b/doc/classes/VisualShaderNodeVectorDistance.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeVectorDistance" inherits="VisualShaderNode" version="4.0">
+<class name="VisualShaderNodeVectorDistance" inherits="VisualShaderNodeVectorBase" version="4.0">
<brief_description>
Returns the distance between two points. To be used within the visual shader graph.
</brief_description>
diff --git a/doc/classes/VisualShaderNodeVectorFunc.xml b/doc/classes/VisualShaderNodeVectorFunc.xml
index 27ae82e11b..17a6418b94 100644
--- a/doc/classes/VisualShaderNodeVectorFunc.xml
+++ b/doc/classes/VisualShaderNodeVectorFunc.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeVectorFunc" inherits="VisualShaderNode" version="4.0">
+<class name="VisualShaderNodeVectorFunc" inherits="VisualShaderNodeVectorBase" version="4.0">
<brief_description>
A vector function to be used within the visual shader graph.
</brief_description>
diff --git a/doc/classes/VisualShaderNodeVectorLen.xml b/doc/classes/VisualShaderNodeVectorLen.xml
index 165455e622..f1b6919bdc 100644
--- a/doc/classes/VisualShaderNodeVectorLen.xml
+++ b/doc/classes/VisualShaderNodeVectorLen.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeVectorLen" inherits="VisualShaderNode" version="4.0">
+<class name="VisualShaderNodeVectorLen" inherits="VisualShaderNodeVectorBase" version="4.0">
<brief_description>
Returns the length of a [Vector3] within the visual shader graph.
</brief_description>
diff --git a/doc/classes/VisualShaderNodeVectorOp.xml b/doc/classes/VisualShaderNodeVectorOp.xml
index 5e8f0abda3..6a579abb9a 100644
--- a/doc/classes/VisualShaderNodeVectorOp.xml
+++ b/doc/classes/VisualShaderNodeVectorOp.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualShaderNodeVectorOp" inherits="VisualShaderNode" version="4.0">
+<class name="VisualShaderNodeVectorOp" inherits="VisualShaderNodeVectorBase" version="4.0">
<brief_description>
A vector operator to be used within the visual shader graph.
</brief_description>
diff --git a/doc/classes/XRInterfaceExtension.xml b/doc/classes/XRInterfaceExtension.xml
index d2bb6aa59a..cd09f83335 100644
--- a/doc/classes/XRInterfaceExtension.xml
+++ b/doc/classes/XRInterfaceExtension.xml
@@ -9,46 +9,52 @@
<tutorials>
</tutorials>
<methods>
- <method name="_commit_views" qualifiers="virtual">
+ <method name="_end_frame" qualifiers="virtual">
<return type="void" />
- <argument index="0" name="render_target" type="RID" />
- <argument index="1" name="screen_rect" type="Rect2" />
<description>
+ Called if interface is active and queues have been submitted.
</description>
</method>
<method name="_get_anchor_detection_is_enabled" qualifiers="virtual const">
<return type="bool" />
<description>
+ Return [code]true[/code] if anchor detection is enabled for this interface.
</description>
</method>
<method name="_get_camera_feed_id" qualifiers="virtual const">
<return type="int" />
<description>
+ Returns the camera feed id for the [CameraFeed] registered with the [CameraServer] that should be presented as the background on an AR capable device (if applicable).
</description>
</method>
<method name="_get_camera_transform" qualifiers="virtual">
<return type="Transform3D" />
<description>
+ Returns the [Transform3D] that positions the [XRCamera3D] in the world.
</description>
</method>
<method name="_get_capabilities" qualifiers="virtual const">
<return type="int" />
<description>
+ Returns the capabilities of this interface.
</description>
</method>
<method name="_get_name" qualifiers="virtual const">
<return type="StringName" />
<description>
+ Returns the name of this interface.
</description>
</method>
<method name="_get_play_area" qualifiers="virtual const">
<return type="PackedVector3Array" />
<description>
+ Returns an [PackedVector3Array] that denotes the play areas boundaries (if applicable).
</description>
</method>
<method name="_get_play_area_mode" qualifiers="virtual const">
<return type="int" />
<description>
+ Returns the [enum XRInterface.PlayAreaMode] that sets up our play area.
</description>
</method>
<method name="_get_projection_for_view" qualifiers="virtual">
@@ -58,27 +64,32 @@
<argument index="2" name="z_near" type="float" />
<argument index="3" name="z_far" type="float" />
<description>
+ Returns the projection matrix for the given view as a [PackedFloat64Array].
</description>
</method>
<method name="_get_render_target_size" qualifiers="virtual">
<return type="Vector2" />
<description>
+ Returns the size of our render target for this interface, this overrides the size of the [Viewport] marked as the xr viewport.
</description>
</method>
<method name="_get_suggested_pose_names" qualifiers="virtual const">
<return type="PackedStringArray" />
<argument index="0" name="tracker_name" type="StringName" />
<description>
+ Returns a [PackedStringArray] with pose names configured by this interface. Note that user configuration can override this list.
</description>
</method>
<method name="_get_suggested_tracker_names" qualifiers="virtual const">
<return type="PackedStringArray" />
<description>
+ Returns a [PackedStringArray] with tracker names configured by this interface. Note that user configuration can override this list.
</description>
</method>
<method name="_get_tracking_status" qualifiers="virtual const">
<return type="int" />
<description>
+ Returns a [enum XRInterface.TrackingStatus] specifying the current status of our tracking.
</description>
</method>
<method name="_get_transform_for_view" qualifiers="virtual">
@@ -86,50 +97,80 @@
<argument index="0" name="view" type="int" />
<argument index="1" name="cam_transform" type="Transform3D" />
<description>
+ Returns a [Transform3D] for a given view.
</description>
</method>
<method name="_get_view_count" qualifiers="virtual">
<return type="int" />
<description>
+ Returns the number of views this interface requires, 1 for mono, 2 for stereoscopic.
</description>
</method>
<method name="_initialize" qualifiers="virtual">
<return type="bool" />
<description>
+ Initializes the interface, returns [code]true[/code] on success.
</description>
</method>
<method name="_is_initialized" qualifiers="virtual const">
<return type="bool" />
<description>
+ Returns [code]true[/code] if this interface has been initialised.
</description>
</method>
<method name="_notification" qualifiers="virtual">
<return type="void" />
<argument index="0" name="what" type="int" />
<description>
+ Informs the interface of an applicable system notification.
+ </description>
+ </method>
+ <method name="_post_draw_viewport" qualifiers="virtual">
+ <return type="void" />
+ <argument index="0" name="render_target" type="RID" />
+ <argument index="1" name="screen_rect" type="Rect2" />
+ <description>
+ Called after the XR [Viewport] draw logic has completed.
+ </description>
+ </method>
+ <method name="_pre_draw_viewport" qualifiers="virtual">
+ <return type="bool" />
+ <argument index="0" name="render_target" type="RID" />
+ <description>
+ Called if this is our primary [XRInterfaceExtension] before we start processing a [Viewport] for every active XR [Viewport], returns [code]true[/code] if that viewport should be rendered. An XR interface may return [code]false[/code] if the user has taken off their headset and we can pause rendering.
+ </description>
+ </method>
+ <method name="_pre_render" qualifiers="virtual">
+ <return type="void" />
+ <description>
+ Called if this [XRInterfaceExtension] is active before rendering starts, most XR interfaces will sync tracking at this point in time.
</description>
</method>
<method name="_process" qualifiers="virtual">
<return type="void" />
<description>
+ Called if this [XRInterfaceExtension] is active before our physics and game process is called. most XR interfaces will update its [XRPositionalTracker]s at this point in time.
</description>
</method>
<method name="_set_anchor_detection_is_enabled" qualifiers="virtual">
<return type="void" />
<argument index="0" name="enabled" type="bool" />
<description>
+ Enables anchor detection on this interface if supported.
</description>
</method>
<method name="_set_play_area_mode" qualifiers="virtual const">
<return type="bool" />
<argument index="0" name="mode" type="int" />
<description>
+ Set the play area mode for this interface.
</description>
</method>
<method name="_supports_play_area_mode" qualifiers="virtual const">
<return type="bool" />
<argument index="0" name="mode" type="int" enum="XRInterface.PlayAreaMode" />
<description>
+ Returns [code]true[/code] if this interface supports this play area mode.
</description>
</method>
<method name="_trigger_haptic_pulse" qualifiers="virtual">
@@ -141,11 +182,13 @@
<argument index="4" name="duration_sec" type="float" />
<argument index="5" name="delay_sec" type="float" />
<description>
+ Triggers a haptic pulse to be emitted on the specified tracker.
</description>
</method>
<method name="_uninitialize" qualifiers="virtual">
<return type="void" />
<description>
+ Uninitialize the interface.
</description>
</method>
<method name="add_blit">
@@ -169,6 +212,7 @@
<return type="RID" />
<argument index="0" name="render_target" type="RID" />
<description>
+ Returns a valid [RID] for a texture to which we should render the current frame if supported by the interface.
</description>
</method>
</methods>
diff --git a/doc/classes/XRServer.xml b/doc/classes/XRServer.xml
index 3a7fdea8d0..335ca4c35f 100644
--- a/doc/classes/XRServer.xml
+++ b/doc/classes/XRServer.xml
@@ -69,24 +69,6 @@
Returns a list of available interfaces the ID and name of each interface.
</description>
</method>
- <method name="get_last_commit_usec">
- <return type="int" />
- <description>
- Returns the absolute timestamp (in μs) of the last [XRServer] commit of the AR/VR eyes to [RenderingServer]. The value comes from an internal call to [method Time.get_ticks_usec].
- </description>
- </method>
- <method name="get_last_frame_usec">
- <return type="int" />
- <description>
- Returns the duration (in μs) of the last frame. This is computed as the difference between [method get_last_commit_usec] and [method get_last_process_usec] when committing.
- </description>
- </method>
- <method name="get_last_process_usec">
- <return type="int" />
- <description>
- Returns the absolute timestamp (in μs) of the last [XRServer] process callback. The value comes from an internal call to [method Time.get_ticks_usec].
- </description>
- </method>
<method name="get_reference_frame" qualifiers="const">
<return type="Transform3D" />
<description>
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 270725ee63..451960d772 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -184,7 +184,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
}
state.current_tex = RID();
- state.current_tex_ptr = NULL;
+ state.current_tex_ptr = nullptr;
state.current_normal = RID();
state.current_specular = RID();
state.canvas_texscreen_used = false;
@@ -233,13 +233,13 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
}
if (material != prev_material) {
- RasterizerStorageGLES3::Shader *shader_ptr = NULL;
+ RasterizerStorageGLES3::Shader *shader_ptr = nullptr;
if (material_ptr) {
shader_ptr = material_ptr->shader;
if (shader_ptr && shader_ptr->mode != RS::SHADER_CANVAS_ITEM) {
- shader_ptr = NULL; // not a canvas item shader, don't use.
+ shader_ptr = nullptr; // not a canvas item shader, don't use.
}
}
@@ -295,8 +295,9 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
t->detect_normal(t->detect_normal_ud);
}
#endif
- if (t->render_target)
+ if (t->render_target) {
t->render_target->used_in_frame = true;
+ }
glBindTexture(t->target, t->tex_id);
}
@@ -582,7 +583,7 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item
static const GLenum prim[5] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP };
if (pb->index_buffer != 0) {
- glDrawElements(prim[polygon->primitive], pb->count, GL_UNSIGNED_INT, 0);
+ glDrawElements(prim[polygon->primitive], pb->count, GL_UNSIGNED_INT, nullptr);
} else {
glDrawArrays(prim[polygon->primitive], 0, pb->count);
}
@@ -946,7 +947,7 @@ void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTe
if (!texture) {
state.current_tex = RID();
- state.current_tex_ptr = NULL;
+ state.current_tex_ptr = nullptr;
ct->size_cache = Size2i(1, 1);
glActiveTexture(GL_TEXTURE0);
@@ -1096,7 +1097,7 @@ RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vec
{
// Always uses vertex positions
glEnableVertexAttribArray(RS::ARRAY_VERTEX);
- glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), NULL);
+ glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), nullptr);
const Vector2 *points_ptr = p_points.ptr();
for (uint32_t i = 0; i < vertex_count; i++) {
@@ -1313,7 +1314,7 @@ void RasterizerCanvasGLES3::initialize() {
glGenBuffers(1, &data.ninepatch_vertices);
glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices);
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * (16 + 16) * 2, NULL, GL_DYNAMIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float) * (16 + 16) * 2, nullptr, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -1443,7 +1444,7 @@ void fragment() {
default_canvas_texture = storage->canvas_texture_allocate();
storage->canvas_texture_initialize(default_canvas_texture);
- state.using_light = NULL;
+ state.using_light = nullptr;
state.using_transparent_rt = false;
state.using_skeleton = false;
state.current_shader_version = state.canvas_shader_default_version;
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 32ead8aa7e..087bf36473 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -130,46 +130,51 @@ void RasterizerGLES3::end_frame(bool p_swap_buffers) {
#ifdef CAN_DEBUG
static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const GLvoid *userParam) {
- if (type == _EXT_DEBUG_TYPE_OTHER_ARB)
+ if (type == _EXT_DEBUG_TYPE_OTHER_ARB) {
return;
+ }
- if (type == _EXT_DEBUG_TYPE_PERFORMANCE_ARB)
+ if (type == _EXT_DEBUG_TYPE_PERFORMANCE_ARB) {
return; //these are ultimately annoying, so removing for now
+ }
char debSource[256], debType[256], debSev[256];
- if (source == _EXT_DEBUG_SOURCE_API_ARB)
+ if (source == _EXT_DEBUG_SOURCE_API_ARB) {
strcpy(debSource, "OpenGL");
- else if (source == _EXT_DEBUG_SOURCE_WINDOW_SYSTEM_ARB)
+ } else if (source == _EXT_DEBUG_SOURCE_WINDOW_SYSTEM_ARB) {
strcpy(debSource, "Windows");
- else if (source == _EXT_DEBUG_SOURCE_SHADER_COMPILER_ARB)
+ } else if (source == _EXT_DEBUG_SOURCE_SHADER_COMPILER_ARB) {
strcpy(debSource, "Shader Compiler");
- else if (source == _EXT_DEBUG_SOURCE_THIRD_PARTY_ARB)
+ } else if (source == _EXT_DEBUG_SOURCE_THIRD_PARTY_ARB) {
strcpy(debSource, "Third Party");
- else if (source == _EXT_DEBUG_SOURCE_APPLICATION_ARB)
+ } else if (source == _EXT_DEBUG_SOURCE_APPLICATION_ARB) {
strcpy(debSource, "Application");
- else if (source == _EXT_DEBUG_SOURCE_OTHER_ARB)
+ } else if (source == _EXT_DEBUG_SOURCE_OTHER_ARB) {
strcpy(debSource, "Other");
+ }
- if (type == _EXT_DEBUG_TYPE_ERROR_ARB)
+ if (type == _EXT_DEBUG_TYPE_ERROR_ARB) {
strcpy(debType, "Error");
- else if (type == _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB)
+ } else if (type == _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB) {
strcpy(debType, "Deprecated behavior");
- else if (type == _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB)
+ } else if (type == _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB) {
strcpy(debType, "Undefined behavior");
- else if (type == _EXT_DEBUG_TYPE_PORTABILITY_ARB)
+ } else if (type == _EXT_DEBUG_TYPE_PORTABILITY_ARB) {
strcpy(debType, "Portability");
- else if (type == _EXT_DEBUG_TYPE_PERFORMANCE_ARB)
+ } else if (type == _EXT_DEBUG_TYPE_PERFORMANCE_ARB) {
strcpy(debType, "Performance");
- else if (type == _EXT_DEBUG_TYPE_OTHER_ARB)
+ } else if (type == _EXT_DEBUG_TYPE_OTHER_ARB) {
strcpy(debType, "Other");
+ }
- if (severity == _EXT_DEBUG_SEVERITY_HIGH_ARB)
+ if (severity == _EXT_DEBUG_SEVERITY_HIGH_ARB) {
strcpy(debSev, "High");
- else if (severity == _EXT_DEBUG_SEVERITY_MEDIUM_ARB)
+ } else if (severity == _EXT_DEBUG_SEVERITY_MEDIUM_ARB) {
strcpy(debSev, "Medium");
- else if (severity == _EXT_DEBUG_SEVERITY_LOW_ARB)
+ } else if (severity == _EXT_DEBUG_SEVERITY_LOW_ARB) {
strcpy(debSev, "Low");
+ }
String output = String() + "GL ERROR: Source: " + debSource + "\tType: " + debType + "\tID: " + itos(id) + "\tSeverity: " + debSev + "\tMessage: " + message;
@@ -203,7 +208,7 @@ void RasterizerGLES3::initialize() {
if (OS::get_singleton()->is_stdout_verbose()) {
if (GLAD_GL_ARB_debug_output) {
glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
- glDebugMessageCallbackARB(_gl_debug_print, NULL);
+ glDebugMessageCallbackARB(_gl_debug_print, nullptr);
glEnable(_EXT_DEBUG_OUTPUT);
} else {
print_line("OpenGL debugging not supported!");
@@ -215,12 +220,12 @@ void RasterizerGLES3::initialize() {
#ifdef CAN_DEBUG
#ifdef GLES_OVER_GL
if (OS::get_singleton()->is_stdout_verbose() && GLAD_GL_ARB_debug_output) {
- glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_ERROR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE);
- glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE);
- glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE);
- glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_PORTABILITY_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE);
- glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_PERFORMANCE_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE);
- glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_OTHER_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE);
+ glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_ERROR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
+ glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
+ glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
+ glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_PORTABILITY_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
+ glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_PERFORMANCE_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
+ glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_OTHER_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
// glDebugMessageInsertARB(
// GL_DEBUG_SOURCE_API_ARB,
// GL_DEBUG_TYPE_OTHER_ARB, 1,
@@ -299,8 +304,9 @@ void RasterizerGLES3::blit_render_targets_to_screen(DisplayServer::WindowID p_sc
}
void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) {
- if (p_image.is_null() || p_image->is_empty())
+ if (p_image.is_null() || p_image->is_empty()) {
return;
+ }
Size2i win_size = DisplayServer::get_singleton()->screen_get_size();
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 31dda16b26..121dc86fb2 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -208,7 +208,7 @@ void RasterizerSceneGLES3::environment_set_canvas_max_layer(RID p_env, int p_max
void RasterizerSceneGLES3::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source) {
}
-void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) {
+void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) {
}
void RasterizerSceneGLES3::environment_glow_set_use_bicubic_upscale(bool p_enable) {
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 0f8c2e88b4..246b908c14 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -115,7 +115,7 @@ public:
void environment_set_canvas_max_layer(RID p_env, int p_max_layer) override;
void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) override;
- void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) override;
+ void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) override;
void environment_glow_set_use_bicubic_upscale(bool p_enable) override;
void environment_glow_set_use_high_quality(bool p_enable) override;
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index fd9e98be83..fda208b812 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -976,7 +976,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer)
*/
void RasterizerStorageGLES3::_texture_set_state_from_flags(Texture *p_tex) {
- if ((p_tex->flags & TEXTURE_FLAG_MIPMAPS) && !p_tex->ignore_mipmaps)
+ if ((p_tex->flags & TEXTURE_FLAG_MIPMAPS) && !p_tex->ignore_mipmaps) {
if (p_tex->flags & TEXTURE_FLAG_FILTER) {
// these do not exactly correspond ...
p_tex->GLSetFilter(p_tex->target, RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS);
@@ -985,7 +985,7 @@ void RasterizerStorageGLES3::_texture_set_state_from_flags(Texture *p_tex) {
p_tex->GLSetFilter(p_tex->target, RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);
//texture->glTexParam_MinFilter(texture->target, config.use_fast_texture_filter ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST_MIPMAP_LINEAR);
}
- else {
+ } else {
if (p_tex->flags & TEXTURE_FLAG_FILTER) {
p_tex->GLSetFilter(p_tex->target, RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR);
//texture->glTexParam_MinFilter(texture->target, GL_LINEAR);
@@ -1125,8 +1125,9 @@ void RasterizerStorageGLES3::texture_debug_usage(List<RS::TextureInfo> *r_info)
for (List<RID>::Element *E = textures.front(); E; E = E->next()) {
Texture *t = texture_owner.get_or_null(E->get());
- if (!t)
+ if (!t) {
continue;
+ }
RS::TextureInfo tinfo;
tinfo.path = t->path;
tinfo.format = t->format;
@@ -1173,7 +1174,7 @@ void RasterizerStorageGLES3::texture_set_proxy(RID p_texture, RID p_proxy) {
if (texture->proxy) {
texture->proxy->proxy_owners.erase(texture);
- texture->proxy = NULL;
+ texture->proxy = nullptr;
}
if (p_proxy.is_valid()) {
@@ -1298,8 +1299,9 @@ void RasterizerStorageGLES3::shader_initialize(RID p_rid) {
//}
void RasterizerStorageGLES3::_shader_make_dirty(Shader *p_shader) {
- if (p_shader->dirty_list.in_list())
+ if (p_shader->dirty_list.in_list()) {
return;
+ }
_shader_dirty_list.add(&p_shader->dirty_list);
}
@@ -1371,7 +1373,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
}
ShaderCompiler::GeneratedCode gen_code;
- ShaderCompiler::IdentifierActions *actions = NULL;
+ ShaderCompiler::IdentifierActions *actions = nullptr;
switch (p_shader->mode) {
case RS::SHADER_CANVAS_ITEM: {
@@ -1697,8 +1699,9 @@ RID RasterizerStorageGLES3::shader_get_default_texture_param(RID p_shader, const
/* COMMON MATERIAL API */
void RasterizerStorageGLES3::_material_make_dirty(Material *p_material) const {
- if (p_material->dirty_list.in_list())
+ if (p_material->dirty_list.in_list()) {
return;
+ }
_material_dirty_list.add(&p_material->dirty_list);
}
@@ -1954,8 +1957,9 @@ void RasterizerStorageGLES3::_update_material(Material *p_material) {
p_material->textures.resize(p_material->shader->texture_uniforms.size());
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_material->shader->uniforms.front(); E; E = E->next()) {
- if (E->get().texture_order < 0)
+ if (E->get().texture_order < 0) {
continue; // not a texture, does not go here
+ }
RID texture;
@@ -2909,7 +2913,7 @@ void RasterizerStorageGLES3::_set_current_render_target(RID p_render_target) {
_dims.win_height = rt->height;
} else {
- frame.current_rt = NULL;
+ frame.current_rt = nullptr;
frame.clear_request = false;
bind_framebuffer_system();
}
@@ -2917,8 +2921,9 @@ void RasterizerStorageGLES3::_set_current_render_target(RID p_render_target) {
void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
// do not allocate a render target with no size
- if (rt->width <= 0 || rt->height <= 0)
+ if (rt->width <= 0 || rt->height <= 0) {
return;
+ }
// do not allocate a render target that is attached to the screen
if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) {
@@ -2966,7 +2971,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glGenTextures(1, &rt->color);
glBindTexture(GL_TEXTURE_2D, rt->color);
- glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, nullptr);
if (texture->flags & TEXTURE_FLAG_FILTER) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -2986,7 +2991,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
if (config.support_depth_texture) {
glGenTextures(1, &rt->depth);
glBindTexture(GL_TEXTURE_2D, rt->depth);
- glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, config.depth_type, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, config.depth_type, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -3109,9 +3114,9 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glBindTexture(GL_TEXTURE_2D, rt->copy_screen_effect.color);
if (rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
} else {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rt->width, rt->height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rt->width, rt->height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -3159,8 +3164,9 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
w >>= 1;
h >>= 1;
- if (w < 2 || h < 2)
+ if (w < 2 || h < 2) {
break;
+ }
level++;
}
@@ -3173,7 +3179,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].color);
for (int l = 0; l < level + 1; l++) {
- glTexImage2D(GL_TEXTURE_2D, l, color_internal_format, width, height, 0, color_format, color_type, NULL);
+ glTexImage2D(GL_TEXTURE_2D, l, color_internal_format, width, height, 0, color_format, color_type, nullptr);
width = MAX(1, (width / 2));
height = MAX(1, (height / 2));
}
@@ -3186,7 +3192,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
for (int l = 0; l < level + 1; l++) {
glGenTextures(1, &rt->mip_maps[i].sizes.write[l].color);
glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].sizes[l].color);
- glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, width, height, 0, color_format, color_type, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, width, height, 0, color_format, color_type, nullptr);
width = MAX(1, (width / 2));
height = MAX(1, (height / 2));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -3255,8 +3261,9 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
// there is nothing to clear when DIRECT_TO_SCREEN is used
- if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN])
+ if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) {
return;
+ }
if (rt->fbo) {
glDeleteFramebuffers(1, &rt->fbo);
@@ -3373,8 +3380,9 @@ void RasterizerStorageGLES3::render_target_set_size(RID p_render_target, int p_w
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
- if (p_width == rt->width && p_height == rt->height)
+ if (p_width == rt->width && p_height == rt->height) {
return;
+ }
_render_target_clear(rt);
@@ -3561,8 +3569,9 @@ void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target, RS::Vie
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
- if (rt->msaa == p_msaa)
+ if (rt->msaa == p_msaa) {
return;
+ }
_render_target_clear(rt);
rt->msaa = p_msaa;
@@ -3638,8 +3647,9 @@ void RasterizerStorageGLES3::render_target_mark_sdf_enabled(RID p_render_target,
RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) {
CanvasLightShadow *cls = memnew(CanvasLightShadow);
- if (p_width > config.max_texture_size)
+ if (p_width > config.max_texture_size) {
p_width = config.max_texture_size;
+ }
cls->size = p_width;
cls->height = 16;
@@ -3657,10 +3667,10 @@ RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) {
glGenTextures(1, &cls->distance);
glBindTexture(GL_TEXTURE_2D, cls->distance);
if (config.use_rgba_2d_shadows) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cls->size, cls->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cls->size, cls->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
} else {
#ifdef GLES_OVER_GL
- glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, cls->size, cls->height, 0, _RED_OES, GL_FLOAT, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, cls->size, cls->height, 0, _RED_OES, GL_FLOAT, nullptr);
#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_FLOAT, cls->size, cls->height, 0, _RED_OES, GL_FLOAT, NULL);
#endif
@@ -3856,7 +3866,7 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
while (shader->materials.first()) {
Material *m = shader->materials.first()->self();
- m->shader = NULL;
+ m->shader = nullptr;
_material_make_dirty(m);
shader->materials.remove(shader->materials.first());
@@ -4248,7 +4258,7 @@ void RasterizerStorageGLES3::initialize() {
GLuint depth;
glGenTextures(1, &depth);
glBindTexture(GL_TEXTURE_2D, depth);
- glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, config.depth_type, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, config.depth_type, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -4280,7 +4290,7 @@ void RasterizerStorageGLES3::initialize() {
glGenTextures(1, &depth);
glBindTexture(GL_TEXTURE_2D, depth);
- glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -4308,7 +4318,7 @@ void RasterizerStorageGLES3::initialize() {
frame.count = 0;
frame.delta = 0;
- frame.current_rt = NULL;
+ frame.current_rt = nullptr;
frame.clear_request = false;
glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &config.max_vertex_texture_image_units);
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 4a4469d40a..0dfc909777 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -142,8 +142,8 @@ public:
} shaders;
struct Info {
- uint64_t texture_mem;
- uint64_t vertex_mem;
+ uint64_t texture_mem = 0;
+ uint64_t vertex_mem = 0;
struct Render {
uint32_t object_count;
@@ -167,9 +167,7 @@ public:
}
} render, render_final, snap;
- Info() :
- texture_mem(0),
- vertex_mem(0) {
+ Info() {
render.reset();
render_final.reset();
}
@@ -275,8 +273,9 @@ public:
// texture coords start from bottom left, means we need to draw render target textures upside down
// to be compatible with vulkan etc.
bool is_upside_down() const {
- if (proxy)
+ if (proxy) {
return proxy->is_upside_down();
+ }
return render_target != nullptr;
}
@@ -364,7 +363,7 @@ public:
images.clear();
for (Set<Texture *>::Element *E = proxy_owners.front(); E; E = E->next()) {
- E->get()->proxy = NULL;
+ E->get()->proxy = nullptr;
}
if (proxy) {
@@ -374,8 +373,9 @@ public:
// texture state
void GLSetFilter(GLenum p_target, RS::CanvasItemTextureFilter p_filter) {
- if (p_filter == state_filter)
+ if (p_filter == state_filter) {
return;
+ }
state_filter = p_filter;
GLint pmin = GL_LINEAR; // param min
GLint pmag = GL_LINEAR; // param mag
@@ -399,8 +399,9 @@ public:
glTexParameteri(p_target, GL_TEXTURE_MAG_FILTER, pmag);
}
void GLSetRepeat(GLenum p_target, RS::CanvasItemTextureRepeat p_repeat) {
- if (p_repeat == state_repeat)
+ if (p_repeat == state_repeat) {
return;
+ }
state_repeat = p_repeat;
GLint prep = GL_CLAMP_TO_EDGE; // parameter repeat
switch (state_repeat) {
@@ -637,7 +638,7 @@ public:
Shader() :
dirty_list(this) {
- shader = NULL;
+ shader = nullptr;
valid = false;
version = RID();
last_pass = 0;
@@ -697,7 +698,7 @@ public:
dirty_list(this) {
can_cast_shadow_cache = false;
is_animated_cache = false;
- shader = NULL;
+ shader = nullptr;
line_width = 1.0;
last_pass = 0;
render_priority = 0;
@@ -1151,27 +1152,23 @@ public:
struct RenderTarget {
RID self;
- GLuint fbo;
- GLuint color;
- GLuint depth;
+ GLuint fbo = 0;
+ GLuint color = 0;
+ GLuint depth = 0;
- GLuint multisample_fbo;
- GLuint multisample_color;
- GLuint multisample_depth;
- bool multisample_active;
+ GLuint multisample_fbo = 0;
+ GLuint multisample_color = 0;
+ GLuint multisample_depth = 0;
+ bool multisample_active = false;
struct Effect {
- GLuint fbo;
- int width;
- int height;
+ GLuint fbo = 0;
+ int width = 0;
+ int height = 0;
- GLuint color;
+ GLuint color = 0;
- Effect() :
- fbo(0),
- width(0),
- height(0),
- color(0) {
+ Effect() {
}
};
@@ -1186,71 +1183,47 @@ public:
};
Vector<Size> sizes;
- GLuint color;
- int levels;
+ GLuint color = 0;
+ int levels = 0;
- MipMaps() :
- color(0),
- levels(0) {
+ MipMaps() {
}
};
MipMaps mip_maps[2];
struct External {
- GLuint fbo;
- GLuint color;
- GLuint depth;
+ GLuint fbo = 0;
+ GLuint color = 0;
+ GLuint depth = 0;
RID texture;
- External() :
- fbo(0),
- color(0),
- depth(0) {
+ External() {
}
} external;
- int x, y, width, height;
+ int x = 0, y = 0, width = 0, height = 0;
bool flags[RENDER_TARGET_FLAG_MAX];
// instead of allocating sized render targets immediately,
// defer this for faster startup
bool allocate_is_dirty = false;
- bool used_in_frame;
- RS::ViewportMSAA msaa;
+ bool used_in_frame = false;
+ RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED;
- bool use_fxaa;
- bool use_debanding;
+ bool use_fxaa = false;
+ bool use_debanding = false;
RID texture;
- bool used_dof_blur_near;
- bool mip_maps_allocated;
-
- Color clear_color;
- bool clear_requested;
-
- RenderTarget() :
- fbo(0),
- color(0),
- depth(0),
- multisample_fbo(0),
- multisample_color(0),
- multisample_depth(0),
- multisample_active(false),
- x(0),
- y(0),
- width(0),
- height(0),
- used_in_frame(false),
- msaa(RS::VIEWPORT_MSAA_DISABLED),
- use_fxaa(false),
- use_debanding(false),
- used_dof_blur_near(false),
- mip_maps_allocated(false),
- clear_color(Color(1, 1, 1, 1)),
- clear_requested(false) {
+ bool used_dof_blur_near = false;
+ bool mip_maps_allocated = false;
+
+ Color clear_color = Color(1, 1, 1, 1);
+ bool clear_requested = false;
+
+ RenderTarget() {
for (int i = 0; i < RENDER_TARGET_FLAG_MAX; ++i) {
flags[i] = false;
}
@@ -1427,8 +1400,9 @@ inline bool RasterizerStorageGLES3::safe_buffer_sub_data(unsigned int p_total_bu
r_offset_after = p_offset + p_data_size;
#ifdef DEBUG_ENABLED
// we are trying to write across the edge of the buffer
- if (r_offset_after > p_total_buffer_size)
+ if (r_offset_after > p_total_buffer_size) {
return false;
+ }
#endif
glBufferSubData(p_target, p_offset, p_data_size, p_data);
return true;
@@ -1440,7 +1414,7 @@ inline void RasterizerStorageGLES3::buffer_orphan_and_upload(unsigned int p_buff
// Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
// Was previously #ifndef GLES_OVER_GL however this causes stalls on desktop mac also (and possibly other)
if (!p_optional_orphan || (config.should_orphan)) {
- glBufferData(p_target, p_buffer_size, NULL, p_usage);
+ glBufferData(p_target, p_buffer_size, nullptr, p_usage);
#ifdef RASTERIZER_EXTRA_CHECKS
// fill with garbage off the end of the array
if (p_buffer_size) {
diff --git a/drivers/gles3/texture_loader_gles3.cpp b/drivers/gles3/texture_loader_gles3.cpp
index e16e4fe254..1cbda02121 100644
--- a/drivers/gles3/texture_loader_gles3.cpp
+++ b/drivers/gles3/texture_loader_gles3.cpp
@@ -61,8 +61,9 @@ RES ResourceFormatGLES2Texture::load(const String &p_path, const String &p_origi
Ref<ImageTexture> texture = memnew(ImageTexture);
texture->create_from_image(img);
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
return texture;
}
diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp
index 400dc25f11..d82dcb8a8d 100644
--- a/drivers/unix/ip_unix.cpp
+++ b/drivers/unix/ip_unix.cpp
@@ -115,7 +115,7 @@ void IPUnix::_resolve_hostname(List<IPAddress> &r_addresses, const String &p_hos
continue;
}
IPAddress ip = _sockaddr2ip(next->ai_addr);
- if (!r_addresses.find(ip)) {
+ if (ip.is_valid() && !r_addresses.find(ip)) {
r_addresses.push_back(ip);
}
next = next->ai_next;
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index e5d577a79f..44455b927b 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -538,7 +538,7 @@ Error VulkanContext::_check_capabilities() {
VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_features;
shader_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
- shader_features.pNext = NULL;
+ shader_features.pNext = nullptr;
device_features.pNext = &shader_features;
@@ -547,7 +547,7 @@ Error VulkanContext::_check_capabilities() {
VkPhysicalDevice16BitStorageFeaturesKHR storage_feature;
storage_feature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR;
- storage_feature.pNext = NULL;
+ storage_feature.pNext = nullptr;
device_features.pNext = &storage_feature;
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp
index 6cd21b5615..6f3bad12c1 100644
--- a/drivers/windows/dir_access_windows.cpp
+++ b/drivers/windows/dir_access_windows.cpp
@@ -165,8 +165,11 @@ Error DirAccessWindows::make_dir(String p_dir) {
bool success;
int err;
- p_dir = "\\\\?\\" + p_dir; //done according to
- // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx
+ if (!p_dir.is_network_share_path()) {
+ p_dir = "\\\\?\\" + p_dir;
+ // Add "\\?\" to the path to extend max. path length past 248, if it's not a network share UNC path.
+ // See https://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx
+ }
success = CreateDirectoryW((LPCWSTR)(p_dir.utf16().get_data()), nullptr);
err = GetLastError();
@@ -349,6 +352,10 @@ String DirAccessWindows::get_filesystem_type() const {
ERR_FAIL_COND_V(unit_end == -1, String());
String unit = path.substr(0, unit_end + 1) + "\\";
+ if (path.is_network_share_path()) {
+ return "Network Share";
+ }
+
WCHAR szVolumeName[100];
WCHAR szFileSystemName[10];
DWORD dwSerialNumber = 0;
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index dbbdd85706..e36d0b846b 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -3289,7 +3289,7 @@ AnimationTrackEditGroup::AnimationTrackEditGroup() {
//////////////////////////////////////
void AnimationTrackEditor::add_track_edit_plugin(const Ref<AnimationTrackEditPlugin> &p_plugin) {
- if (track_edit_plugins.find(p_plugin) != -1) {
+ if (track_edit_plugins.has(p_plugin)) {
return;
}
track_edit_plugins.push_back(p_plugin);
@@ -3481,7 +3481,7 @@ void AnimationTrackEditor::_track_remove_request(int p_track) {
void AnimationTrackEditor::_track_grab_focus(int p_track) {
// Don't steal focus if not working with the track editor.
- if (Object::cast_to<AnimationTrackEdit>(get_focus_owner())) {
+ if (Object::cast_to<AnimationTrackEdit>(get_viewport()->gui_get_focus_owner())) {
track_edits[p_track]->grab_focus();
}
}
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index fb36bfc5e5..967f7e0d1f 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -122,7 +122,7 @@ void FindReplaceBar::unhandled_input(const Ref<InputEvent> &p_event) {
return;
}
- Control *focus_owner = get_focus_owner();
+ Control *focus_owner = get_viewport()->gui_get_focus_owner();
if (text_editor->has_focus() || (focus_owner && vbc_lineedit->is_ancestor_of(focus_owner))) {
bool accepted = true;
@@ -724,7 +724,7 @@ void CodeTextEditor::input(const Ref<InputEvent> &event) {
}
if (!text_editor->has_focus()) {
- if ((find_replace_bar != nullptr && find_replace_bar->is_visible()) && (find_replace_bar->has_focus() || find_replace_bar->is_ancestor_of(get_focus_owner()))) {
+ if ((find_replace_bar != nullptr && find_replace_bar->is_visible()) && (find_replace_bar->has_focus() || find_replace_bar->is_ancestor_of(get_viewport()->gui_get_focus_owner()))) {
if (ED_IS_SHORTCUT("script_text_editor/find_next", key_event)) {
find_replace_bar->search_next();
accept_event();
@@ -1663,17 +1663,29 @@ void CodeTextEditor::_error_pressed(const Ref<InputEvent> &p_event) {
void CodeTextEditor::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
+ error_button->set_icon(get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons")));
+ error_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor")));
+ error_button->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
+ error_button->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
+
+ warning_button->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")));
+ warning_button->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor")));
+ warning_button->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
+ warning_button->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
+
+ line_and_col_txt->add_theme_font_override("font", get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
+ line_and_col_txt->add_theme_font_size_override("font_size", get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
+
+ if (p_what == NOTIFICATION_ENTER_TREE) {
+ break;
+ }
if (toggle_scripts_button->is_visible()) {
update_toggle_scripts_button();
}
_update_text_editor_theme();
} break;
- case NOTIFICATION_ENTER_TREE: {
- error_button->set_icon(get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons")));
- warning_button->set_icon(get_theme_icon(SNAME("NodeWarning"), SNAME("EditorIcons")));
- add_theme_constant_override("separation", 4 * EDSCALE);
- } break;
case NOTIFICATION_VISIBILITY_CHANGED: {
if (toggle_scripts_button->is_visible()) {
update_toggle_scripts_button();
@@ -1874,10 +1886,6 @@ CodeTextEditor::CodeTextEditor() {
error_button->connect("pressed", callable_mp(this, &CodeTextEditor::_error_button_pressed));
error_button->set_tooltip(TTR("Errors"));
- error_button->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor")));
- error_button->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
- error_button->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
-
is_errors_panel_opened = false;
set_error_count(0);
@@ -1890,10 +1898,6 @@ CodeTextEditor::CodeTextEditor() {
warning_button->connect("pressed", callable_mp(this, &CodeTextEditor::_warning_button_pressed));
warning_button->set_tooltip(TTR("Warnings"));
- warning_button->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor")));
- warning_button->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
- warning_button->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
-
is_warnings_panel_opened = false;
set_warning_count(0);
@@ -1901,8 +1905,6 @@ CodeTextEditor::CodeTextEditor() {
line_and_col_txt = memnew(Label);
status_bar->add_child(line_and_col_txt);
line_and_col_txt->set_v_size_flags(SIZE_EXPAND | SIZE_SHRINK_CENTER);
- line_and_col_txt->add_theme_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_theme_font(SNAME("status_source"), SNAME("EditorFonts")));
- line_and_col_txt->add_theme_font_size_override("font_size", EditorNode::get_singleton()->get_gui_base()->get_theme_font_size(SNAME("status_source_size"), SNAME("EditorFonts")));
line_and_col_txt->set_tooltip(TTR("Line and column numbers."));
line_and_col_txt->set_mouse_filter(MOUSE_FILTER_STOP);
@@ -1933,4 +1935,5 @@ CodeTextEditor::CodeTextEditor() {
font_resize_timer->connect("timeout", callable_mp(this, &CodeTextEditor::_font_resize_timeout));
EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &CodeTextEditor::_on_settings_change));
+ add_theme_constant_override("separation", 4 * EDSCALE);
}
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index bda558bb72..1d5fa9cbbb 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -540,13 +540,27 @@ ConnectDialog::~ConnectDialog() {
// Originally copied and adapted from EditorProperty, try to keep style in sync.
Control *ConnectionsDockTree::make_custom_tooltip(const String &p_text) const {
EditorHelpBit *help_bit = memnew(EditorHelpBit);
- help_bit->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("TooltipPanel")));
help_bit->get_rich_text()->set_fixed_size_to_width(360 * EDSCALE);
- String text = TTR("Signal:") + " [u][b]" + p_text.get_slice("::", 0) + "[/b][/u]";
- text += p_text.get_slice("::", 1).strip_edges() + "\n";
- text += p_text.get_slice("::", 2).strip_edges();
- help_bit->call_deferred(SNAME("set_text"), text); // Hack so it uses proper theme once inside scene.
+ // p_text is expected to be something like this:
+ // "gui_input::(event: InputEvent)::<Signal description>"
+ // with the latter being possibly empty.
+ PackedStringArray slices = p_text.split("::", false);
+ if (slices.size() < 2) {
+ // Shouldn't happen here, but just in case pass the text along.
+ help_bit->set_text(p_text);
+ return help_bit;
+ }
+
+ String text = TTR("Signal:") + " [u][b]" + slices[0] + "[/b][/u]";
+ text += slices[1].strip_edges() + "\n";
+ if (slices.size() > 2) {
+ text += slices[2].strip_edges();
+ } else {
+ text += "[i]" + TTR("No description.") + "[/i]";
+ }
+ help_bit->set_text(text);
+
return help_bit;
}
@@ -1009,7 +1023,7 @@ void ConnectionsDock::update_tree() {
PackedStringArray argnames;
String filter_text = search_box->get_text();
- if (!filter_text.is_subsequence_ofi(signal_name)) {
+ if (!filter_text.is_subsequence_ofn(signal_name)) {
continue;
}
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index d0dfbc7c11..e8fd97fa1a 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -178,7 +178,7 @@ void CreateDialog::_update_search() {
// Filter all candidate results.
Vector<String> candidates;
for (List<StringName>::Element *I = type_list.front(); I; I = I->next()) {
- if (empty_search || search_text.is_subsequence_ofi(I->get())) {
+ if (empty_search || search_text.is_subsequence_ofn(I->get())) {
candidates.push_back(I->get());
}
}
@@ -467,7 +467,7 @@ void CreateDialog::select_type(const String &p_type) {
}
favorite->set_disabled(false);
- favorite->set_pressed(favorite_list.find(p_type) != -1);
+ favorite->set_pressed(favorite_list.has(p_type));
get_ok_button()->set_disabled(false);
}
@@ -539,12 +539,12 @@ void CreateDialog::_favorite_toggled() {
String name = item->get_text(0);
- if (favorite_list.find(name) == -1) {
- favorite_list.push_back(name);
- favorite->set_pressed(true);
- } else {
+ if (favorite_list.has(name)) {
favorite_list.erase(name);
favorite->set_pressed(false);
+ } else {
+ favorite_list.push_back(name);
+ favorite->set_pressed(true);
}
_save_and_update_favorite_list();
diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp
index 29d0014b8a..41f4db541d 100644
--- a/editor/debugger/editor_debugger_tree.cpp
+++ b/editor/debugger/editor_debugger_tree.cpp
@@ -186,7 +186,7 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int
// Apply filters.
while (parent) {
const bool had_siblings = item->get_prev() || item->get_next();
- if (filter.is_subsequence_ofi(item->get_text(0))) {
+ if (filter.is_subsequence_ofn(item->get_text(0))) {
break; // Filter matches, must survive.
}
parent->remove_child(item);
diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp
index d5e825a26c..da1d6a54f2 100644
--- a/editor/debugger/editor_profiler.cpp
+++ b/editor/debugger/editor_profiler.cpp
@@ -456,8 +456,9 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
if (mb.is_valid() || (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) {
updating_frame = true;
- if (x < total_metrics)
+ if (x < total_metrics) {
cursor_metric_edit->set_value(_get_frame_metric(x).frame_number);
+ }
updating_frame = false;
if (activate->is_pressed()) {
diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp
index 6acf654b04..749ab7e2f6 100644
--- a/editor/doc_tools.cpp
+++ b/editor/doc_tools.cpp
@@ -534,11 +534,11 @@ void DocTools::generate(bool p_basic_types) {
Vector<Error> errs = ClassDB::get_method_error_return_values(name, E.name);
if (errs.size()) {
- if (errs.find(OK) == -1) {
+ if (!errs.has(OK)) {
errs.insert(0, OK);
}
for (int i = 0; i < errs.size(); i++) {
- if (method.errors_returned.find(errs[i]) == -1) {
+ if (!method.errors_returned.has(errs[i])) {
method.errors_returned.push_back(errs[i]);
}
}
diff --git a/editor/editor_command_palette.cpp b/editor/editor_command_palette.cpp
index 1724e87489..d13d1a6c68 100644
--- a/editor/editor_command_palette.cpp
+++ b/editor/editor_command_palette.cpp
@@ -72,7 +72,7 @@ void EditorCommandPalette::_update_command_search(const String &search_text) {
r.shortcut_text = commands[r.key_name].shortcut;
r.last_used = commands[r.key_name].last_used;
- if (search_text.is_subsequence_ofi(r.display_name)) {
+ if (search_text.is_subsequence_ofn(r.display_name)) {
if (!search_text.is_empty()) {
r.score = _score_path(search_text, r.display_name.to_lower());
}
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index f97973ce5d..792897e451 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -1525,7 +1525,7 @@ void EditorExport::remove_export_preset(int p_idx) {
}
void EditorExport::add_export_plugin(const Ref<EditorExportPlugin> &p_plugin) {
- if (export_plugins.find(p_plugin) == -1) {
+ if (!export_plugins.has(p_plugin)) {
export_plugins.push_back(p_plugin);
}
}
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 33c6c77e53..b6d8ea5bd6 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -230,7 +230,14 @@ Vector<String> EditorFileDialog::get_selected_files() const {
void EditorFileDialog::update_dir() {
if (drives->is_visible()) {
- drives->select(dir_access->get_current_drive());
+ if (dir_access->get_current_dir().is_network_share_path()) {
+ _update_drives(false);
+ drives->add_item(RTR("Network"));
+ drives->set_item_disabled(drives->get_item_count() - 1, true);
+ drives->select(drives->get_item_count() - 1);
+ } else {
+ drives->select(dir_access->get_current_drive());
+ }
}
dir->set_text(dir_access->get_current_dir(false));
@@ -1152,7 +1159,7 @@ void EditorFileDialog::_select_drive(int p_idx) {
_push_history();
}
-void EditorFileDialog::_update_drives() {
+void EditorFileDialog::_update_drives(bool p_select) {
int dc = dir_access->get_drive_count();
if (dc == 0 || access != ACCESS_FILESYSTEM) {
drives->hide();
@@ -1170,8 +1177,9 @@ void EditorFileDialog::_update_drives() {
String d = dir_access->get_drive(i);
drives->add_item(dir_access->get_drive(i));
}
-
- drives->select(dir_access->get_current_drive());
+ if (p_select) {
+ drives->select(dir_access->get_current_drive());
+ }
}
}
diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h
index 16077cbfb9..6cfdf53780 100644
--- a/editor/editor_file_dialog.h
+++ b/editor/editor_file_dialog.h
@@ -180,7 +180,7 @@ private:
void _delete_items();
- void _update_drives();
+ void _update_drives(bool p_select = true);
void _go_up();
void _go_back();
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 6d5e56184a..bb76af8f9b 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -163,14 +163,14 @@ void EditorHelp::_class_desc_select(const String &p_select) {
void EditorHelp::_class_desc_input(const Ref<InputEvent> &p_input) {
}
-void EditorHelp::_class_desc_resized() {
+void EditorHelp::_class_desc_resized(bool p_force_update_theme) {
// Add extra horizontal margins for better readability.
// The margins increase as the width of the editor help container increases.
Ref<Font> doc_code_font = get_theme_font(SNAME("doc_source"), SNAME("EditorFonts"));
int font_size = get_theme_font_size(SNAME("doc_source_size"), SNAME("EditorFonts"));
real_t char_width = doc_code_font->get_char_size('x', 0, font_size).width;
const int new_display_margin = MAX(30 * EDSCALE, get_parent_anchorable_rect().size.width - char_width * 120 * EDSCALE) * 0.5;
- if (display_margin != new_display_margin) {
+ if (display_margin != new_display_margin || p_force_update_theme) {
display_margin = new_display_margin;
Ref<StyleBox> class_desc_stylebox = EditorNode::get_singleton()->get_theme_base()->get_theme_stylebox(SNAME("normal"), SNAME("RichTextLabel"))->duplicate();
@@ -1772,7 +1772,7 @@ void EditorHelp::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
if (is_inside_tree()) {
- _class_desc_resized();
+ _class_desc_resized(true);
}
update_toggle_scripts_button();
} break;
@@ -1876,8 +1876,8 @@ EditorHelp::EditorHelp() {
class_desc->connect("meta_clicked", callable_mp(this, &EditorHelp::_class_desc_select));
class_desc->connect("gui_input", callable_mp(this, &EditorHelp::_class_desc_input));
- class_desc->connect("resized", callable_mp(this, &EditorHelp::_class_desc_resized));
- _class_desc_resized();
+ class_desc->connect("resized", callable_mp(this, &EditorHelp::_class_desc_resized), varray(false));
+ _class_desc_resized(false);
// Added second so it opens at the bottom so it won't offset the entire widget.
find_bar = memnew(FindBar);
@@ -1910,6 +1910,8 @@ DocTools *EditorHelp::get_doc_data() {
return doc;
}
+//// EditorHelpBit ///
+
void EditorHelpBit::_go_to_help(String p_what) {
EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
ScriptEditor::get_singleton()->goto_help(p_what);
@@ -1950,12 +1952,9 @@ void EditorHelpBit::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
rich_text->add_theme_color_override("selection_color", get_theme_color(SNAME("selection_color"), SNAME("EditorHelp")));
- } break;
-
- case NOTIFICATION_READY: {
rich_text->clear();
_add_text_to_rt(text, rich_text);
-
+ rich_text->reset_size(); // Force recalculating size after parsing bbcode.
} break;
}
}
@@ -1971,9 +1970,12 @@ EditorHelpBit::EditorHelpBit() {
add_child(rich_text);
rich_text->connect("meta_clicked", callable_mp(this, &EditorHelpBit::_meta_clicked));
rich_text->set_override_selected_font_color(false);
- set_custom_minimum_size(Size2(0, 70 * EDSCALE));
+ rich_text->set_fit_content_height(true);
+ set_custom_minimum_size(Size2(0, 50 * EDSCALE));
}
+//// FindBar ///
+
FindBar::FindBar() {
search_text = memnew(LineEdit);
add_child(search_text);
@@ -2126,7 +2128,7 @@ void FindBar::unhandled_input(const Ref<InputEvent> &p_event) {
Ref<InputEventKey> k = p_event;
if (k.is_valid()) {
- if (k->is_pressed() && (rich_text_label->has_focus() || is_ancestor_of(get_focus_owner()))) {
+ if (k->is_pressed() && (rich_text_label->has_focus() || is_ancestor_of(get_viewport()->gui_get_focus_owner()))) {
bool accepted = true;
switch (k->get_keycode()) {
diff --git a/editor/editor_help.h b/editor/editor_help.h
index 237cf4f347..10281a764c 100644
--- a/editor/editor_help.h
+++ b/editor/editor_help.h
@@ -155,7 +155,7 @@ class EditorHelp : public VBoxContainer {
void _class_list_select(const String &p_select);
void _class_desc_select(const String &p_select);
void _class_desc_input(const Ref<InputEvent> &p_input);
- void _class_desc_resized();
+ void _class_desc_resized(bool p_force_update_theme);
int display_margin = 0;
Error _goto_desc(const String &p_class, int p_vscr = -1);
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index a3538d3381..6f7508b10b 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -833,30 +833,42 @@ void EditorProperty::_update_pin_flags() {
}
}
-Control *EditorProperty::make_custom_tooltip(const String &p_text) const {
- tooltip_text = p_text;
+static Control *make_help_bit(const String &p_text, bool p_property) {
EditorHelpBit *help_bit = memnew(EditorHelpBit);
- //help_bit->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("TooltipPanel")));
help_bit->get_rich_text()->set_fixed_size_to_width(360 * EDSCALE);
- String text;
PackedStringArray slices = p_text.split("::", false);
- if (!slices.is_empty()) {
- String property_name = slices[0].strip_edges();
- text = TTR("Property:") + " [u][b]" + property_name + "[/b][/u]";
+ if (slices.is_empty()) {
+ // Shouldn't happen here, but just in case pass the text along.
+ help_bit->set_text(p_text);
+ return help_bit;
+ }
- if (slices.size() > 1) {
- String property_doc = slices[1].strip_edges();
- if (property_name != property_doc) {
- text += "\n" + property_doc;
- }
+ String property_name = slices[0].strip_edges();
+ String text;
+ if (p_property) {
+ text = TTR("Property:") + " ";
+ }
+ text += "[u][b]" + property_name + "[/b][/u]";
+
+ if (slices.size() > 1) {
+ String property_doc = slices[1].strip_edges();
+ if (property_name != property_doc) {
+ text += "\n" + property_doc;
}
- help_bit->call_deferred(SNAME("set_text"), text); //hack so it uses proper theme once inside scene
+ } else {
+ text += "\n[i]" + TTR("No description.") + "[/i]";
}
+ help_bit->set_text(text);
return help_bit;
}
+Control *EditorProperty::make_custom_tooltip(const String &p_text) const {
+ tooltip_text = p_text;
+ return make_help_bit(p_text, true);
+}
+
String EditorProperty::get_tooltip_text() const {
return tooltip_text;
}
@@ -919,6 +931,7 @@ void EditorProperty::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_warning"), "set_draw_warning", "is_draw_warning");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keying"), "set_keying", "is_keying");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deletable"), "set_deletable", "is_deletable");
+
ADD_SIGNAL(MethodInfo("property_changed", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
ADD_SIGNAL(MethodInfo("multiple_properties_changed", PropertyInfo(Variant::PACKED_STRING_ARRAY, "properties"), PropertyInfo(Variant::ARRAY, "value")));
ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING_NAME, "property")));
@@ -1093,25 +1106,7 @@ void EditorInspectorCategory::_notification(int p_what) {
Control *EditorInspectorCategory::make_custom_tooltip(const String &p_text) const {
tooltip_text = p_text;
- EditorHelpBit *help_bit = memnew(EditorHelpBit);
- help_bit->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("TooltipPanel")));
- help_bit->get_rich_text()->set_fixed_size_to_width(360 * EDSCALE);
-
- PackedStringArray slices = p_text.split("::", false);
- if (!slices.is_empty()) {
- String property_name = slices[0].strip_edges();
- String text = "[u][b]" + property_name + "[/b][/u]";
-
- if (slices.size() > 1) {
- String property_doc = slices[1].strip_edges();
- if (property_name != property_doc) {
- text += "\n" + property_doc;
- }
- }
- help_bit->call_deferred(SNAME("set_text"), text); //hack so it uses proper theme once inside scene
- }
-
- return help_bit;
+ return make_help_bit(p_text, false);
}
Size2 EditorInspectorCategory::get_minimum_size() const {
@@ -2304,7 +2299,7 @@ void EditorInspector::update_tree() {
if (property_focusable != -1) {
//check focusable is really focusable
bool restore_focus = false;
- Control *focused = get_focus_owner();
+ Control *focused = get_viewport() ? get_viewport()->gui_get_focus_owner() : nullptr;
if (focused) {
Node *parent = focused->get_parent();
while (parent) {
@@ -2595,7 +2590,7 @@ void EditorInspector::update_tree() {
// Ignore properties that do not fit the filter.
if (use_filter && !filter.is_empty()) {
- if (!filter.is_subsequence_ofi(path) && !filter.is_subsequence_ofi(property_label_string) && property_prefix.to_lower().find(filter.to_lower()) == -1) {
+ if (!filter.is_subsequence_ofn(path) && !filter.is_subsequence_ofn(property_label_string) && property_prefix.to_lower().find(filter.to_lower()) == -1) {
continue;
}
}
@@ -3543,7 +3538,7 @@ void EditorInspector::_bind_methods() {
ADD_SIGNAL(MethodInfo("property_selected", PropertyInfo(Variant::STRING, "property")));
ADD_SIGNAL(MethodInfo("property_keyed", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), PropertyInfo(Variant::BOOL, "advance")));
ADD_SIGNAL(MethodInfo("property_deleted", PropertyInfo(Variant::STRING, "property")));
- ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::OBJECT, "res"), PropertyInfo(Variant::STRING, "prop")));
+ ADD_SIGNAL(MethodInfo("resource_selected", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), PropertyInfo(Variant::STRING, "path")));
ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("property_edited", PropertyInfo(Variant::STRING, "property")));
ADD_SIGNAL(MethodInfo("property_toggled", PropertyInfo(Variant::STRING, "property"), PropertyInfo(Variant::BOOL, "checked")));
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index a1f259c864..076a774efa 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -93,6 +93,7 @@
#include "editor/editor_run_script.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
+#include "editor/editor_settings_dialog.h"
#include "editor/editor_spin_slider.h"
#include "editor/editor_themes.h"
#include "editor/editor_toaster.h"
@@ -190,7 +191,6 @@
#include "editor/project_settings_editor.h"
#include "editor/quick_open.h"
#include "editor/register_exporters.h"
-#include "editor/settings_config_dialog.h"
#include <stdio.h>
#include <stdlib.h>
@@ -340,7 +340,7 @@ void EditorNode::_update_scene_tabs() {
}
if (show_rb && editor_data.get_scene_root_script(i).is_valid()) {
- scene_tabs->set_tab_right_button(i, script_icon);
+ scene_tabs->set_tab_button_icon(i, script_icon);
}
}
@@ -822,8 +822,8 @@ void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_nam
if (p_activate_name.length()) {
set_addon_plugin_enabled(p_activate_name, true);
}
- project_settings->update_plugins();
- project_settings->hide();
+ project_settings_editor->update_plugins();
+ project_settings_editor->hide();
push_item(script.operator->());
}
@@ -2773,7 +2773,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case RUN_SETTINGS: {
- project_settings->popup_project_settings();
+ project_settings_editor->popup_project_settings();
} break;
case FILE_INSTALL_ANDROID_SOURCE: {
if (p_confirmed) {
@@ -2846,7 +2846,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
_update_update_spinner();
} break;
case SETTINGS_PREFERENCES: {
- settings_config_dialog->popup_edit_settings();
+ editor_settings_dialog->popup_edit_settings();
} break;
case SETTINGS_EDITOR_DATA_FOLDER: {
OS::get_singleton()->shell_open(String("file://") + EditorPaths::get_singleton()->get_data_dir());
@@ -3240,7 +3240,7 @@ void EditorNode::_update_addon_config() {
ProjectSettings::get_singleton()->set("editor_plugins/enabled", enabled_addons);
}
- project_settings->queue_save();
+ project_settings_editor->queue_save();
}
void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled, bool p_config_changed) {
@@ -3725,7 +3725,7 @@ void EditorNode::_show_messages() {
void EditorNode::_add_to_recent_scenes(const String &p_scene) {
Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scenes", Array());
- if (rc.find(p_scene) != -1) {
+ if (rc.has(p_scene)) {
rc.erase(p_scene);
}
rc.push_front(p_scene);
@@ -4222,6 +4222,8 @@ void EditorNode::_dock_floating_close_request(Control *p_control) {
_update_dock_containers();
floating_docks.erase(p_control);
+
+ _edit_current();
}
void EditorNode::_dock_make_float() {
@@ -4264,6 +4266,8 @@ void EditorNode::_dock_make_float() {
_update_dock_containers();
floating_docks.push_back(dock);
+
+ _edit_current();
}
void EditorNode::_update_dock_containers() {
@@ -6233,7 +6237,7 @@ EditorNode::EditorNode() {
scene_tabs->set_min_width(int(EDITOR_DEF("interface/scene_tabs/minimum_width", 50)) * EDSCALE);
scene_tabs->set_drag_to_rearrange_enabled(true);
scene_tabs->connect("tab_changed", callable_mp(this, &EditorNode::_scene_tab_changed));
- scene_tabs->connect("tab_rmb_clicked", callable_mp(this, &EditorNode::_scene_tab_script_edited));
+ scene_tabs->connect("tab_button_pressed", callable_mp(this, &EditorNode::_scene_tab_script_edited));
scene_tabs->connect("tab_close_pressed", callable_mp(this, &EditorNode::_scene_tab_closed), varray(SCENE_TAB_CLOSE));
scene_tabs->connect("tab_hovered", callable_mp(this, &EditorNode::_scene_tab_hovered));
scene_tabs->connect("mouse_exited", callable_mp(this, &EditorNode::_scene_tab_exit));
@@ -6325,11 +6329,11 @@ EditorNode::EditorNode() {
dependency_fixer = memnew(DependencyEditor);
gui_base->add_child(dependency_fixer);
- settings_config_dialog = memnew(EditorSettingsDialog);
- gui_base->add_child(settings_config_dialog);
+ editor_settings_dialog = memnew(EditorSettingsDialog);
+ gui_base->add_child(editor_settings_dialog);
- project_settings = memnew(ProjectSettingsEditor(&editor_data));
- gui_base->add_child(project_settings);
+ project_settings_editor = memnew(ProjectSettingsEditor(&editor_data));
+ gui_base->add_child(project_settings_editor);
scene_import_settings = memnew(SceneImportSettings);
gui_base->add_child(scene_import_settings);
diff --git a/editor/editor_node.h b/editor/editor_node.h
index f8489777bd..5c013a18d9 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -323,8 +323,8 @@ private:
ConfirmationDialog *install_android_build_template;
ConfirmationDialog *remove_android_build_template;
- EditorSettingsDialog *settings_config_dialog;
- ProjectSettingsEditor *project_settings;
+ EditorSettingsDialog *editor_settings_dialog;
+ ProjectSettingsEditor *project_settings_editor;
bool settings_changed = true; // make it update settings on first frame
void _update_from_settings();
@@ -713,7 +713,7 @@ public:
EditorPluginList *get_editor_plugins_force_over() { return editor_plugins_force_over; }
EditorPluginList *get_editor_plugins_force_input_forwarding() { return editor_plugins_force_input_forwarding; }
- ProjectSettingsEditor *get_project_settings() { return project_settings; }
+ ProjectSettingsEditor *get_project_settings() { return project_settings_editor; }
static void add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed = false);
static void remove_editor_plugin(EditorPlugin *p_editor, bool p_config_changed = false);
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 29f6079fcf..a1c031aa1b 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -513,11 +513,9 @@ void EditorPlugin::add_tool_menu_item(const String &p_name, const Callable &p_ca
EditorNode::get_singleton()->add_tool_menu_item(p_name, p_callable);
}
-void EditorPlugin::add_tool_submenu_item(const String &p_name, Object *p_submenu) {
+void EditorPlugin::add_tool_submenu_item(const String &p_name, PopupMenu *p_submenu) {
ERR_FAIL_NULL(p_submenu);
- PopupMenu *submenu = Object::cast_to<PopupMenu>(p_submenu);
- ERR_FAIL_NULL(submenu);
- EditorNode::get_singleton()->add_tool_submenu_item(p_name, submenu);
+ EditorNode::get_singleton()->add_tool_submenu_item(p_name, p_submenu);
}
void EditorPlugin::remove_tool_menu_item(const String &p_name) {
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index faa8ae1ce6..06517190f6 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -42,6 +42,7 @@
#include "scene/3d/camera_3d.h"
#include "scene/main/node.h"
#include "scene/resources/texture.h"
+
class EditorNode;
class Node3D;
class Camera3D;
@@ -217,7 +218,7 @@ public:
void remove_control_from_bottom_panel(Control *p_control);
void add_tool_menu_item(const String &p_name, const Callable &p_callable);
- void add_tool_submenu_item(const String &p_name, Object *p_submenu);
+ void add_tool_submenu_item(const String &p_name, PopupMenu *p_submenu);
void remove_tool_menu_item(const String &p_name);
void set_input_event_forwarding_always_enabled();
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 6bb4b5e81b..5ff83649c0 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -791,261 +791,293 @@ EditorPropertyFlags::EditorPropertyFlags() {
///////////////////// LAYERS /////////////////////////
-class EditorPropertyLayersGrid : public Control {
- GDCLASS(EditorPropertyLayersGrid, Control);
-
-private:
- Vector<Rect2> flag_rects;
- Rect2 expand_rect;
- bool expand_hovered = false;
- bool expanded = false;
- int expansion_rows = 0;
- int hovered_index = -1;
- bool read_only = false;
+void EditorPropertyLayersGrid::_rename_pressed(int p_menu) {
+ // Show rename popup for active layer.
+ if (renamed_layer_index == -1) {
+ return;
+ }
+ String name = names[renamed_layer_index];
+ rename_dialog->set_title(vformat(TTR("Renaming layer %d:"), renamed_layer_index + 1));
+ rename_dialog_text->set_text(name);
+ rename_dialog_text->select(0, name.length());
+ rename_dialog->popup_centered(Size2(300, 80) * EDSCALE);
+ rename_dialog_text->grab_focus();
+}
- Size2 get_grid_size() const {
- Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
- int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
- return Vector2(0, font->get_height(font_size) * 3);
+void EditorPropertyLayersGrid::_rename_operation_confirm() {
+ String new_name = rename_dialog_text->get_text().strip_edges();
+ if (new_name.length() == 0) {
+ EditorNode::get_singleton()->show_warning(TTR("No name provided."));
+ return;
+ } else if (new_name.find("/") != -1 || new_name.find("\\") != -1 || new_name.find(":") != -1) {
+ EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters."));
+ return;
}
+ names.set(renamed_layer_index, new_name);
+ tooltips.set(renamed_layer_index, new_name + "\n" + vformat(TTR("Bit %d, value %d"), renamed_layer_index, 1 << renamed_layer_index));
+ emit_signal(SNAME("rename_confirmed"), renamed_layer_index, new_name);
+}
+
+EditorPropertyLayersGrid::EditorPropertyLayersGrid() {
+ rename_dialog = memnew(ConfirmationDialog);
+ VBoxContainer *rename_dialog_vb = memnew(VBoxContainer);
+ rename_dialog->add_child(rename_dialog_vb);
+ rename_dialog_text = memnew(LineEdit);
+ rename_dialog_vb->add_margin_child(TTR("Name:"), rename_dialog_text);
+ rename_dialog->get_ok_button()->set_text(TTR("Rename"));
+ add_child(rename_dialog);
+ rename_dialog->register_text_enter(rename_dialog_text);
+ rename_dialog->connect("confirmed", callable_mp(this, &EditorPropertyLayersGrid::_rename_operation_confirm));
+ layer_rename = memnew(PopupMenu);
+ layer_rename->add_item(TTR("Rename layer"), 0);
+ add_child(layer_rename);
+ layer_rename->connect("id_pressed", callable_mp(this, &EditorPropertyLayersGrid::_rename_pressed));
+}
+
+Size2 EditorPropertyLayersGrid::get_grid_size() const {
+ Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
+ int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
+ return Vector2(0, font->get_height(font_size) * 3);
+}
-public:
- uint32_t value = 0;
- int layer_group_size = 0;
- int layer_count = 0;
- Vector<String> names;
- Vector<String> tooltips;
+void EditorPropertyLayersGrid::set_read_only(bool p_read_only) {
+ read_only = p_read_only;
+}
- void set_read_only(bool p_read_only) {
- read_only = p_read_only;
+Size2 EditorPropertyLayersGrid::get_minimum_size() const {
+ Size2 min_size = get_grid_size();
+
+ // Add extra rows when expanded.
+ if (expanded) {
+ const int bsize = (min_size.height * 80 / 100) / 2;
+ for (int i = 0; i < expansion_rows; ++i) {
+ min_size.y += 2 * (bsize + 1) + 3;
+ }
}
- virtual Size2 get_minimum_size() const override {
- Size2 min_size = get_grid_size();
+ return min_size;
+}
- // Add extra rows when expanded.
- if (expanded) {
- const int bsize = (min_size.height * 80 / 100) / 2;
- for (int i = 0; i < expansion_rows; ++i) {
- min_size.y += 2 * (bsize + 1) + 3;
- }
+String EditorPropertyLayersGrid::get_tooltip(const Point2 &p_pos) const {
+ for (int i = 0; i < flag_rects.size(); i++) {
+ if (i < tooltips.size() && flag_rects[i].has_point(p_pos)) {
+ return tooltips[i];
}
-
- return min_size;
}
+ return String();
+}
- virtual String get_tooltip(const Point2 &p_pos) const override {
- for (int i = 0; i < flag_rects.size(); i++) {
- if (i < tooltips.size() && flag_rects[i].has_point(p_pos)) {
- return tooltips[i];
+void EditorPropertyLayersGrid::gui_input(const Ref<InputEvent> &p_ev) {
+ if (read_only) {
+ return;
+ }
+ const Ref<InputEventMouseMotion> mm = p_ev;
+ if (mm.is_valid()) {
+ bool expand_was_hovered = expand_hovered;
+ expand_hovered = expand_rect.has_point(mm->get_position());
+ if (expand_hovered != expand_was_hovered) {
+ update();
+ }
+
+ if (!expand_hovered) {
+ for (int i = 0; i < flag_rects.size(); i++) {
+ if (flag_rects[i].has_point(mm->get_position())) {
+ // Used to highlight the hovered flag in the layers grid.
+ hovered_index = i;
+ update();
+ return;
+ }
}
}
- return String();
- }
- void gui_input(const Ref<InputEvent> &p_ev) override {
- if (read_only) {
- return;
+ // Remove highlight when no square is hovered.
+ if (hovered_index != -1) {
+ hovered_index = -1;
+ update();
}
- const Ref<InputEventMouseMotion> mm = p_ev;
- if (mm.is_valid()) {
- bool expand_was_hovered = expand_hovered;
- expand_hovered = expand_rect.has_point(mm->get_position());
- if (expand_hovered != expand_was_hovered) {
- update();
- }
- if (!expand_hovered) {
- for (int i = 0; i < flag_rects.size(); i++) {
- if (flag_rects[i].has_point(mm->get_position())) {
- // Used to highlight the hovered flag in the layers grid.
- hovered_index = i;
- update();
- return;
- }
- }
- }
+ return;
+ }
- // Remove highlight when no square is hovered.
- if (hovered_index != -1) {
- hovered_index = -1;
- update();
+ const Ref<InputEventMouseButton> mb = p_ev;
+ if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) {
+ if (hovered_index >= 0) {
+ // Toggle the flag.
+ // We base our choice on the hovered flag, so that it always matches the hovered flag.
+ if (value & (1 << hovered_index)) {
+ value &= ~(1 << hovered_index);
+ } else {
+ value |= (1 << hovered_index);
}
- return;
+ emit_signal(SNAME("flag_changed"), value);
+ update();
+ } else if (expand_hovered) {
+ expanded = !expanded;
+ update_minimum_size();
+ update();
}
-
- const Ref<InputEventMouseButton> mb = p_ev;
- if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) {
- if (hovered_index >= 0) {
- // Toggle the flag.
- // We base our choice on the hovered flag, so that it always matches the hovered flag.
- if (value & (1 << hovered_index)) {
- value &= ~(1 << hovered_index);
- } else {
- value |= (1 << hovered_index);
- }
-
- emit_signal(SNAME("flag_changed"), value);
- update();
- } else if (expand_hovered) {
- expanded = !expanded;
- update_minimum_size();
- update();
- }
+ }
+ if (mb.is_valid() && mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) {
+ if (hovered_index >= 0) {
+ renamed_layer_index = hovered_index;
+ layer_rename->set_position(get_screen_position() + mb->get_position());
+ layer_rename->reset_size();
+ layer_rename->popup();
}
}
+}
- void _notification(int p_what) {
- switch (p_what) {
- case NOTIFICATION_DRAW: {
- Size2 grid_size = get_grid_size();
- grid_size.x = get_size().x;
-
- flag_rects.clear();
+void EditorPropertyLayersGrid::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_DRAW: {
+ Size2 grid_size = get_grid_size();
+ grid_size.x = get_size().x;
- int prev_expansion_rows = expansion_rows;
- expansion_rows = 0;
+ flag_rects.clear();
- const int bsize = (grid_size.height * 80 / 100) / 2;
- const int h = bsize * 2 + 1;
+ int prev_expansion_rows = expansion_rows;
+ expansion_rows = 0;
- Color color = get_theme_color(read_only ? SNAME("disabled_highlight_color") : SNAME("highlight_color"), SNAME("Editor"));
+ const int bsize = (grid_size.height * 80 / 100) / 2;
+ const int h = bsize * 2 + 1;
- Color text_color = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_color"), SNAME("Editor"));
- text_color.a *= 0.5;
+ Color color = get_theme_color(read_only ? SNAME("disabled_highlight_color") : SNAME("highlight_color"), SNAME("Editor"));
- Color text_color_on = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_hover_color"), SNAME("Editor"));
- text_color_on.a *= 0.7;
+ Color text_color = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_color"), SNAME("Editor"));
+ text_color.a *= 0.5;
- const int vofs = (grid_size.height - h) / 2;
+ Color text_color_on = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_hover_color"), SNAME("Editor"));
+ text_color_on.a *= 0.7;
- int layer_index = 0;
- int block_index = 0;
+ const int vofs = (grid_size.height - h) / 2;
- Point2 arrow_pos;
+ int layer_index = 0;
+ int block_index = 0;
- Point2 block_ofs(4, vofs);
+ Point2 arrow_pos;
- while (true) {
- Point2 ofs = block_ofs;
+ Point2 block_ofs(4, vofs);
- for (int i = 0; i < 2; i++) {
- for (int j = 0; j < layer_group_size; j++) {
- const bool on = value & (1 << layer_index);
- Rect2 rect2 = Rect2(ofs, Size2(bsize, bsize));
+ while (true) {
+ Point2 ofs = block_ofs;
- color.a = on ? 0.6 : 0.2;
- if (layer_index == hovered_index) {
- // Add visual feedback when hovering a flag.
- color.a += 0.15;
- }
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < layer_group_size; j++) {
+ const bool on = value & (1 << layer_index);
+ Rect2 rect2 = Rect2(ofs, Size2(bsize, bsize));
- draw_rect(rect2, color);
- flag_rects.push_back(rect2);
+ color.a = on ? 0.6 : 0.2;
+ if (layer_index == hovered_index) {
+ // Add visual feedback when hovering a flag.
+ color.a += 0.15;
+ }
- Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
- int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
- Vector2 offset;
- offset.y = rect2.size.y * 0.75;
+ draw_rect(rect2, color);
+ flag_rects.push_back(rect2);
- draw_string(font, rect2.position + offset, itos(layer_index + 1), HORIZONTAL_ALIGNMENT_CENTER, rect2.size.x, font_size, on ? text_color_on : text_color);
+ Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Label"));
+ int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label"));
+ Vector2 offset;
+ offset.y = rect2.size.y * 0.75;
- ofs.x += bsize + 1;
+ draw_string(font, rect2.position + offset, itos(layer_index + 1), HORIZONTAL_ALIGNMENT_CENTER, rect2.size.x, font_size, on ? text_color_on : text_color);
- ++layer_index;
- }
+ ofs.x += bsize + 1;
- ofs.x = block_ofs.x;
- ofs.y += bsize + 1;
+ ++layer_index;
}
- if (layer_index >= layer_count) {
- if (!flag_rects.is_empty() && (expansion_rows == 0)) {
- const Rect2 &last_rect = flag_rects[flag_rects.size() - 1];
- arrow_pos = last_rect.get_end();
- }
- break;
+ ofs.x = block_ofs.x;
+ ofs.y += bsize + 1;
+ }
+
+ if (layer_index >= layer_count) {
+ if (!flag_rects.is_empty() && (expansion_rows == 0)) {
+ const Rect2 &last_rect = flag_rects[flag_rects.size() - 1];
+ arrow_pos = last_rect.get_end();
}
+ break;
+ }
- int block_size_x = layer_group_size * (bsize + 1);
- block_ofs.x += block_size_x + 3;
+ int block_size_x = layer_group_size * (bsize + 1);
+ block_ofs.x += block_size_x + 3;
- if (block_ofs.x + block_size_x + 12 > grid_size.width) {
- // Keep last valid cell position for the expansion icon.
- if (!flag_rects.is_empty() && (expansion_rows == 0)) {
- const Rect2 &last_rect = flag_rects[flag_rects.size() - 1];
- arrow_pos = last_rect.get_end();
- }
- ++expansion_rows;
-
- if (expanded) {
- // Expand grid to next line.
- block_ofs.x = 4;
- block_ofs.y += 2 * (bsize + 1) + 3;
- } else {
- // Skip remaining blocks.
- break;
- }
+ if (block_ofs.x + block_size_x + 12 > grid_size.width) {
+ // Keep last valid cell position for the expansion icon.
+ if (!flag_rects.is_empty() && (expansion_rows == 0)) {
+ const Rect2 &last_rect = flag_rects[flag_rects.size() - 1];
+ arrow_pos = last_rect.get_end();
+ }
+ ++expansion_rows;
+
+ if (expanded) {
+ // Expand grid to next line.
+ block_ofs.x = 4;
+ block_ofs.y += 2 * (bsize + 1) + 3;
+ } else {
+ // Skip remaining blocks.
+ break;
}
-
- ++block_index;
}
- if ((expansion_rows != prev_expansion_rows) && expanded) {
- update_minimum_size();
- }
+ ++block_index;
+ }
- if ((expansion_rows == 0) && (layer_index == layer_count)) {
- // Whole grid was drawn, no need for expansion icon.
- break;
- }
+ if ((expansion_rows != prev_expansion_rows) && expanded) {
+ update_minimum_size();
+ }
- Ref<Texture2D> arrow = get_theme_icon(SNAME("arrow"), SNAME("Tree"));
- ERR_FAIL_COND(arrow.is_null());
+ if ((expansion_rows == 0) && (layer_index == layer_count)) {
+ // Whole grid was drawn, no need for expansion icon.
+ break;
+ }
- Color arrow_color = get_theme_color(SNAME("highlight_color"), SNAME("Editor"));
- arrow_color.a = expand_hovered ? 1.0 : 0.6;
+ Ref<Texture2D> arrow = get_theme_icon(SNAME("arrow"), SNAME("Tree"));
+ ERR_FAIL_COND(arrow.is_null());
- arrow_pos.x += 2.0;
- arrow_pos.y -= arrow->get_height();
+ Color arrow_color = get_theme_color(SNAME("highlight_color"), SNAME("Editor"));
+ arrow_color.a = expand_hovered ? 1.0 : 0.6;
- Rect2 arrow_draw_rect(arrow_pos, arrow->get_size());
- expand_rect = arrow_draw_rect;
- if (expanded) {
- arrow_draw_rect.size.y *= -1.0; // Flip arrow vertically when expanded.
- }
+ arrow_pos.x += 2.0;
+ arrow_pos.y -= arrow->get_height();
- RID ci = get_canvas_item();
- arrow->draw_rect(ci, arrow_draw_rect, false, arrow_color);
+ Rect2 arrow_draw_rect(arrow_pos, arrow->get_size());
+ expand_rect = arrow_draw_rect;
+ if (expanded) {
+ arrow_draw_rect.size.y *= -1.0; // Flip arrow vertically when expanded.
+ }
- } break;
+ RID ci = get_canvas_item();
+ arrow->draw_rect(ci, arrow_draw_rect, false, arrow_color);
- case NOTIFICATION_MOUSE_EXIT: {
- if (expand_hovered) {
- expand_hovered = false;
- update();
- }
- if (hovered_index != -1) {
- hovered_index = -1;
- update();
- }
- } break;
+ } break;
- default:
- break;
- }
- }
+ case NOTIFICATION_MOUSE_EXIT: {
+ if (expand_hovered) {
+ expand_hovered = false;
+ update();
+ }
+ if (hovered_index != -1) {
+ hovered_index = -1;
+ update();
+ }
+ } break;
- void set_flag(uint32_t p_flag) {
- value = p_flag;
- update();
+ default:
+ break;
}
+}
- static void _bind_methods() {
- ADD_SIGNAL(MethodInfo("flag_changed", PropertyInfo(Variant::INT, "flag")));
- }
-};
+void EditorPropertyLayersGrid::set_flag(uint32_t p_flag) {
+ value = p_flag;
+ update();
+}
+
+void EditorPropertyLayersGrid::_bind_methods() {
+ ADD_SIGNAL(MethodInfo("flag_changed", PropertyInfo(Variant::INT, "flag")));
+ ADD_SIGNAL(MethodInfo("rename_confirmed", PropertyInfo(Variant::INT, "layer_id"), PropertyInfo(Variant::STRING, "new_name")));
+}
void EditorPropertyLayers::_set_read_only(bool p_read_only) {
button->set_disabled(p_read_only);
@@ -1063,7 +1095,7 @@ void EditorPropertyLayers::update_property() {
}
void EditorPropertyLayers::setup(LayerType p_layer_type) {
- String basename;
+ layer_type = p_layer_type;
int layer_group_size = 0;
int layer_count = 0;
switch (p_layer_type) {
@@ -1127,6 +1159,13 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) {
grid->layer_count = layer_count;
}
+void EditorPropertyLayers::set_layer_name(int p_index, const String &p_name) {
+ if (ProjectSettings::get_singleton()->has_setting(basename + vformat("/layer_%d", p_index + 1))) {
+ ProjectSettings::get_singleton()->set(basename + vformat("/layer_%d", p_index + 1), p_name);
+ ProjectSettings::get_singleton()->save();
+ }
+}
+
void EditorPropertyLayers::_button_pressed() {
int layer_count = grid->layer_count;
int layer_group_size = grid->layer_group_size;
@@ -1159,6 +1198,10 @@ void EditorPropertyLayers::_menu_pressed(int p_menu) {
_grid_changed(grid->value);
}
+void EditorPropertyLayers::_refresh_names() {
+ setup(layer_type);
+}
+
void EditorPropertyLayers::_bind_methods() {
}
@@ -1168,6 +1211,7 @@ EditorPropertyLayers::EditorPropertyLayers() {
add_child(hb);
grid = memnew(EditorPropertyLayersGrid);
grid->connect("flag_changed", callable_mp(this, &EditorPropertyLayers::_grid_changed));
+ grid->connect("rename_confirmed", callable_mp(this, &EditorPropertyLayers::set_layer_name));
grid->set_h_size_flags(SIZE_EXPAND_FILL);
hb->add_child(grid);
@@ -1184,6 +1228,7 @@ EditorPropertyLayers::EditorPropertyLayers() {
layers->set_hide_on_checkable_item_selection(false);
layers->connect("id_pressed", callable_mp(this, &EditorPropertyLayers::_menu_pressed));
layers->connect("popup_hide", callable_mp((BaseButton *)button, &BaseButton::set_pressed), varray(false));
+ EditorNode::get_singleton()->connect("project_settings_changed", callable_mp(this, &EditorPropertyLayers::_refresh_names));
}
///////////////////// INT /////////////////////////
@@ -2753,7 +2798,7 @@ void EditorPropertyNodePath::_node_selected(const NodePath &p_path) {
}
if (!base_node && get_edited_object()->has_method("get_root_path")) {
- base_node = get_edited_object()->call("get_root_path");
+ base_node = Object::cast_to<Node>(get_edited_object()->call("get_root_path"));
}
if (!base_node && Object::cast_to<RefCounted>(get_edited_object())) {
@@ -3273,9 +3318,9 @@ struct EditorPropertyRangeHint {
bool angle_in_degrees = false;
bool greater = true;
bool lesser = true;
- double min = -99999;
- double max = 99999;
- double step = 0;
+ double min = -99999.0;
+ double max = 99999.0;
+ double step = 1.0;
String suffix;
bool exp_range = false;
bool hide_slider = true;
@@ -3286,18 +3331,25 @@ static EditorPropertyRangeHint _parse_range_hint(PropertyHint p_hint, const Stri
EditorPropertyRangeHint hint;
hint.step = p_default_step;
bool degrees = false;
- if (p_hint == PROPERTY_HINT_RANGE && p_hint_text.get_slice_count(",") >= 2) {
- hint.greater = false; //if using ranged, assume false by default
+
+ if (p_hint == PROPERTY_HINT_RANGE) {
+ Vector<String> slices = p_hint_text.split(",");
+ ERR_FAIL_COND_V_MSG(slices.size() < 2, hint,
+ vformat("Invalid PROPERTY_HINT_RANGE with hint \"%s\": Missing required min and/or max values.", p_hint_text));
+
+ hint.greater = false; // If using ranged, assume false by default.
hint.lesser = false;
- hint.min = p_hint_text.get_slice(",", 0).to_float();
- hint.max = p_hint_text.get_slice(",", 1).to_float();
- if (p_hint_text.get_slice_count(",") >= 3) {
- hint.step = p_hint_text.get_slice(",", 2).to_float();
+ hint.min = slices[0].to_float();
+ hint.max = slices[1].to_float();
+
+ if (slices.size() >= 3 && slices[2].is_valid_float()) {
+ // Step is optional, could be something else if not a number.
+ hint.step = slices[2].to_float();
}
hint.hide_slider = false;
- for (int i = 2; i < p_hint_text.get_slice_count(","); i++) {
- String slice = p_hint_text.get_slice(",", i).strip_edges();
+ for (int i = 2; i < slices.size(); i++) {
+ String slice = slices[i].strip_edges();
if (slice == "radians") {
hint.radians = true;
} else if (slice == "degrees") {
@@ -3320,6 +3372,9 @@ static EditorPropertyRangeHint _parse_range_hint(PropertyHint p_hint, const Stri
hint.suffix = U"\u00B0";
}
+ ERR_FAIL_COND_V_MSG(hint.step == 0, hint,
+ vformat("Invalid PROPERTY_HINT_RANGE with hint \"%s\": Step cannot be 0.", p_hint_text));
+
return hint;
}
@@ -3390,7 +3445,6 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
EditorPropertyInteger *editor = memnew(EditorPropertyInteger);
EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1);
-
editor->setup(hint.min, hint.max, hint.step, hint.greater, hint.lesser);
return editor;
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index fdb0360d6b..9a16a78ff8 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -279,7 +279,46 @@ public:
EditorPropertyFlags();
};
-class EditorPropertyLayersGrid;
+///////////////////// LAYERS /////////////////////////
+
+class EditorPropertyLayersGrid : public Control {
+ GDCLASS(EditorPropertyLayersGrid, Control);
+
+private:
+ Vector<Rect2> flag_rects;
+ Rect2 expand_rect;
+ bool expand_hovered = false;
+ bool expanded = false;
+ int expansion_rows = 0;
+ int hovered_index = -1;
+ bool read_only = false;
+ int renamed_layer_index = -1;
+ PopupMenu *layer_rename;
+ ConfirmationDialog *rename_dialog;
+ LineEdit *rename_dialog_text;
+
+ void _rename_pressed(int p_menu);
+ void _rename_operation_confirm();
+ Size2 get_grid_size() const;
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ uint32_t value = 0;
+ int layer_group_size = 0;
+ int layer_count = 0;
+ Vector<String> names;
+ Vector<String> tooltips;
+
+ void set_read_only(bool p_read_only);
+ virtual Size2 get_minimum_size() const override;
+ virtual String get_tooltip(const Point2 &p_pos) const override;
+ void gui_input(const Ref<InputEvent> &p_ev) override;
+ void set_flag(uint32_t p_flag);
+ EditorPropertyLayersGrid();
+};
class EditorPropertyLayers : public EditorProperty {
GDCLASS(EditorPropertyLayers, EditorProperty);
@@ -297,12 +336,14 @@ public:
private:
EditorPropertyLayersGrid *grid;
void _grid_changed(uint32_t p_grid);
+ String basename;
LayerType layer_type;
PopupMenu *layers;
Button *button;
void _button_pressed();
void _menu_pressed(int p_menu);
+ void _refresh_names();
protected:
virtual void _set_read_only(bool p_read_only) override;
@@ -310,6 +351,7 @@ protected:
public:
void setup(LayerType p_layer_type);
+ void set_layer_name(int p_index, const String &p_name);
virtual void update_property() override;
EditorPropertyLayers();
};
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 8146f48f91..f230a9b435 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -369,7 +369,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// Skip locales which we can't render properly (see above comment).
// Test against language code without regional variants (e.g. ur_PK).
String lang_code = locale.get_slice("_", 0);
- if (locales_to_skip.find(lang_code) != -1) {
+ if (locales_to_skip.has(lang_code)) {
continue;
}
diff --git a/editor/settings_config_dialog.cpp b/editor/editor_settings_dialog.cpp
index 71edeefd10..2520d662c5 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/editor_settings_dialog.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* settings_config_dialog.cpp */
+/* editor_settings_dialog.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "settings_config_dialog.h"
+#include "editor_settings_dialog.h"
#include "core/config/project_settings.h"
#include "core/input/input_map.h"
@@ -379,7 +379,7 @@ void EditorSettingsDialog::_update_shortcuts() {
// Join the text of the events with a delimiter so they can all be displayed in one cell.
String events_display_string = event_strings.is_empty() ? "None" : String("; ").join(event_strings);
- if (!shortcut_filter.is_subsequence_ofi(action_name) && (events_display_string == "None" || !shortcut_filter.is_subsequence_ofi(events_display_string))) {
+ if (!shortcut_filter.is_subsequence_ofn(action_name) && (events_display_string == "None" || !shortcut_filter.is_subsequence_ofn(events_display_string))) {
continue;
}
@@ -428,7 +428,7 @@ void EditorSettingsDialog::_update_shortcuts() {
// Shortcut Item
- if (!shortcut_filter.is_subsequence_ofi(sc->get_name())) {
+ if (!shortcut_filter.is_subsequence_ofn(sc->get_name())) {
continue;
}
diff --git a/editor/settings_config_dialog.h b/editor/editor_settings_dialog.h
index c3dfd736d5..f1c4ea7770 100644
--- a/editor/settings_config_dialog.h
+++ b/editor/editor_settings_dialog.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* settings_config_dialog.h */
+/* editor_settings_dialog.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SETTINGS_CONFIG_DIALOG_H
-#define SETTINGS_CONFIG_DIALOG_H
+#ifndef EDITOR_SETTINGS_DIALOG_H
+#define EDITOR_SETTINGS_DIALOG_H
#include "editor/action_map_editor.h"
#include "editor/editor_sectioned_inspector.h"
@@ -128,4 +128,4 @@ public:
~EditorSettingsDialog();
};
-#endif // SETTINGS_CONFIG_DIALOG_H
+#endif // EDITOR_SETTINGS_DIALOG_H
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index db4161fc3d..308a268e42 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -150,11 +150,26 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
// are contained in the dictionary above.
Set<StringName> exceptions;
+ // Some of the colors below are listed for completeness sake.
+ // This can be a basis for proper palette validation later.
if (!p_dark_theme) {
// Convert color: FROM TO
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#478cbf", "#478cbf"); // Godot Blue
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#414042", "#414042"); // Godot Gray
+
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffffff", "#414141"); // Pure white
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#000000", "#bfbfbf"); // Pure black
+ // Keep pure RGB colors as is, but list them for explicity.
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff0000", "#ff0000"); // Pure red
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#00ff00", "#00ff00"); // Pure green
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#0000ff", "#0000ff"); // Pure blue
+
+ // GUI Colors
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e0e0e0", "#5a5a5a"); // Common icon color
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffffff", "#414141"); // White
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#b4b4b4", "#363636"); // Script darker color
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fefefe", "#fefefe"); // Forced light color
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#808080", "#808080"); // GUI disabled color
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#b3b3b3", "#363636"); // GUI disabled light color
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#699ce8", "#699ce8"); // GUI highlight color
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f9f9f9", "#606060"); // Scrollbar grabber highlight color
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#c38ef1", "#a85de9"); // Animation
@@ -162,7 +177,10 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#8da5f3", "#3d64dd"); // 2D
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#4b70ea", "#1a3eac"); // 2D Dark
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#8eef97", "#2fa139"); // Control
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffdd65", "#ca8a04"); // Node warning
+
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5fb2ff", "#0079f0"); // Selection (blue)
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#003e7a", "#2b74bb"); // Selection (darker blue)
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f7f5cf", "#615f3a"); // Gizmo (yellow)
// Rainbow
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff4545", "#ff2929"); // Red
@@ -173,31 +191,45 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#8045ff", "#702aff"); // Purple
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff4596", "#ff2781"); // Pink
- // Audio gradient
- // Red is defined further below.
+ // Audio gradients
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#e1da5b", "#d6cf4b"); // Yellow
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5fff97", "#00f010"); // Green
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffca5f", "#fea900"); // Mesh resource (orange)
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#0787ff", "#68b6ff"); // Shape resource (blue)
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#62aeff", "#1678e0"); // Frozen gradient top
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#75d1e6", "#41acc5"); // Frozen gradient middle
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#84ffee", "#49ccba"); // Frozen gradient bottom
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff5f5f", "#ff3333"); // Red audio gradient + remove (red)
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5fff97", "#00db50"); // Add (green)
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5fb2ff", "#5caeff"); // Selection (blue)
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#f70000", "#c91616"); // Color track red
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#eec315", "#d58c0b"); // Color track orange
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#dbee15", "#b7d10a"); // Color track yellow
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#288027", "#218309"); // Color track green
+
+ // Resource groups
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ffca5f", "#fea900"); // Mesh resource (orange)
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#2998ff", "#68b6ff"); // Shape resource (blue)
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a2d2ff", "#4998e3"); // Shape resource (light blue)
// Animation editor tracks
// The property track icon color is set by the common icon color.
- ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ea7940", "#bd5e2c"); // 3D Transform track
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ea7940", "#bd5e2c"); // 3D Position track
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ff2b88", "#bd165f"); // 3D Rotation track
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#eac840", "#bd9d1f"); // 3D Scale track
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#3cf34e", "#16a827"); // Call Method track
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#2877f6", "#236be6"); // Bezier Curve track
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#eae440", "#9f9722"); // Audio Playback track
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#a448f0", "#9853ce"); // Animation Playback track
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5ad5c4", "#0a9c88"); // Blend Shape track
+
+ // Control layouts
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#d6d6d6", "#474747"); // Highlighted part
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#474747", "#d6d6d6"); // Background part
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#919191", "#6e6e6e"); // Border part
// TileSet editor icons
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#fce00e", "#aa8d24"); // New Single Tile
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#0e71fc", "#0350bd"); // New Autotile
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#c6ced4", "#828f9b"); // New Atlas
+ // Visual script
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#41ecad", "#25e3a0"); // VisualScript variant
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#6f91f0", "#6d8eeb"); // VisualScript bool
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#5abbef", "#4fb2e9"); // VisualScript int
@@ -216,6 +248,11 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#41ec80", "#2ce573"); // VisualScript RID
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#55f3e3", "#12d5c3"); // VisualScript Object
ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#54ed9e", "#57e99f"); // VisualScript Dictionary
+ // Visual shaders
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#77ce57", "#67c046"); // Vector funcs
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#ea686c", "#d95256"); // Vector transforms
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#eac968", "#d9b64f"); // Textures and cubemaps
+ ADD_CONVERT_COLOR(dark_icon_color_dictionary, "#cf68ea", "#c050dd"); // Functions and expressions
exceptions.insert("EditorPivot");
exceptions.insert("EditorHandle");
@@ -246,9 +283,9 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
const Color error_color = p_theme->get_color("error_color", "Editor");
const Color success_color = p_theme->get_color("success_color", "Editor");
const Color warning_color = p_theme->get_color("warning_color", "Editor");
- dark_icon_color_dictionary[Color::html("#ff0000")] = error_color;
- dark_icon_color_dictionary[Color::html("#45ff8b")] = success_color;
- dark_icon_color_dictionary[Color::html("#dbab09")] = warning_color;
+ dark_icon_color_dictionary[Color::html("#ff5f5f")] = error_color;
+ dark_icon_color_dictionary[Color::html("#5fff97")] = success_color;
+ dark_icon_color_dictionary[Color::html("#ffdd65")] = warning_color;
// Generate icons.
if (!p_only_thumbs) {
@@ -390,6 +427,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color font_focus_color = mono_color.lerp(base_color, 0.125);
const Color font_disabled_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.3);
const Color font_readonly_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.65);
+ const Color font_placeholder_color = Color(mono_color.r, mono_color.g, mono_color.b, 0.6);
const Color selection_color = accent_color * Color(1, 1, 1, 0.4);
const Color disabled_color = mono_color.inverted().lerp(base_color, 0.7);
const Color disabled_bg_color = mono_color.inverted().lerp(base_color, 0.9);
@@ -979,8 +1017,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("SceneTabFG", "EditorStyles", style_tab_selected);
theme->set_stylebox("SceneTabBG", "EditorStyles", style_tab_unselected);
theme->set_icon("close", "TabBar", theme->get_icon("GuiClose", "EditorIcons"));
- theme->set_stylebox("close_bg_pressed", "TabBar", style_menu);
- theme->set_stylebox("close_bg_highlight", "TabBar", style_menu);
+ theme->set_stylebox("button_pressed", "TabBar", style_menu);
+ theme->set_stylebox("button_highlight", "TabBar", style_menu);
theme->set_icon("increment", "TabContainer", theme->get_icon("GuiScrollArrowRight", "EditorIcons"));
theme->set_icon("decrement", "TabContainer", theme->get_icon("GuiScrollArrowLeft", "EditorIcons"));
theme->set_icon("increment", "TabBar", theme->get_icon("GuiScrollArrowRight", "EditorIcons"));
@@ -1072,6 +1110,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("font_color", "LineEdit", font_color);
theme->set_color("font_selected_color", "LineEdit", mono_color);
theme->set_color("font_uneditable_color", "LineEdit", font_readonly_color);
+ theme->set_color("font_placeholder_color", "LineEdit", font_placeholder_color);
theme->set_color("caret_color", "LineEdit", font_color);
theme->set_color("selection_color", "LineEdit", selection_color);
theme->set_color("clear_button_color", "LineEdit", font_color);
@@ -1086,6 +1125,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("space", "TextEdit", theme->get_icon("GuiSpace", "EditorIcons"));
theme->set_color("font_color", "TextEdit", font_color);
theme->set_color("font_readonly_color", "TextEdit", font_readonly_color);
+ theme->set_color("font_placeholder_color", "TextEdit", font_placeholder_color);
theme->set_color("caret_color", "TextEdit", font_color);
theme->set_color("selection_color", "TextEdit", selection_color);
theme->set_constant("line_spacing", "TextEdit", 4 * EDSCALE);
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index cd29a3e617..bc71072d29 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1801,7 +1801,7 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
// Add the files from favorites.
Vector<String> favorites = EditorSettings::get_singleton()->get_favorites();
for (int i = 0; i < p_selected.size(); i++) {
- if (favorites.find(p_selected[i]) == -1) {
+ if (!favorites.has(p_selected[i])) {
favorites.push_back(p_selected[i]);
}
}
@@ -2324,7 +2324,7 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data,
Vector<String> fnames = drag_data["files"];
Vector<String> favorites = EditorSettings::get_singleton()->get_favorites();
for (int i = 0; i < fnames.size(); i++) {
- if (favorites.find(fnames[i]) == -1) {
+ if (!favorites.has(fnames[i])) {
favorites.push_back(fnames[i]);
}
}
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index 15455b759b..1644bb9dbe 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -71,13 +71,13 @@ void GroupDialog::_load_nodes(Node *p_current) {
TreeItem *node = nullptr;
NodePath path = scene_tree->get_edited_scene_root()->get_path_to(p_current);
if (keep && p_current->is_in_group(selected_group)) {
- if (remove_filter->get_text().is_subsequence_ofi(String(p_current->get_name()))) {
+ if (remove_filter->get_text().is_subsequence_ofn(String(p_current->get_name()))) {
node = nodes_to_remove->create_item(remove_node_root);
keep = true;
} else {
keep = false;
}
- } else if (keep && add_filter->get_text().is_subsequence_ofi(String(p_current->get_name()))) {
+ } else if (keep && add_filter->get_text().is_subsequence_ofn(String(p_current->get_name()))) {
node = nodes_to_add->create_item(add_node_root);
keep = true;
} else {
diff --git a/editor/icons/AudioBusLayout.svg b/editor/icons/AudioBusLayout.svg
index 9928f369e7..c3bbc882e4 100644
--- a/editor/icons/AudioBusLayout.svg
+++ b/editor/icons/AudioBusLayout.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m3 1c-1.108 0-2 .89199-2 2v10c0 1.108.89199 2 2 2h2c1.108 0 2-.89199 2-2v-10c0-1.108-.89199-2-2-2zm8 0c-1.108 0-2 .89199-2 2v10c0 1.108.89199 2 2 2h2c1.108 0 2-.89199 2-2v-10c0-1.108-.89199-2-2-2zm-8 1h2c.55401 0 1 .44599 1 1v10c0 .55401-.44599 1-1 1h-2c-.55401 0-1-.44599-1-1v-10c0-.55401.44599-1 1-1z" fill="url(#a)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff5f5f"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#5fff97"/></linearGradient><path d="m3 1c-1.108 0-2 .89199-2 2v10c0 1.108.89199 2 2 2h2c1.108 0 2-.89199 2-2v-10c0-1.108-.89199-2-2-2zm8 0c-1.108 0-2 .89199-2 2v10c0 1.108.89199 2 2 2h2c1.108 0 2-.89199 2-2v-10c0-1.108-.89199-2-2-2zm-8 1h2c.55401 0 1 .44599 1 1v10c0 .55401-.44599 1-1 1h-2c-.55401 0-1-.44599-1-1v-10c0-.55401.44599-1 1-1z" fill="url(#a)"/></svg>
diff --git a/editor/icons/AudioListener2D.svg b/editor/icons/AudioListener2D.svg
index db84dcfed7..9167460290 100644
--- a/editor/icons/AudioListener2D.svg
+++ b/editor/icons/AudioListener2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a5 5 0 0 0 -5 5h2a3 3 0 0 1 3-3 3 3 0 0 1 3 3c0 1.75-.54175 2.3583-1.1406 2.8574-.29944.2495-.62954.44071-.97656.69141-.17351.1253-.35729.26529-.53711.49219-.17982.227-.3457.58398-.3457.95898 0 1.2778-.31632 1.5742-.63867 1.7676-.32236.1934-.86133.23242-1.3613.23242h-1v2h1c.5 0 1.461.038922 2.3887-.51758.87316-.5239 1.4826-1.6633 1.5566-3.2266.011365-.0098.027247-.024684.10938-.083984.21547-.1556.63537-.40194 1.0859-.77734.90112-.751 1.8594-2.1445 1.8594-4.3945a5 5 0 0 0 -5-5zm7.9277 1-1.7383 1.0039a6 6 0 0 1 .81055 2.9961 6 6 0 0 1 -.80859 2.998l1.7363 1.002a8 8 0 0 0 0-8z" fill="#a5b7f3"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a5 5 0 0 0 -5 5h2a3 3 0 0 1 3-3 3 3 0 0 1 3 3c0 1.75-.54175 2.3583-1.1406 2.8574-.29944.2495-.62954.44071-.97656.69141-.17351.1253-.35729.26529-.53711.49219-.17982.227-.3457.58398-.3457.95898 0 1.2778-.31632 1.5742-.63867 1.7676-.32236.1934-.86133.23242-1.3613.23242h-1v2h1c.5 0 1.461.038922 2.3887-.51758.87316-.5239 1.4826-1.6633 1.5566-3.2266.011365-.0098.027247-.024684.10938-.083984.21547-.1556.63537-.40194 1.0859-.77734.90112-.751 1.8594-2.1445 1.8594-4.3945a5 5 0 0 0 -5-5zm7.9277 1-1.7383 1.0039a6 6 0 0 1 .81055 2.9961 6 6 0 0 1 -.80859 2.998l1.7363 1.002a8 8 0 0 0 0-8z" fill="#8da5f3"/></svg>
diff --git a/editor/icons/AudioStreamMP3.svg b/editor/icons/AudioStreamMP3.svg
index dc034c90de..2e54de9faa 100644
--- a/editor/icons/AudioStreamMP3.svg
+++ b/editor/icons/AudioStreamMP3.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m11.971 1.002c-.08326.00207-.16593.014541-.24609.037109l-7 2c-.42881.12287-.7244.51487-.72461.96094v5.5508c-.16454-.033679-.33205-.050692-.5-.050781-1.3807 0-2.5 1.1193-2.5 2.5-.00000475 1.3807 1.1193 2.5 2.5 2.5 1.3456-.0013 2.4488-1.0674 2.4961-2.4121.0025906-.029226.003894-.058551.0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5c-.000916-.56314-.4664-1.0145-1.0293-.99805zm-1.4707 6.998c-.277 0-.5.223-.5.5v5c0 .277.223.5.5.5s.5-.223.5-.5v-5c0-.277-.223-.5-.5-.5zm2 1c-.277 0-.5.223-.5.5v3c0 .277.223.5.5.5s.5-.223.5-.5v-3c0-.277-.223-.5-.5-.5zm-4 1c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5zm6 0c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5z" fill="url(#a)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff5f5f"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#5fff97"/></linearGradient><path d="m11.971 1.002c-.08326.00207-.16593.014541-.24609.037109l-7 2c-.42881.12287-.7244.51487-.72461.96094v5.5508c-.16454-.033679-.33205-.050692-.5-.050781-1.3807 0-2.5 1.1193-2.5 2.5-.00000475 1.3807 1.1193 2.5 2.5 2.5 1.3456-.0013 2.4488-1.0674 2.4961-2.4121.0025906-.029226.003894-.058551.0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5c-.000916-.56314-.4664-1.0145-1.0293-.99805zm-1.4707 6.998c-.277 0-.5.223-.5.5v5c0 .277.223.5.5.5s.5-.223.5-.5v-5c0-.277-.223-.5-.5-.5zm2 1c-.277 0-.5.223-.5.5v3c0 .277.223.5.5.5s.5-.223.5-.5v-3c0-.277-.223-.5-.5-.5zm-4 1c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5zm6 0c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5z" fill="url(#a)"/></svg>
diff --git a/editor/icons/AudioStreamOGGVorbis.svg b/editor/icons/AudioStreamOGGVorbis.svg
index dc034c90de..2e54de9faa 100644
--- a/editor/icons/AudioStreamOGGVorbis.svg
+++ b/editor/icons/AudioStreamOGGVorbis.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m11.971 1.002c-.08326.00207-.16593.014541-.24609.037109l-7 2c-.42881.12287-.7244.51487-.72461.96094v5.5508c-.16454-.033679-.33205-.050692-.5-.050781-1.3807 0-2.5 1.1193-2.5 2.5-.00000475 1.3807 1.1193 2.5 2.5 2.5 1.3456-.0013 2.4488-1.0674 2.4961-2.4121.0025906-.029226.003894-.058551.0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5c-.000916-.56314-.4664-1.0145-1.0293-.99805zm-1.4707 6.998c-.277 0-.5.223-.5.5v5c0 .277.223.5.5.5s.5-.223.5-.5v-5c0-.277-.223-.5-.5-.5zm2 1c-.277 0-.5.223-.5.5v3c0 .277.223.5.5.5s.5-.223.5-.5v-3c0-.277-.223-.5-.5-.5zm-4 1c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5zm6 0c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5z" fill="url(#a)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff5f5f"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#5fff97"/></linearGradient><path d="m11.971 1.002c-.08326.00207-.16593.014541-.24609.037109l-7 2c-.42881.12287-.7244.51487-.72461.96094v5.5508c-.16454-.033679-.33205-.050692-.5-.050781-1.3807 0-2.5 1.1193-2.5 2.5-.00000475 1.3807 1.1193 2.5 2.5 2.5 1.3456-.0013 2.4488-1.0674 2.4961-2.4121.0025906-.029226.003894-.058551.0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5c-.000916-.56314-.4664-1.0145-1.0293-.99805zm-1.4707 6.998c-.277 0-.5.223-.5.5v5c0 .277.223.5.5.5s.5-.223.5-.5v-5c0-.277-.223-.5-.5-.5zm2 1c-.277 0-.5.223-.5.5v3c0 .277.223.5.5.5s.5-.223.5-.5v-3c0-.277-.223-.5-.5-.5zm-4 1c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5zm6 0c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5z" fill="url(#a)"/></svg>
diff --git a/editor/icons/AudioStreamPlayer.svg b/editor/icons/AudioStreamPlayer.svg
index 6d074c0744..31bd847e37 100644
--- a/editor/icons/AudioStreamPlayer.svg
+++ b/editor/icons/AudioStreamPlayer.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><g transform="translate(0 -1036.4)"><path d="m10.023 1044.4c-.56139-.013-1.0235.4264-1.0234.9724v5.0542c.0006911.7482.83361 1.2154 1.5.8414l4-2.5262c.66694-.3743.66694-1.3104 0-1.6847l-4-2.5261c-.14505-.082-.30893-.1269-.47656-.131z" fill="#e0e0e0"/><path d="m11.971 1.002a1.0001 1.0001 0 0 0 -.24609.037109l-7 2a1.0001 1.0001 0 0 0 -.72461.96094v5.5508a2.5 2.5 0 0 0 -.5-.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961-2.4121 1.0001 1.0001 0 0 0 .0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293-.99805z" fill="url(#a)" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff5f5f"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#5fff97"/></linearGradient><g transform="translate(0 -1036.4)"><path d="m10.023 1044.4c-.56139-.013-1.0235.4264-1.0234.9724v5.0542c.0006911.7482.83361 1.2154 1.5.8414l4-2.5262c.66694-.3743.66694-1.3104 0-1.6847l-4-2.5261c-.14505-.082-.30893-.1269-.47656-.131z" fill="#e0e0e0"/><path d="m11.971 1.002a1.0001 1.0001 0 0 0 -.24609.037109l-7 2a1.0001 1.0001 0 0 0 -.72461.96094v5.5508a2.5 2.5 0 0 0 -.5-.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961-2.4121 1.0001 1.0001 0 0 0 .0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293-.99805z" fill="url(#a)" transform="translate(0 1036.4)"/></g></svg>
diff --git a/editor/icons/AudioStreamPlayer2D.svg b/editor/icons/AudioStreamPlayer2D.svg
index 0bf091de29..716680f215 100644
--- a/editor/icons/AudioStreamPlayer2D.svg
+++ b/editor/icons/AudioStreamPlayer2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><g transform="translate(0 -1036.4)"><path d="m10.023 1044.4c-.56139-.013-1.0235.4264-1.0234.9724v5.0542c.0006911.7482.83361 1.2154 1.5.8414l4-2.5262c.66694-.3743.66694-1.3104 0-1.6847l-4-2.5261c-.14505-.082-.30893-.1269-.47656-.131z" fill="#8da5f3"/><path d="m11.971 1.002a1.0001 1.0001 0 0 0 -.24609.037109l-7 2a1.0001 1.0001 0 0 0 -.72461.96094v5.5508a2.5 2.5 0 0 0 -.5-.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961-2.4121 1.0001 1.0001 0 0 0 .0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293-.99805z" fill="url(#a)" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff5f5f"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#5fff97"/></linearGradient><g transform="translate(0 -1036.4)"><path d="m10.023 1044.4c-.56139-.013-1.0235.4264-1.0234.9724v5.0542c.0006911.7482.83361 1.2154 1.5.8414l4-2.5262c.66694-.3743.66694-1.3104 0-1.6847l-4-2.5261c-.14505-.082-.30893-.1269-.47656-.131z" fill="#8da5f3"/><path d="m11.971 1.002a1.0001 1.0001 0 0 0 -.24609.037109l-7 2a1.0001 1.0001 0 0 0 -.72461.96094v5.5508a2.5 2.5 0 0 0 -.5-.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961-2.4121 1.0001 1.0001 0 0 0 .0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293-.99805z" fill="url(#a)" transform="translate(0 1036.4)"/></g></svg>
diff --git a/editor/icons/AudioStreamPlayer3D.svg b/editor/icons/AudioStreamPlayer3D.svg
index ebe3128a21..d89dacd588 100644
--- a/editor/icons/AudioStreamPlayer3D.svg
+++ b/editor/icons/AudioStreamPlayer3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><g transform="translate(0 -1036.4)"><path d="m10.023 1044.4c-.56139-.013-1.0235.4264-1.0234.9724v5.0542c.0006911.7482.83361 1.2154 1.5.8414l4-2.5262c.66694-.3743.66694-1.3104 0-1.6847l-4-2.5261c-.14505-.082-.30893-.1269-.47656-.131z" fill="#fc7f7f"/><path d="m11.971 1.002a1.0001 1.0001 0 0 0 -.24609.037109l-7 2a1.0001 1.0001 0 0 0 -.72461.96094v5.5508a2.5 2.5 0 0 0 -.5-.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961-2.4121 1.0001 1.0001 0 0 0 .0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293-.99805z" fill="url(#a)" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff5f5f"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#5fff97"/></linearGradient><g transform="translate(0 -1036.4)"><path d="m10.023 1044.4c-.56139-.013-1.0235.4264-1.0234.9724v5.0542c.0006911.7482.83361 1.2154 1.5.8414l4-2.5262c.66694-.3743.66694-1.3104 0-1.6847l-4-2.5261c-.14505-.082-.30893-.1269-.47656-.131z" fill="#fc7f7f"/><path d="m11.971 1.002a1.0001 1.0001 0 0 0 -.24609.037109l-7 2a1.0001 1.0001 0 0 0 -.72461.96094v5.5508a2.5 2.5 0 0 0 -.5-.050781 2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.4961-2.4121 1.0001 1.0001 0 0 0 .0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5a1.0001 1.0001 0 0 0 -1.0293-.99805z" fill="url(#a)" transform="translate(0 1036.4)"/></g></svg>
diff --git a/editor/icons/AudioStreamSample.svg b/editor/icons/AudioStreamSample.svg
index dc034c90de..2e54de9faa 100644
--- a/editor/icons/AudioStreamSample.svg
+++ b/editor/icons/AudioStreamSample.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m11.971 1.002c-.08326.00207-.16593.014541-.24609.037109l-7 2c-.42881.12287-.7244.51487-.72461.96094v5.5508c-.16454-.033679-.33205-.050692-.5-.050781-1.3807 0-2.5 1.1193-2.5 2.5-.00000475 1.3807 1.1193 2.5 2.5 2.5 1.3456-.0013 2.4488-1.0674 2.4961-2.4121.0025906-.029226.003894-.058551.0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5c-.000916-.56314-.4664-1.0145-1.0293-.99805zm-1.4707 6.998c-.277 0-.5.223-.5.5v5c0 .277.223.5.5.5s.5-.223.5-.5v-5c0-.277-.223-.5-.5-.5zm2 1c-.277 0-.5.223-.5.5v3c0 .277.223.5.5.5s.5-.223.5-.5v-3c0-.277-.223-.5-.5-.5zm-4 1c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5zm6 0c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5z" fill="url(#a)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1" y2="15"><stop offset="0" stop-color="#ff5f5f"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#5fff97"/></linearGradient><path d="m11.971 1.002c-.08326.00207-.16593.014541-.24609.037109l-7 2c-.42881.12287-.7244.51487-.72461.96094v5.5508c-.16454-.033679-.33205-.050692-.5-.050781-1.3807 0-2.5 1.1193-2.5 2.5-.00000475 1.3807 1.1193 2.5 2.5 2.5 1.3456-.0013 2.4488-1.0674 2.4961-2.4121.0025906-.029226.003894-.058551.0039062-.087891v-7.2441l5-1.4277v3.1719l2-1v-3.5c-.000916-.56314-.4664-1.0145-1.0293-.99805zm-1.4707 6.998c-.277 0-.5.223-.5.5v5c0 .277.223.5.5.5s.5-.223.5-.5v-5c0-.277-.223-.5-.5-.5zm2 1c-.277 0-.5.223-.5.5v3c0 .277.223.5.5.5s.5-.223.5-.5v-3c0-.277-.223-.5-.5-.5zm-4 1c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5zm6 0c-.277 0-.5.223-.5.5v1c0 .277.223.5.5.5s.5-.223.5-.5v-1c0-.277-.223-.5-.5-.5z" fill="url(#a)"/></svg>
diff --git a/editor/icons/BoxMesh.svg b/editor/icons/BoxMesh.svg
index 6809b989cc..ef2f77a255 100644
--- a/editor/icons/BoxMesh.svg
+++ b/editor/icons/BoxMesh.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 .88867-7 3.5v7.2227l7 3.5 7-3.5v-7.2227zm0 2.1152 3.9395 1.9707-3.9395 1.9688-3.9395-1.9688zm-5 3.5527 4 2v3.9414l-4-2.002zm10 0v3.9395l-4 2.002v-3.9414z" fill="#ffca5f" stroke-width="1.0667" transform="scale(.9375)"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 .889-7 3.5v7.222l7 3.5 7-3.5v-7.222zm0 2.115 3.94 1.971-3.94 1.968-3.939-1.968zm-5 3.553 4 2v3.941l-4-2.002zm10 0v3.939l-4 2.002v-3.941z" fill="#ffca5f" fill-rule="nonzero"/></svg>
diff --git a/editor/icons/BoxShape3D.svg b/editor/icons/BoxShape3D.svg
index f9012d1fe4..a16f0bb1e1 100644
--- a/editor/icons/BoxShape3D.svg
+++ b/editor/icons/BoxShape3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m8 1-7 3v8l7 3 7-3v-8z" fill="#2998ff" transform="translate(0 1036.4)"/><path d="m8 1051.4-7-3v-8l7 3z" fill="#68b6ff"/><path d="m1 1040.4 7 3 7-3-7-3z" fill="#a2d2ff"/></g></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1-7 3v8l7 3 7-3v-8z" fill="#2998ff"/><path d="m8 15-7-3v-8l7 3z" fill="#5fb2ff"/><path d="m1 4 7 3 7-3-7-3z" fill="#a2d2ff"/></svg>
diff --git a/editor/icons/Breakpoint.svg b/editor/icons/Breakpoint.svg
index b95c2b511e..60d59b66c8 100644
--- a/editor/icons/Breakpoint.svg
+++ b/editor/icons/Breakpoint.svg
@@ -1 +1 @@
-<svg enable-background="new 0 0 16 16" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m15 8c0 3.866-3.134 7-7 7s-7-3.134-7-7 3.134-7 7-7 7 3.134 7 7" fill="#e1e1e1"/><pathd="m12 8c0 2.209-1.791 4-4 4s-4-1.791-4-4 1.791-4 4-4 4 1.791 4 4" fill="#f6f6f6"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero"><path d="m13.308 8c0 2.931-2.377 5.308-5.308 5.308s-5.308-2.377-5.308-5.308 2.377-5.308 5.308-5.308 5.308 2.377 5.308 5.308" fill="#e0e0e0"/><path d="m11.033 8c0 1.675-1.358 3.033-3.033 3.033s-3.033-1.358-3.033-3.033 1.358-3.033 3.033-3.033 3.033 1.358 3.033 3.033" fill="#fefefe"/></g></svg>
diff --git a/editor/icons/BusVuEmpty.svg b/editor/icons/BusVuEmpty.svg
index cc72e7cd36..88a14bc3ee 100644
--- a/editor/icons/BusVuEmpty.svg
+++ b/editor/icons/BusVuEmpty.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 16 128" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="926.36" y2="1050.36"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><g transform="translate(0 -924.36)"><path d="m3 926.36c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 5c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1z" fill="url(#a)"/><path d="m3 2c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 5c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1z" fill-opacity=".19608" transform="translate(0 924.36)"/></g></svg>
+<svg height="128" viewBox="0 0 16 128" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="926.36" y2="1050.36"><stop offset="0" stop-color="#ff5f5f"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#5fff97"/></linearGradient><g transform="translate(0 -924.36)"><path d="m3 926.36c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 5c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1z" fill="url(#a)"/><path d="m3 2c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 5c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1z" fill-opacity=".19608" transform="translate(0 924.36)"/></g></svg>
diff --git a/editor/icons/BusVuFull.svg b/editor/icons/BusVuFull.svg
index 34396c3c18..0bc00971c0 100644
--- a/editor/icons/BusVuFull.svg
+++ b/editor/icons/BusVuFull.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 16 128" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="2" y2="126"><stop offset="0" stop-color="#ff7a7a"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#66ff9e"/></linearGradient><path d="m3 2c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 5c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1z" fill="url(#a)"/></svg>
+<svg height="128" viewBox="0 0 16 128" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="2" y2="126"><stop offset="0" stop-color="#ff5f5f"/><stop offset=".5" stop-color="#e1da5b"/><stop offset="1" stop-color="#5fff97"/></linearGradient><path d="m3 2c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 5c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1zm0 3c-.554 0-1 .446-1 1s.446 1 1 1h10c.554 0 1-.446 1-1s-.446-1-1-1z" fill="url(#a)"/></svg>
diff --git a/editor/icons/CPUParticles2D.svg b/editor/icons/CPUParticles2D.svg
index 29770bc240..2a2c616954 100644
--- a/editor/icons/CPUParticles2D.svg
+++ b/editor/icons/CPUParticles2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4.5587261.60940813c-.4226244 0-.7617187.3410473-.7617187.76367177v.5078126c0 .1028478.020058.199689.056641.2890624h-1.1933597c-.4226245 0-.7617188.3390944-.7617188.7617188v.921875c-.040428-.00657-.0767989-.0234375-.1191406-.0234375h-.5078125c-.42262448 0-.76367188.3410475-.76367188.7636719v.3730468c0 .4226245.3410474.7617188.76367188.7617188h.5078125c.042396 0 .078663-.016851.1191406-.023437v4.4531248c-.040428-.0066-.076799-.02344-.1191406-.02344h-.5078125c-.42262448 0-.76367188.341047-.76367188.763672v.373047c0 .422625.3410474.761718.76367188.761718h.5078125c.042396 0 .078663-.01685.1191406-.02344v1.125c0 .422624.3390944.763672.7617188.763672h1.1367187v.457031c0 .422624.3390943.763672.7617187.763672h.3730469c.4226244 0 .7636719-.341048.7636719-.763672v-.457031h4.4062501v.457031c0 .422624.339094.763672.761719.763672h.373047c.422624 0 .763671-.341048.763671-.763672v-.457031h1.269532c.422625 0 .763672-.341048.763672-.763672v-1.111328c.01774.0012.03272.0098.05078.0098h.507812c.422624 0 .763672-.339093.763672-.761718v-.373047c0-.422624-.341048-.763672-.763672-.763672h-.507812c-.01803 0-.03307.0085-.05078.0098v-4.4258454c.01774.00122.03272.00977.05078.00977h.507812c.422624 0 .763672-.3390943.763672-.7617188v-.3730512c0-.4226244-.341048-.7636719-.763672-.7636719h-.507812c-.01803 0-.03307.00855-.05078.00977v-.9082075c0-.4226244-.341047-.7617187-.763672-.7617188h-1.328125c.03658-.089375.05859-.1862118.05859-.2890624v-.5078126c0-.42262437-.341047-.76367177-.763671-.76367177h-.373047c-.422625 0-.761719.3410474-.761719.76367177v.5078126c0 .1028478.02006.1996891.05664.2890624h-4.5214809c.036585-.0893749.0585938-.1862118.0585938-.2890624v-.5078126c0-.42262437-.3410475-.76367177-.7636719-.76367177zm3.2382813 2.35742177a3.279661 3.6440678 0 0 1 3.2128906 2.9394532 2.1864407 2.1864407 0 0 1 1.888672 2.1621094 2.1864407 2.1864407 0 0 1 -2.1875 2.1855475h-5.8300782a2.1864407 2.1864407 0 0 1 -2.1855469-2.1855475 2.1864407 2.1864407 0 0 1 1.8847656-2.1640626 3.279661 3.6440678 0 0 1 3.2167969-2.9375zm-2.9160156 8.0156251a.72881355.72881355 0 0 1 .7285156.728516.72881355.72881355 0 0 1 -.7285156.730469.72881355.72881355 0 0 1 -.7285157-.730469.72881355.72881355 0 0 1 .7285157-.728516zm5.8300782 0a.72881355.72881355 0 0 1 .730469.728516.72881355.72881355 0 0 1 -.730469.730469.72881355.72881355 0 0 1 -.7285157-.730469.72881355.72881355 0 0 1 .7285157-.728516zm-2.9140626.728516a.72881355.72881355 0 0 1 .7285156.730469.72881355.72881355 0 0 1 -.7285156.728515.72881355.72881355 0 0 1 -.7285156-.728515.72881355.72881355 0 0 1 .7285156-.730469z" fill="#a3b6f3" fill-opacity=".992157"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4.5587261.60940813c-.4226244 0-.7617187.3410473-.7617187.76367177v.5078126c0 .1028478.020058.199689.056641.2890624h-1.1933597c-.4226245 0-.7617188.3390944-.7617188.7617188v.921875c-.040428-.00657-.0767989-.0234375-.1191406-.0234375h-.5078125c-.42262448 0-.76367188.3410475-.76367188.7636719v.3730468c0 .4226245.3410474.7617188.76367188.7617188h.5078125c.042396 0 .078663-.016851.1191406-.023437v4.4531248c-.040428-.0066-.076799-.02344-.1191406-.02344h-.5078125c-.42262448 0-.76367188.341047-.76367188.763672v.373047c0 .422625.3410474.761718.76367188.761718h.5078125c.042396 0 .078663-.01685.1191406-.02344v1.125c0 .422624.3390944.763672.7617188.763672h1.1367187v.457031c0 .422624.3390943.763672.7617187.763672h.3730469c.4226244 0 .7636719-.341048.7636719-.763672v-.457031h4.4062501v.457031c0 .422624.339094.763672.761719.763672h.373047c.422624 0 .763671-.341048.763671-.763672v-.457031h1.269532c.422625 0 .763672-.341048.763672-.763672v-1.111328c.01774.0012.03272.0098.05078.0098h.507812c.422624 0 .763672-.339093.763672-.761718v-.373047c0-.422624-.341048-.763672-.763672-.763672h-.507812c-.01803 0-.03307.0085-.05078.0098v-4.4258454c.01774.00122.03272.00977.05078.00977h.507812c.422624 0 .763672-.3390943.763672-.7617188v-.3730512c0-.4226244-.341048-.7636719-.763672-.7636719h-.507812c-.01803 0-.03307.00855-.05078.00977v-.9082075c0-.4226244-.341047-.7617187-.763672-.7617188h-1.328125c.03658-.089375.05859-.1862118.05859-.2890624v-.5078126c0-.42262437-.341047-.76367177-.763671-.76367177h-.373047c-.422625 0-.761719.3410474-.761719.76367177v.5078126c0 .1028478.02006.1996891.05664.2890624h-4.5214809c.036585-.0893749.0585938-.1862118.0585938-.2890624v-.5078126c0-.42262437-.3410475-.76367177-.7636719-.76367177zm3.2382813 2.35742177a3.279661 3.6440678 0 0 1 3.2128906 2.9394532 2.1864407 2.1864407 0 0 1 1.888672 2.1621094 2.1864407 2.1864407 0 0 1 -2.1875 2.1855475h-5.8300782a2.1864407 2.1864407 0 0 1 -2.1855469-2.1855475 2.1864407 2.1864407 0 0 1 1.8847656-2.1640626 3.279661 3.6440678 0 0 1 3.2167969-2.9375zm-2.9160156 8.0156251a.72881355.72881355 0 0 1 .7285156.728516.72881355.72881355 0 0 1 -.7285156.730469.72881355.72881355 0 0 1 -.7285157-.730469.72881355.72881355 0 0 1 .7285157-.728516zm5.8300782 0a.72881355.72881355 0 0 1 .730469.728516.72881355.72881355 0 0 1 -.730469.730469.72881355.72881355 0 0 1 -.7285157-.730469.72881355.72881355 0 0 1 .7285157-.728516zm-2.9140626.728516a.72881355.72881355 0 0 1 .7285156.730469.72881355.72881355 0 0 1 -.7285156.728515.72881355.72881355 0 0 1 -.7285156-.728515.72881355.72881355 0 0 1 .7285156-.730469z" fill="#8da5f3" fill-opacity=".992157"/></svg>
diff --git a/editor/icons/Callable.svg b/editor/icons/Callable.svg
index d689f1a4c4..3f0d33a06c 100644
--- a/editor/icons/Callable.svg
+++ b/editor/icons/Callable.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 4.2333 4.2333" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 1c-2 2-4 4-7 4h-4v5h4c3 .000038 5 2 7 4zm1 4v5c2.5896-.015798 2.5896-4.9849 0-5zm-11 6v4h2l1-4z" fill="#e0e0e0" transform="scale(.26458)"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m12 1c-2 2-4 4-7 4h-4v5h4c3 0 5 2 7 4zm1 4v5c2.59-.016 2.59-4.985 0-5zm-11 6v4h2l1-4z" fill="#e0e0e0" fill-rule="nonzero"/></svg>
diff --git a/editor/icons/CanvasGroup.svg b/editor/icons/CanvasGroup.svg
index 232ae53231..110fcbd205 100644
--- a/editor/icons/CanvasGroup.svg
+++ b/editor/icons/CanvasGroup.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v6h-6v8h8v-6h6v-8zm2 2h4v4h-4z" fill="#a5b8f3" fill-opacity=".588235"/><path d="m1 1v2c0 .0000234.446 0 1 0s1 .0000234 1 0v-2c0-.00002341-.446 0-1 0s-1-.00002341-1 0zm12 0v2c0 .0000234.446 0 1 0s1 .0000234 1 0v-2c0-.00002341-.446 0-1 0s-1-.00002341-1 0zm-12 12v2c0 .000023.446 0 1 0s1 .000023 1 0v-2c0-.000023-.446 0-1 0s-1-.000023-1 0zm12 0v2c0 .000023.446 0 1 0s1 .000023 1 0v-2c0-.000023-.446 0-1 0s-1-.000023-1 0z" fill="#a5b7f4"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v6h-6v8h8v-6h6v-8zm2 2h4v4h-4z" fill="#8da5f3" fill-opacity=".588235"/><path d="m1 1v2c0 .0000234.446 0 1 0s1 .0000234 1 0v-2c0-.00002341-.446 0-1 0s-1-.00002341-1 0zm12 0v2c0 .0000234.446 0 1 0s1 .0000234 1 0v-2c0-.00002341-.446 0-1 0s-1-.00002341-1 0zm-12 12v2c0 .000023.446 0 1 0s1 .000023 1 0v-2c0-.000023-.446 0-1 0s-1-.000023-1 0zm12 0v2c0 .000023.446 0 1 0s1 .000023 1 0v-2c0-.000023-.446 0-1 0s-1-.000023-1 0z" fill="#8da5f3"/></svg>
diff --git a/editor/icons/CanvasModulate.svg b/editor/icons/CanvasModulate.svg
index a96fb75643..86cb7ef64c 100644
--- a/editor/icons/CanvasModulate.svg
+++ b/editor/icons/CanvasModulate.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m1 1037.4v14h14v-14zm2 2h10v10h-10z" fill="#8da5f3"/><g fill-rule="evenodd"><path d="m12 1048.4h-5l5-5z" fill="#70bfff"/><path d="m4 1040.4h5l-5 5z" fill="#ff4545"/><path d="m4 1048.4v-3l5-5h3v3l-5 5z" fill="#7aff70"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m1 1037.4v14h14v-14zm2 2h10v10h-10z" fill="#8da5f3"/><g fill-rule="evenodd"><path d="m12 1048.4h-5l5-5z" fill="#45d7ff"/><path d="m4 1040.4h5l-5 5z" fill="#ff4545"/><path d="m4 1048.4v-3l5-5h3v3l-5 5z" fill="#80ff45"/></g></g></svg>
diff --git a/editor/icons/CapsuleShape2D.svg b/editor/icons/CapsuleShape2D.svg
index 99a67d4641..5b3c411f9b 100644
--- a/editor/icons/CapsuleShape2D.svg
+++ b/editor/icons/CapsuleShape2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2.77 0-5 2.23-5 5v4c0 2.77 2.23 5 5 5s5-2.23 5-5v-4c0-2.77-2.23-5-5-5zm0 2c1.662 0 3 1.338 3 3v4c0 1.662-1.338 3-3 3s-3-1.338-3-3v-4c0-1.662 1.338-3 3-3z" fill="#68b6ff"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2.77 0-5 2.23-5 5v4c0 2.77 2.23 5 5 5s5-2.23 5-5v-4c0-2.77-2.23-5-5-5zm0 2c1.662 0 3 1.338 3 3v4c0 1.662-1.338 3-3 3s-3-1.338-3-3v-4c0-1.662 1.338-3 3-3z" fill="#5fb2ff"/></svg>
diff --git a/editor/icons/CapsuleShape3D.svg b/editor/icons/CapsuleShape3D.svg
index 4d5bc522b1..c566d68f19 100644
--- a/editor/icons/CapsuleShape3D.svg
+++ b/editor/icons/CapsuleShape3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m8 1037.4c-2.7527 0-5 2.2419-5 4.9903v4.0175c0 2.7484 2.2473 4.9922 5 4.9922s5-2.2438 5-4.9922v-4.0175c0-2.7484-2.2473-4.9903-5-4.9903z" fill="#68b6ff"/><circle cx="6.5" cy="1040.9" fill="#a2d2ff" r="1.5"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m8 1037.4c-2.7527 0-5 2.2419-5 4.9903v4.0175c0 2.7484 2.2473 4.9922 5 4.9922s5-2.2438 5-4.9922v-4.0175c0-2.7484-2.2473-4.9903-5-4.9903z" fill="#5fb2ff"/><circle cx="6.5" cy="1040.9" fill="#a2d2ff" r="1.5"/></g></svg>
diff --git a/editor/icons/CircleShape2D.svg b/editor/icons/CircleShape2D.svg
index d23ca6d8a3..37a0903a0c 100644
--- a/editor/icons/CircleShape2D.svg
+++ b/editor/icons/CircleShape2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1038.4a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" fill="none" stroke="#68b6ff" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1038.4a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6z" fill="none" stroke="#5fb2ff" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
diff --git a/editor/icons/CodeEdit.svg b/editor/icons/CodeEdit.svg
index 7f08340ffb..8461c739b4 100644
--- a/editor/icons/CodeEdit.svg
+++ b/editor/icons/CodeEdit.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m29 1042.4h1v1h-1z" fill="#fefeff"/><path d="m3 1c-1.1046 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm2 1-1 1 1 1-1 1 1 1 2-2zm2 3v1h2v-1z" fill="#8eef97" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 1c-1.1046 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm2 1-1 1 1 1-1 1 1 1 2-2zm2 3v1h2v-1z" fill="#8eef97" transform="translate(0 1036.4)"/></g></svg>
diff --git a/editor/icons/ColorRect.svg b/editor/icons/ColorRect.svg
index f08b17ed1f..e69591104f 100644
--- a/editor/icons/ColorRect.svg
+++ b/editor/icons/ColorRect.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m1 1v14h14v-14zm2 2h10v10h-10z" fill="#8eef97" transform="translate(0 1036.4)"/><g fill-rule="evenodd"><path d="m12 1048.4h-4.8l4.8-4.8z" fill="#70bfff"/><path d="m4 1040.4h4.8l-4.8 4.8z" fill="#ff4545"/><path d="m4 1048.4v-3.2l4.8-4.8h3.2v3.2l-4.8 4.8z" fill="#7aff70"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m1 1v14h14v-14zm2 2h10v10h-10z" fill="#8eef97" transform="translate(0 1036.4)"/><g fill-rule="evenodd"><path d="m12 1048.4h-4.8l4.8-4.8z" fill="#45d7ff"/><path d="m4 1040.4h4.8l-4.8 4.8z" fill="#ff4545"/><path d="m4 1048.4v-3.2l4.8-4.8h3.2v3.2l-4.8 4.8z" fill="#80ff45"/></g></g></svg>
diff --git a/editor/icons/ConcavePolygonShape2D.svg b/editor/icons/ConcavePolygonShape2D.svg
index 463fece525..26eda843a8 100644
--- a/editor/icons/ConcavePolygonShape2D.svg
+++ b/editor/icons/ConcavePolygonShape2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-12l6 6 6-6z" fill="none" stroke="#68b6ff" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-12l6 6 6-6z" fill="none" stroke="#5fb2ff" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
diff --git a/editor/icons/ConcavePolygonShape3D.svg b/editor/icons/ConcavePolygonShape3D.svg
index 60d1a6234f..67631ec0e7 100644
--- a/editor/icons/ConcavePolygonShape3D.svg
+++ b/editor/icons/ConcavePolygonShape3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><g fill="#2998ff"><path d="m8 1-7 3v8l7 3 7-3v-8z" transform="translate(0 1036.4)"/><path d="m8 1037.4-7 3v8l7 3 7-3v-8z"/><path d="m3 1041.4v6l5 2 5-2v-6l-5-2z"/></g><path d="m8 1049.4 5-2-5-2-5 2z" fill="#a2d2ff"/><path d="m8 1045.4 5 2v-6l-5-2z" fill="#68b6ff"/><g transform="translate(0 1036.4)"><path d="m8 1-7 3 2 1 5-2 5 2 2-1z" fill="#a2d2ff"/><path d="m1 4v8l7 3v-2l-5-2v-6z" fill="#68b6ff"/><path d="m15 4-2 1v6l-5 2v2l7-3z" fill="#2998ff"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><g fill="#2998ff"><path d="m8 1-7 3v8l7 3 7-3v-8z" transform="translate(0 1036.4)"/><path d="m8 1037.4-7 3v8l7 3 7-3v-8z"/><path d="m3 1041.4v6l5 2 5-2v-6l-5-2z"/></g><path d="m8 1049.4 5-2-5-2-5 2z" fill="#a2d2ff"/><path d="m8 1045.4 5 2v-6l-5-2z" fill="#5fb2ff"/><g transform="translate(0 1036.4)"><path d="m8 1-7 3 2 1 5-2 5 2 2-1z" fill="#a2d2ff"/><path d="m1 4v8l7 3v-2l-5-2v-6z" fill="#5fb2ff"/><path d="m15 4-2 1v6l-5 2v2l7-3z" fill="#2998ff"/></g></g></svg>
diff --git a/editor/icons/ConvexPolygonShape2D.svg b/editor/icons/ConvexPolygonShape2D.svg
index dc2b0faf81..fa5369aace 100644
--- a/editor/icons/ConvexPolygonShape2D.svg
+++ b/editor/icons/ConvexPolygonShape2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-6l6-6 6 6z" fill="none" stroke="#68b6ff" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14 1050.4h-12v-6l6-6 6 6z" fill="none" stroke="#5fb2ff" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
diff --git a/editor/icons/ConvexPolygonShape3D.svg b/editor/icons/ConvexPolygonShape3D.svg
index 3478289ab1..f0c9101c72 100644
--- a/editor/icons/ConvexPolygonShape3D.svg
+++ b/editor/icons/ConvexPolygonShape3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m8 1-7 3v8l7 3 7-3z" fill="#2998ff" transform="translate(0 1036.4)"/><path d="m8 1051.4-7-3v-8l7 3z" fill="#68b6ff"/><path d="m8 1-7 3 7 11 7-3z" fill="#2998ff" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m8 1-7 3v8l7 3 7-3z" fill="#2998ff" transform="translate(0 1036.4)"/><path d="m8 1051.4-7-3v-8l7 3z" fill="#5fb2ff"/><path d="m8 1-7 3 7 11 7-3z" fill="#2998ff" transform="translate(0 1036.4)"/></g></svg>
diff --git a/editor/icons/CurveClose.svg b/editor/icons/CurveClose.svg
index 5cb8ab890e..032f1c6c55 100644
--- a/editor/icons/CurveClose.svg
+++ b/editor/icons/CurveClose.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm8 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/><path d="m10 6v2h2v-2zm0 2h-2v2h2zm-2 2h-2v2h2z" fill="#5fb2ff"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#e0e0e0" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm8 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#ffffff"/><path d="m10 6v2h2v-2zm0 2h-2v2h2zm-2 2h-2v2h2z" fill="#5fb2ff"/></g></g></svg>
diff --git a/editor/icons/CurveCreate.svg b/editor/icons/CurveCreate.svg
index 1e80817a34..4e406b35f6 100644
--- a/editor/icons/CurveCreate.svg
+++ b/editor/icons/CurveCreate.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm6 5v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#5fff97"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#e0e0e0" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm6 5v3h-3v2h3v3h2v-3h3v-2h-3v-3z" fill="#5fff97"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#ffffff"/></g></g></svg>
diff --git a/editor/icons/CurveCurve.svg b/editor/icons/CurveCurve.svg
index e43e7ccd8a..b5312aea24 100644
--- a/editor/icons/CurveCurve.svg
+++ b/editor/icons/CurveCurve.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m8.4688.4707-2.6875 2.6875h-.0019531a2 2 0 0 0 -.7793-.1582 2 2 0 0 0 -2 2 2 2 0 0 0 .16016.7793l-2.6914 2.6914 1.0625 1.0605 2.6895-2.6895a2 2 0 0 0 .7793.1582 2 2 0 0 0 2-2 2 2 0 0 0 -.16016-.77734l2.6914-2.6914-1.0625-1.0605z" fill="#5fb2ff"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#e0e0e0" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m8.4688.4707-2.6875 2.6875h-.0019531a2 2 0 0 0 -.7793-.1582 2 2 0 0 0 -2 2 2 2 0 0 0 .16016.7793l-2.6914 2.6914 1.0625 1.0605 2.6895-2.6895a2 2 0 0 0 .7793.1582 2 2 0 0 0 2-2 2 2 0 0 0 -.16016-.77734l2.6914-2.6914-1.0625-1.0605z" fill="#5fb2ff"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#ffffff"/></g></g></svg>
diff --git a/editor/icons/CurveDelete.svg b/editor/icons/CurveDelete.svg
index cf15d75bc1..1c8f5e2aae 100644
--- a/editor/icons/CurveDelete.svg
+++ b/editor/icons/CurveDelete.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><path d="m5 1039.4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm4.8789 5.4648-1.4141 1.4141 2.1211 2.1211-2.1211 2.1211 1.4141 1.4141 2.1211-2.1211 2.1211 2.1211 1.4141-1.4141-2.1211-2.1211 2.1211-2.1211-1.4141-1.4141-2.1211 2.1211z" fill="#ff5f5f"/><path d="m13 1039.4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#e0e0e0" stroke-opacity=".39216" stroke-width="2"/><path d="m5 1039.4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm4.8789 5.4648-1.4141 1.4141 2.1211 2.1211-2.1211 2.1211 1.4141 1.4141 2.1211-2.1211 2.1211 2.1211 1.4141-1.4141-2.1211-2.1211 2.1211-2.1211-1.4141-1.4141-2.1211 2.1211z" fill="#ff5f5f"/><path d="m13 1039.4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#ffffff"/></g></svg>
diff --git a/editor/icons/CurveEdit.svg b/editor/icons/CurveEdit.svg
index 57e365f3cd..d8318a6bc3 100644
--- a/editor/icons/CurveEdit.svg
+++ b/editor/icons/CurveEdit.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#f5f5f5" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm3 5 3.291 8 .94726-2.8203 1.8828 1.8828.94336-.94141-1.8848-1.8828 2.8203-.94726-8-3.291z" fill="#5fb2ff"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#f5f5f5"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 1049.4c-2-9-1-10 8-8" fill="none" stroke="#e0e0e0" stroke-opacity=".39216" stroke-width="2"/><g transform="translate(0 1036.4)"><path d="m5 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm3 5 3.291 8 .94726-2.8203 1.8828 1.8828.94336-.94141-1.8848-1.8828 2.8203-.94726-8-3.291z" fill="#5fb2ff"/><path d="m13 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-8 8a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#ffffff"/></g></g></svg>
diff --git a/editor/icons/CylinderShape3D.svg b/editor/icons/CylinderShape3D.svg
index cbff4c8897..1283097848 100644
--- a/editor/icons/CylinderShape3D.svg
+++ b/editor/icons/CylinderShape3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m.890374 3.687944h13.171325v7.699331h-13.171325z" fill="#68b6ff"/><ellipse cx="7.477298" cy="3.722912" fill="#a2d2ff" rx="6.586479" ry="2.820821"/><ellipse cx="7.474688" cy="11.34481" fill="#68b6ff" rx="6.586479" ry="2.820821"/></svg>
+<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m.890374 3.687944h13.171325v7.699331h-13.171325z" fill="#5fb2ff"/><ellipse cx="7.477298" cy="3.722912" fill="#a2d2ff" rx="6.586479" ry="2.820821"/><ellipse cx="7.474688" cy="11.34481" fill="#5fb2ff" rx="6.586479" ry="2.820821"/></svg>
diff --git a/editor/icons/DebugSkipBreakpointsOff.svg b/editor/icons/DebugSkipBreakpointsOff.svg
index e7228c599f..aef0d45a05 100644
--- a/editor/icons/DebugSkipBreakpointsOff.svg
+++ b/editor/icons/DebugSkipBreakpointsOff.svg
@@ -1 +1 @@
-<svg height="17" viewBox="0 0 17 17" width="17" xmlns="http://www.w3.org/2000/svg"><path d="m4.8983252 3.006855a1.6192284 1.3289529 0 0 1 -.0000431.0097" stroke-width=".626319"/><path d="m8.796752 5.0553513a2.563139 3.6270869 0 0 1 -.0000683.02648" stroke-width=".626319"/><path d="m13.121337 4.512148a6.1594577 6.0545759 0 0 1 -.248787 8.20109 6.1594577 6.0545759 0 0 1 -8.3355404.427215 6.1594577 6.0545759 0 0 1 -1.1151058-8.1311866 6.1594577 6.0545759 0 0 1 8.1530832-1.7576713" fill="#ff8585" fill-opacity=".996078" stroke-width="1.019123"/></svg>
+<svg height="17" viewBox="0 0 17 17" width="17" xmlns="http://www.w3.org/2000/svg"><path d="m4.8983252 3.006855a1.6192284 1.3289529 0 0 1 -.0000431.0097" stroke-width=".626319"/><path d="m8.796752 5.0553513a2.563139 3.6270869 0 0 1 -.0000683.02648" stroke-width=".626319"/><path d="m13.121337 4.512148a6.1594577 6.0545759 0 0 1 -.248787 8.20109 6.1594577 6.0545759 0 0 1 -8.3355404.427215 6.1594577 6.0545759 0 0 1 -1.1151058-8.1311866 6.1594577 6.0545759 0 0 1 8.1530832-1.7576713" fill="#fc7f7f" fill-opacity=".996078" stroke-width="1.019123"/></svg>
diff --git a/editor/icons/DebugSkipBreakpointsOn.svg b/editor/icons/DebugSkipBreakpointsOn.svg
index 0836954bbb..d8fbc6e43a 100644
--- a/editor/icons/DebugSkipBreakpointsOn.svg
+++ b/editor/icons/DebugSkipBreakpointsOn.svg
@@ -1 +1 @@
-<svg height="17" viewBox="0 0 17 17" width="17" xmlns="http://www.w3.org/2000/svg"><path d="m4.8983252 3.006855a1.6192284 1.3289529 0 0 1 -.0000431.0097" stroke-width=".626319"/><path d="m8.796752 5.0553513a2.563139 3.6270869 0 0 1 -.0000683.02648" stroke-width=".626319"/><path d="m13.121337 4.512148a6.1594577 6.0545759 0 0 1 -.248787 8.20109 6.1594577 6.0545759 0 0 1 -8.3355404.427215 6.1594577 6.0545759 0 0 1 -1.1151058-8.1311866 6.1594577 6.0545759 0 0 1 8.1530832-1.7576713" fill="#ff8585" fill-opacity=".996078" stroke-width="1.019123"/><path d="m-9.290675 10.816157h18.575495v2.518711h-18.575495z" fill="#e0e0e0" stroke-width="1.187332" transform="matrix(.70605846 -.70815355 .70605846 .70815355 0 0)"/></svg>
+<svg height="17" viewBox="0 0 17 17" width="17" xmlns="http://www.w3.org/2000/svg"><path d="m4.8983252 3.006855a1.6192284 1.3289529 0 0 1 -.0000431.0097" stroke-width=".626319"/><path d="m8.796752 5.0553513a2.563139 3.6270869 0 0 1 -.0000683.02648" stroke-width=".626319"/><path d="m13.121337 4.512148a6.1594577 6.0545759 0 0 1 -.248787 8.20109 6.1594577 6.0545759 0 0 1 -8.3355404.427215 6.1594577 6.0545759 0 0 1 -1.1151058-8.1311866 6.1594577 6.0545759 0 0 1 8.1530832-1.7576713" fill="#fc7f7f" fill-opacity=".996078" stroke-width="1.019123"/><path d="m-9.290675 10.816157h18.575495v2.518711h-18.575495z" fill="#e0e0e0" stroke-width="1.187332" transform="matrix(.70605846 -.70815355 .70605846 .70815355 0 0)"/></svg>
diff --git a/editor/icons/Decal.svg b/editor/icons/Decal.svg
index 8c33f44360..d1f362bb26 100644
--- a/editor/icons/Decal.svg
+++ b/editor/icons/Decal.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2c-3.3137085 0-6 2.6862915-6 6 0 2.220299 1.2092804 4.153789 3.0019531 5.191406l8.9082029-6.1894529c-.476307-2.8374399-2.937354-5.0019531-5.910156-5.0019531z" fill="#fc7f7f"/><path d="m5.001954 13.191406 8.908202-6.1894529c-.882819-.510985-1.904638-.808594-2.998046-.808594-3.3137079 0-6 2.686292-6 5.9999999 0 .340906.03522.672663.08984.998047z" fill="#ff5d5d"/><path d="m13.910156 7.0019531-8.908202 6.1894529c.882819.510985 1.904638.808594 2.998046.808594 3.313708 0 6-2.686292 6-5.9999999 0-.340906-.03522-.672663-.08984-.998047z" fill="#fc7f7f" fill-opacity=".392157"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2c-3.3137085 0-6 2.6862915-6 6 0 2.220299 1.2092804 4.153789 3.0019531 5.191406l8.9082029-6.1894529c-.476307-2.8374399-2.937354-5.0019531-5.910156-5.0019531z" fill="#fc7f7f"/><path d="m5.001954 13.191406 8.908202-6.1894529c-.882819-.510985-1.904638-.808594-2.998046-.808594-3.3137079 0-6 2.686292-6 5.9999999 0 .340906.03522.672663.08984.998047z" fill="#ff5f5f"/><path d="m13.910156 7.0019531-8.908202 6.1894529c.882819.510985 1.904638.808594 2.998046.808594 3.313708 0 6-2.686292 6-5.9999999 0-.340906-.03522-.672663-.08984-.998047z" fill="#fc7f7f" fill-opacity=".392157"/></svg>
diff --git a/editor/icons/DirectionalLight2D.svg b/editor/icons/DirectionalLight2D.svg
index f30702b502..bc611a71bd 100644
--- a/editor/icons/DirectionalLight2D.svg
+++ b/editor/icons/DirectionalLight2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v3h2v-3zm-2.5352 2.0508-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm7.0703 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-3.5352 1.9492c-1.6569 0-3 1.3432-3 3s1.3431 3 3 3 3-1.3432 3-3-1.3431-3-3-3zm-7 2v2h3v-2zm11 0v2h3v-2zm-7.5352 3.1211-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm7.0703 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-4.5352 1.8789v3h2v-3z" fill="#a5b7f4"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v3h2v-3zm-2.5352 2.0508-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm7.0703 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-3.5352 1.9492c-1.6569 0-3 1.3432-3 3s1.3431 3 3 3 3-1.3432 3-3-1.3431-3-3-3zm-7 2v2h3v-2zm11 0v2h3v-2zm-7.5352 3.1211-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm7.0703 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-4.5352 1.8789v3h2v-3z" fill="#8da5f3"/></svg>
diff --git a/editor/icons/EditorBoneHandle.svg b/editor/icons/EditorBoneHandle.svg
index a6d7c3f878..378c2ea8c1 100644
--- a/editor/icons/EditorBoneHandle.svg
+++ b/editor/icons/EditorBoneHandle.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><circle cx="4" cy="4" fill="#fff" r="4"/><circle cx="4" cy="4" fill="#000" r="2.5"/></svg>
+<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><circle cx="4" cy="4" fill="#fff" r="4"/><circle cx="4" cy="4" fill="#000000" r="2.5"/></svg>
diff --git a/editor/icons/EditorControlAnchor.svg b/editor/icons/EditorControlAnchor.svg
index 3383ea121f..a638ee8d00 100644
--- a/editor/icons/EditorControlAnchor.svg
+++ b/editor/icons/EditorControlAnchor.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 0a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 1.0566-.11914l9.9434 6.1191-6.1172-9.9395a5 5 0 0 0 .11719-1.0605 5 5 0 0 0 -5-5z" fill-opacity=".39216" transform="translate(0 1036.4)"/><path d="m5 1a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 1.1406-.16992l9.8594 7.1699-7.168-9.8555a4 4 0 0 0 .16797-1.1445 4 4 0 0 0 -4-4z" fill="#8eef97" fill-rule="evenodd" transform="translate(0 1036.4)"/><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/><circle cx="5" cy="1041.4" fill="#8eef97" r="0"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m5 0a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 1.0566-.11914l9.9434 6.1191-6.1172-9.9395a5 5 0 0 0 .11719-1.0605 5 5 0 0 0 -5-5z" fill-opacity=".39216" transform="translate(0 1036.4)"/><path d="m5 1a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 1.1406-.16992l9.8594 7.1699-7.168-9.8555a4 4 0 0 0 .16797-1.1445 4 4 0 0 0 -4-4z" fill="#8eef97" fill-rule="evenodd" transform="translate(0 1036.4)"/></g></svg>
diff --git a/editor/icons/EditorCurveHandle.svg b/editor/icons/EditorCurveHandle.svg
index e0f3256807..e57d6b5dbb 100644
--- a/editor/icons/EditorCurveHandle.svg
+++ b/editor/icons/EditorCurveHandle.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" fill="#fefefe" r="4.4" stroke="#000" stroke-linecap="square" stroke-width="1.6"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" fill="#ffffff" r="4.4" stroke="#000000" stroke-linecap="square" stroke-width="1.6"/></svg>
diff --git a/editor/icons/EditorPathSharpHandle.svg b/editor/icons/EditorPathSharpHandle.svg
index 5166930cca..1bdf32df57 100644
--- a/editor/icons/EditorPathSharpHandle.svg
+++ b/editor/icons/EditorPathSharpHandle.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14.868629 8.0000002-6.8686288 6.8686288-6.8686293-6.8686288 6.8686293-6.8686293z" fill="#fefefe" stroke="#000" stroke-linecap="square" stroke-width="1.6"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m14.868629 8.0000002-6.8686288 6.8686288-6.8686293-6.8686288 6.8686293-6.8686293z" fill="#ffffff" stroke="#000000" stroke-linecap="square" stroke-width="1.6"/></svg>
diff --git a/editor/icons/EditorPathSmoothHandle.svg b/editor/icons/EditorPathSmoothHandle.svg
index 2ab4f3a96a..d4bd434020 100644
--- a/editor/icons/EditorPathSmoothHandle.svg
+++ b/editor/icons/EditorPathSmoothHandle.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13.6 2.4v11.2h-11.2v-11.2z" fill="#fefefe" stroke="#000" stroke-linecap="square" stroke-width="1.6"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13.6 2.4v11.2h-11.2v-11.2z" fill="#ffffff" stroke="#000000" stroke-linecap="square" stroke-width="1.6"/></svg>
diff --git a/editor/icons/EditorPositionPrevious.svg b/editor/icons/EditorPositionPrevious.svg
index ba69650d81..159a4c0167 100644
--- a/editor/icons/EditorPositionPrevious.svg
+++ b/editor/icons/EditorPositionPrevious.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v3.0605a4.2662 4.0576 0 0 1 1-.11914 4.2662 4.0576 0 0 1 1 .11914v-3.0605zm1 4.0801a2.9201 2.9201 0 0 0 -2.9199 2.9199 2.9201 2.9201 0 0 0 2.9199 2.9199 2.9201 2.9201 0 0 0 2.9199-2.9199 2.9201 2.9201 0 0 0 -2.9199-2.9199zm-7 1.9199v2h2.8691a4.2662 4.0576 0 0 1 -.13477-1 4.2662 4.0576 0 0 1 .13672-1h-2.8711zm11.131 0a4.2662 4.0576 0 0 1 .13477 1 4.2662 4.0576 0 0 1 -.13672 1h2.8711v-2h-2.8691zm-5.1309 4.9395v3.0605h2v-3.0605a4.2662 4.0576 0 0 1 -1 .11914 4.2662 4.0576 0 0 1 -1-.11914z" fill="#69f" fill-opacity=".69804"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v3.0605a4.2662 4.0576 0 0 1 1-.11914 4.2662 4.0576 0 0 1 1 .11914v-3.0605zm1 4.0801a2.9201 2.9201 0 0 0 -2.9199 2.9199 2.9201 2.9201 0 0 0 2.9199 2.9199 2.9201 2.9201 0 0 0 2.9199-2.9199 2.9201 2.9201 0 0 0 -2.9199-2.9199zm-7 1.9199v2h2.8691a4.2662 4.0576 0 0 1 -.13477-1 4.2662 4.0576 0 0 1 .13672-1h-2.8711zm11.131 0a4.2662 4.0576 0 0 1 .13477 1 4.2662 4.0576 0 0 1 -.13672 1h2.8711v-2h-2.8691zm-5.1309 4.9395v3.0605h2v-3.0605a4.2662 4.0576 0 0 1 -1 .11914 4.2662 4.0576 0 0 1 -1-.11914z" fill="#5fb2ff" fill-opacity=".69804"/></svg>
diff --git a/editor/icons/EditorPositionUnselected.svg b/editor/icons/EditorPositionUnselected.svg
index 881fcab079..30aaa77659 100644
--- a/editor/icons/EditorPositionUnselected.svg
+++ b/editor/icons/EditorPositionUnselected.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 0v4.4199a4.2662 4.0576 0 0 0 -1.709 1.5801h-4.291v4h4.2949a4.2662 4.0576 0 0 0 1.7051 1.582v4.418h4v-4.4199a4.2662 4.0576 0 0 0 1.709-1.5801h4.291v-4h-4.2949a4.2662 4.0576 0 0 0 -1.7051-1.582v-4.418z" fill-opacity=".41077"/><path d="m7 1v3.0605a4.2662 4.0576 0 0 1 1-.11914 4.2662 4.0576 0 0 1 1 .11914v-3.0605zm1 4.0801a2.9201 2.9201 0 0 0 -2.9199 2.9199 2.9201 2.9201 0 0 0 2.9199 2.9199 2.9201 2.9201 0 0 0 2.9199-2.9199 2.9201 2.9201 0 0 0 -2.9199-2.9199zm-7 1.9199v2h2.8691a4.2662 4.0576 0 0 1 -.13477-1 4.2662 4.0576 0 0 1 .13672-1h-2.8711zm11.131 0a4.2662 4.0576 0 0 1 .13477 1 4.2662 4.0576 0 0 1 -.13672 1h2.8711v-2h-2.8691zm-5.1309 4.9395v3.0605h2v-3.0605a4.2662 4.0576 0 0 1 -1 .11914 4.2662 4.0576 0 0 1 -1-.11914z" fill="#d9d9d9"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 0v4.4199a4.2662 4.0576 0 0 0 -1.709 1.5801h-4.291v4h4.2949a4.2662 4.0576 0 0 0 1.7051 1.582v4.418h4v-4.4199a4.2662 4.0576 0 0 0 1.709-1.5801h4.291v-4h-4.2949a4.2662 4.0576 0 0 0 -1.7051-1.582v-4.418z" fill-opacity=".41077"/><path d="m7 1v3.0605a4.2662 4.0576 0 0 1 1-.11914 4.2662 4.0576 0 0 1 1 .11914v-3.0605zm1 4.0801a2.9201 2.9201 0 0 0 -2.9199 2.9199 2.9201 2.9201 0 0 0 2.9199 2.9199 2.9201 2.9201 0 0 0 2.9199-2.9199 2.9201 2.9201 0 0 0 -2.9199-2.9199zm-7 1.9199v2h2.8691a4.2662 4.0576 0 0 1 -.13477-1 4.2662 4.0576 0 0 1 .13672-1h-2.8711zm11.131 0a4.2662 4.0576 0 0 1 .13477 1 4.2662 4.0576 0 0 1 -.13672 1h2.8711v-2h-2.8691zm-5.1309 4.9395v3.0605h2v-3.0605a4.2662 4.0576 0 0 1 -1 .11914 4.2662 4.0576 0 0 1 -1-.11914z" fill="#d6d6d6"/></svg>
diff --git a/editor/icons/Error.svg b/editor/icons/Error.svg
index 4b306ae1ca..8478decb41 100644
--- a/editor/icons/Error.svg
+++ b/editor/icons/Error.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><rect fill="#ff5d5d" height="8" ry="4" width="8"/></svg>
+<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><rect fill="#ff5f5f" height="8" ry="4" width="8"/></svg>
diff --git a/editor/icons/ErrorWarning.svg b/editor/icons/ErrorWarning.svg
index 53b7be2763..e034bf194f 100644
--- a/editor/icons/ErrorWarning.svg
+++ b/editor/icons/ErrorWarning.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m4 0c-2.216 0-4 1.784-4 4s1.784 4 4 4z" fill="#ff5d5d"/><path d="m4 .00000003c2.216 0 4 1.78399997 4 3.99999997s-1.784 4-4 4z" fill="#ffdd65"/></svg>
+<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m4 0c-2.216 0-4 1.784-4 4s1.784 4 4 4z" fill="#ff5f5f"/><path d="m4 .00000003c2.216 0 4 1.78399997 4 3.99999997s-1.784 4-4 4z" fill="#ffdd65"/></svg>
diff --git a/editor/icons/FileBroken.svg b/editor/icons/FileBroken.svg
index 2f5099aa29..d68c89e240 100644
--- a/editor/icons/FileBroken.svg
+++ b/editor/icons/FileBroken.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1v8.5859l1.293-1.293a1.0001 1.0001 0 0 1 .69141-.29102 1.0001 1.0001 0 0 1 .72266.29102l2.293 2.293 2.293-2.293a1.0001 1.0001 0 0 1 1.4141 0l2.293 2.293 1-1v-3.5859h-5v-5h-7zm8 0v4h4zm-6 9.4141-2 2v2.5859h12v-2.5859l-.29297.29297a1.0001 1.0001 0 0 1 -1.4141 0l-2.293-2.293-2.293 2.293a1.0001 1.0001 0 0 1 -1.4141 0l-2.293-2.293z" fill="#ff5d5d" transform="translate(0 -.000017)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1v8.5859l1.293-1.293a1.0001 1.0001 0 0 1 .69141-.29102 1.0001 1.0001 0 0 1 .72266.29102l2.293 2.293 2.293-2.293a1.0001 1.0001 0 0 1 1.4141 0l2.293 2.293 1-1v-3.5859h-5v-5h-7zm8 0v4h4zm-6 9.4141-2 2v2.5859h12v-2.5859l-.29297.29297a1.0001 1.0001 0 0 1 -1.4141 0l-2.293-2.293-2.293 2.293a1.0001 1.0001 0 0 1 -1.4141 0l-2.293-2.293z" fill="#ff5f5f" transform="translate(0 -.000017)"/></svg>
diff --git a/editor/icons/FileBrokenBigThumb.svg b/editor/icons/FileBrokenBigThumb.svg
index effaa0afe9..7dc5a14452 100644
--- a/editor/icons/FileBrokenBigThumb.svg
+++ b/editor/icons/FileBrokenBigThumb.svg
@@ -1 +1 @@
-<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><path d="m14 5c-2.1987 0-4 1.8013-4 4v26.172a1.0001 1.0001 0 0 0 1.707.70703l3.293-3.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l9.293-9.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l8-8a1.0001 1.0001 0 0 0 .29297-.70703v-11.172a1.0001 1.0001 0 0 0 -.29297-.70703l-16-16a1.0001 1.0001 0 0 0 -.70703-.29297h-23zm0 2h22v12c0 2.1987 1.8013 4 4 4h12v9.7578l-7 7-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-9.293 9.293-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-2.293 2.293v-23.758c0-1.1253.87473-2 2-2zm.98438 28.83a1.0001 1.0001 0 0 0 -.69141.29297l-4 4a1.0001 1.0001 0 0 0 -.29297.70703v14.17c0 2.1987 1.8013 4 4 4h36c2.1987 0 4-1.8013 4-4v-16.17a1.0001 1.0001 0 0 0 -1.707-.70703l-7.293 7.293-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-9.293 9.293-9.293-9.293a1.0001 1.0001 0 0 0 -.72266-.29297zm.015625 2.4141 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l9.293-9.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l6.293-6.293v13.756c0 1.1253-.87473 2-2 2h-36c-1.1253 0-2-.87473-2-2v-13.756l3-3z" fill="#ff5d5d" transform="translate(0 -.000017)"/></svg>
+<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><path d="m14 5c-2.1987 0-4 1.8013-4 4v26.172a1.0001 1.0001 0 0 0 1.707.70703l3.293-3.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l9.293-9.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l8-8a1.0001 1.0001 0 0 0 .29297-.70703v-11.172a1.0001 1.0001 0 0 0 -.29297-.70703l-16-16a1.0001 1.0001 0 0 0 -.70703-.29297h-23zm0 2h22v12c0 2.1987 1.8013 4 4 4h12v9.7578l-7 7-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-9.293 9.293-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-2.293 2.293v-23.758c0-1.1253.87473-2 2-2zm.98438 28.83a1.0001 1.0001 0 0 0 -.69141.29297l-4 4a1.0001 1.0001 0 0 0 -.29297.70703v14.17c0 2.1987 1.8013 4 4 4h36c2.1987 0 4-1.8013 4-4v-16.17a1.0001 1.0001 0 0 0 -1.707-.70703l-7.293 7.293-9.293-9.293a1.0001 1.0001 0 0 0 -1.4141 0l-9.293 9.293-9.293-9.293a1.0001 1.0001 0 0 0 -.72266-.29297zm.015625 2.4141 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l9.293-9.293 9.293 9.293a1.0001 1.0001 0 0 0 1.4141 0l6.293-6.293v13.756c0 1.1253-.87473 2-2 2h-36c-1.1253 0-2-.87473-2-2v-13.756l3-3z" fill="#ff5f5f" transform="translate(0 -.000017)"/></svg>
diff --git a/editor/icons/FileDead.svg b/editor/icons/FileDead.svg
index f8df831a22..b5c18f3780 100644
--- a/editor/icons/FileDead.svg
+++ b/editor/icons/FileDead.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1v14h12v-9h-5v-5zm8 0v4h4zm-6.0078 6c.1353-.0020779.26567.050774.36133.14648l.64648.64648.64648-.64648c.09183-.091882.21582-.14442.3457-.14648.1353-.00208.26567.050774.36133.14648.19521.19525.19521.51178 0 .70703l-.64648.64648.64648.64648c.19521.19525.19521.51178 0 .70703-.19525.19521-.51178.19521-.70703 0l-.64648-.64648-.64648.64648c-.19525.19521-.51178.19521-.70703 0-.19521-.19525-.19521-.51178 0-.70703l.64648-.64648-.64648-.64648c-.19521-.19525-.19521-.51178 0-.70703.09183-.091882.21582-.14442.3457-.14648zm6 0c.1353-.00208.26567.050774.36133.14648l.64648.64648.64648-.64648c.09183-.091883.21582-.14442.3457-.14648.1353-.00208.26567.050774.36133.14648.19521.19525.19521.51178 0 .70703l-.64648.64648.64648.64648c.19521.19525.19521.51178 0 .70703-.19525.19521-.51178.19521-.70703 0l-.64648-.64648-.64648.64648c-.19525.19521-.51178.19521-.70703 0-.19521-.19525-.19521-.51178 0-.70703l.64648-.64648-.64648-.64648c-.19521-.19525-.19521-.51178 0-.70703.09183-.091882.21582-.14442.3457-.14648zm-6.4922 4h9c.277 0 .5.223.5.5s-.223.5-.5.5h-4.5c0 1.1046-.89543 2-2 2s-2-.8954-2-2h-.5c-.277 0-.5-.223-.5-.5s.223-.5.5-.5zm1.5 1c-.000019.5523.44771 1 1 1s1-.4477 1-1z" fill="#ff5d5d" transform="translate(0 -.000017)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1v14h12v-9h-5v-5zm8 0v4h4zm-6.0078 6c.1353-.0020779.26567.050774.36133.14648l.64648.64648.64648-.64648c.09183-.091882.21582-.14442.3457-.14648.1353-.00208.26567.050774.36133.14648.19521.19525.19521.51178 0 .70703l-.64648.64648.64648.64648c.19521.19525.19521.51178 0 .70703-.19525.19521-.51178.19521-.70703 0l-.64648-.64648-.64648.64648c-.19525.19521-.51178.19521-.70703 0-.19521-.19525-.19521-.51178 0-.70703l.64648-.64648-.64648-.64648c-.19521-.19525-.19521-.51178 0-.70703.09183-.091882.21582-.14442.3457-.14648zm6 0c.1353-.00208.26567.050774.36133.14648l.64648.64648.64648-.64648c.09183-.091883.21582-.14442.3457-.14648.1353-.00208.26567.050774.36133.14648.19521.19525.19521.51178 0 .70703l-.64648.64648.64648.64648c.19521.19525.19521.51178 0 .70703-.19525.19521-.51178.19521-.70703 0l-.64648-.64648-.64648.64648c-.19525.19521-.51178.19521-.70703 0-.19521-.19525-.19521-.51178 0-.70703l.64648-.64648-.64648-.64648c-.19521-.19525-.19521-.51178 0-.70703.09183-.091882.21582-.14442.3457-.14648zm-6.4922 4h9c.277 0 .5.223.5.5s-.223.5-.5.5h-4.5c0 1.1046-.89543 2-2 2s-2-.8954-2-2h-.5c-.277 0-.5-.223-.5-.5s.223-.5.5-.5zm1.5 1c-.000019.5523.44771 1 1 1s1-.4477 1-1z" fill="#ff5f5f" transform="translate(0 -.000017)"/></svg>
diff --git a/editor/icons/FileDeadBigThumb.svg b/editor/icons/FileDeadBigThumb.svg
index ca4578e7b7..0c1e3e03c6 100644
--- a/editor/icons/FileDeadBigThumb.svg
+++ b/editor/icons/FileDeadBigThumb.svg
@@ -1 +1 @@
-<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><path d="m14 993.36c-2.1987 0-4 1.8013-4 4v46c0 2.1987 1.8013 4 4 4h36c2.1987 0 4-1.8013 4-4v-33h-.0078c.002-.2483-.0793-.501-.28516-.707l-16-16c-.18788-.18693-.44247-.28939-.70704-.28907v-.004zm0 2h22v12c0 2.1987 1.8013 4 4 4h12v32c0 1.1253-.87472 2-2 2h-36c-1.1253 0-2-.8747-2-2v-46c0-1.1253.87472-2 2-2zm2.9512 22.002a1 1 0 0 0 -.60938.2461 1 1 0 0 0 -.09375 1.4121l2.9238 3.3398-2.9238 3.3418a1 1 0 0 0 .09375 1.4121 1 1 0 0 0 1.4102-.094l2.748-3.1407 2.748 3.1407a1 1 0 0 0 1.4102.094 1 1 0 0 0 .09375-1.4121l-2.9238-3.3418 2.9238-3.3398a1 1 0 0 0 -.09375-1.4121 1 1 0 0 0 -.63867-.2461 1 1 0 0 0 -.77148.3398l-2.748 3.1406-2.748-3.1406a1 1 0 0 0 -.80078-.3398zm23 0a1 1 0 0 0 -.60938.2461 1 1 0 0 0 -.09375 1.4121l2.9238 3.3398-2.9238 3.3418a1 1 0 0 0 .09375 1.4121 1 1 0 0 0 1.4102-.094l2.748-3.1407 2.748 3.1407a1 1 0 0 0 1.4102.094 1 1 0 0 0 .09375-1.4121l-2.9238-3.3418 2.9238-3.3398a1 1 0 0 0 -.09375-1.4121 1 1 0 0 0 -.63867-.2461 1 1 0 0 0 -.77148.3398l-2.748 3.1406-2.748-3.1406a1 1 0 0 0 -.80078-.3398zm-18.951 13.998a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h3v3c0 2.7527 2.2473 5 5 5s5-2.2473 5-5v-3h9a1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm5 2h6v3c0 1.6793-1.3207 3-3 3s-3-1.3207-3-3z" fill="#ff5d5d" transform="translate(0 -988.360017)"/></svg>
+<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><path d="m14 993.36c-2.1987 0-4 1.8013-4 4v46c0 2.1987 1.8013 4 4 4h36c2.1987 0 4-1.8013 4-4v-33h-.0078c.002-.2483-.0793-.501-.28516-.707l-16-16c-.18788-.18693-.44247-.28939-.70704-.28907v-.004zm0 2h22v12c0 2.1987 1.8013 4 4 4h12v32c0 1.1253-.87472 2-2 2h-36c-1.1253 0-2-.8747-2-2v-46c0-1.1253.87472-2 2-2zm2.9512 22.002a1 1 0 0 0 -.60938.2461 1 1 0 0 0 -.09375 1.4121l2.9238 3.3398-2.9238 3.3418a1 1 0 0 0 .09375 1.4121 1 1 0 0 0 1.4102-.094l2.748-3.1407 2.748 3.1407a1 1 0 0 0 1.4102.094 1 1 0 0 0 .09375-1.4121l-2.9238-3.3418 2.9238-3.3398a1 1 0 0 0 -.09375-1.4121 1 1 0 0 0 -.63867-.2461 1 1 0 0 0 -.77148.3398l-2.748 3.1406-2.748-3.1406a1 1 0 0 0 -.80078-.3398zm23 0a1 1 0 0 0 -.60938.2461 1 1 0 0 0 -.09375 1.4121l2.9238 3.3398-2.9238 3.3418a1 1 0 0 0 .09375 1.4121 1 1 0 0 0 1.4102-.094l2.748-3.1407 2.748 3.1407a1 1 0 0 0 1.4102.094 1 1 0 0 0 .09375-1.4121l-2.9238-3.3418 2.9238-3.3398a1 1 0 0 0 -.09375-1.4121 1 1 0 0 0 -.63867-.2461 1 1 0 0 0 -.77148.3398l-2.748 3.1406-2.748-3.1406a1 1 0 0 0 -.80078-.3398zm-18.951 13.998a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h3v3c0 2.7527 2.2473 5 5 5s5-2.2473 5-5v-3h9a1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm5 2h6v3c0 1.6793-1.3207 3-3 3s-3-1.3207-3-3z" fill="#ff5f5f" transform="translate(0 -988.360017)"/></svg>
diff --git a/editor/icons/FileDeadMediumThumb.svg b/editor/icons/FileDeadMediumThumb.svg
index 2d1808b90a..6ca43c8903 100644
--- a/editor/icons/FileDeadMediumThumb.svg
+++ b/editor/icons/FileDeadMediumThumb.svg
@@ -1 +1 @@
-<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-1.6447 0-3 1.3553-3 3v24c0 1.6447 1.3553 3 3 3h22c1.6447 0 3-1.3553 3-3v-16.809c-.000051-.2652-.10543-.51952-.29297-.70703l-9.1816-9.1895c-.18719-.18825-.44155-.29435-.70703-.29492h-14.818zm0 2h14v6c0 1.6447 1.3553 3 3 3h6v16c0 .5713-.42868 1-1 1h-22c-.57133 0-1-.4287-1-1v-24c0-.5713.42867-1 1-1zm1.9863 11.002a1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l1.293 1.293-1.293 1.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l1.293-1.293 1.293 1.293a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-1.293-1.293 1.293-1.293a1 1 0 0 0 0-1.4141 1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102l-1.293 1.293-1.293-1.293a1 1 0 0 0 -.7207-.29102zm14 0a1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l1.293 1.293-1.293 1.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l1.293-1.293 1.293 1.293a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-1.293-1.293 1.293-1.293a1 1 0 0 0 0-1.4141 1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102l-1.293 1.293-1.293-1.293a1 1 0 0 0 -.7207-.29102zm-13.986 7.998a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h1a4 4 0 0 0 2 3.4648 4 4 0 0 0 4 0 4 4 0 0 0 2-3.4648h9a1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm3 2h4a2 2 0 0 1 -2 2 2 2 0 0 1 -2-2z" fill="#ff5d5d" transform="translate(0 -.000017)"/></svg>
+<svg height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="m5 1c-1.6447 0-3 1.3553-3 3v24c0 1.6447 1.3553 3 3 3h22c1.6447 0 3-1.3553 3-3v-16.809c-.000051-.2652-.10543-.51952-.29297-.70703l-9.1816-9.1895c-.18719-.18825-.44155-.29435-.70703-.29492h-14.818zm0 2h14v6c0 1.6447 1.3553 3 3 3h6v16c0 .5713-.42868 1-1 1h-22c-.57133 0-1-.4287-1-1v-24c0-.5713.42867-1 1-1zm1.9863 11.002a1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l1.293 1.293-1.293 1.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l1.293-1.293 1.293 1.293a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-1.293-1.293 1.293-1.293a1 1 0 0 0 0-1.4141 1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102l-1.293 1.293-1.293-1.293a1 1 0 0 0 -.7207-.29102zm14 0a1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l1.293 1.293-1.293 1.293a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l1.293-1.293 1.293 1.293a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-1.293-1.293 1.293-1.293a1 1 0 0 0 0-1.4141 1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102l-1.293 1.293-1.293-1.293a1 1 0 0 0 -.7207-.29102zm-13.986 7.998a1 1 0 0 0 -1 1 1 1 0 0 0 1 1h1a4 4 0 0 0 2 3.4648 4 4 0 0 0 4 0 4 4 0 0 0 2-3.4648h9a1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm3 2h4a2 2 0 0 1 -2 2 2 2 0 0 1 -2-2z" fill="#ff5f5f" transform="translate(0 -.000017)"/></svg>
diff --git a/editor/icons/GizmoCPUParticles3D.svg b/editor/icons/GizmoCPUParticles3D.svg
index 785cd81625..e62dd530c4 100644
--- a/editor/icons/GizmoCPUParticles3D.svg
+++ b/editor/icons/GizmoCPUParticles3D.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m35.503779 1.2819066c-3.570424 0-6.435164 2.9483368-6.435164 6.6019028v4.3900146c0 .889114.169457 1.726301.478513 2.49893h-10.081759c-3.570424 0-6.435167 2.931453-6.435167 6.585021v7.969562c-.341543-.0568-.648813-.202614-1.006525-.202614h-4.2901096c-3.5704232 0-6.451665 2.948338-6.451665 6.601904v3.224972c0 3.653568 2.8812418 6.585016 6.451665 6.585016h4.2901096c.358169 0 .664563-.14568 1.006525-.202618v38.497043c-.341543-.05706-.648814-.202616-1.006525-.202616h-4.2901096c-3.5704232 0-6.451665 2.948332-6.451665 6.601908v3.224971c0 3.653575 2.8812418 6.585017 6.451665 6.585017h4.2901096c.358169 0 .664563-.145692 1.006525-.202612v9.725542c0 3.6536 2.864743 6.60193 6.435167 6.60193h9.603246v3.951c0 3.65357 2.86474 6.60192 6.435164 6.60192h3.15158c3.57042 0 6.451663-2.94836 6.451663-6.60192v-3.95104h37.224955v3.951c0 3.65358 2.86474 6.60193 6.435166 6.60193h3.151583c3.570418 0 6.451653-2.94836 6.451653-6.60193v-3.951h10.725281c3.57043 0 6.45166-2.94833 6.45166-6.60191v-9.607372c.14985.0105.27643.0846.42899.0846h4.29014c3.5704 0 6.45165-2.931432 6.45165-6.585011v-3.224992c0-3.653565-2.88125-6.601906-6.45165-6.601906h-4.29014c-.15231 0-.27938.07348-.42899.08472v-38.261071c.14985.01042.27643.08445.42899.08445h4.29014c3.5704 0 6.45165-2.931451 6.45165-6.585023v-3.224986c0-3.653566-2.88125-6.601906-6.45165-6.601906h-4.29014c-.15231 0-.27938.07392-.42899.08446v-7.851429c0-3.653567-2.88123-6.585019-6.45166-6.585021h-11.220281c.309043-.772641.494982-1.609791.494982-2.498929v-4.3900086c0-3.6535651-2.881246-6.601903-6.451662-6.601903h-3.15158c-3.570428 0-6.435167 2.9483379-6.435167 6.601903v4.3900146c0 .889115.16948 1.726301.478507 2.49893h-38.198448c.309083-.772642.495011-1.609792.495011-2.49893v-4.3900146c0-3.6535651-2.881243-6.601903-6.451663-6.601903z" fill="#f7f5cf" stroke="#b4b4b4" stroke-width="2.563805"/><g fill="#b4b4b4" stroke-width="8.546018"><path d="m62.861474 21.661698a27.707285 31.502779 0 0 1 27.143197 25.411422 18.471523 18.901669 0 0 1 15.955909 18.691329 18.471523 18.901669 0 0 1 -18.480472 18.893947h-49.25376a18.471523 18.901669 0 0 1 -18.463973-18.893947 18.471523 18.901669 0 0 1 15.922908-18.708215 27.707285 31.502779 0 0 1 27.176191-25.394536z"/><path d="m38.226348 90.956369a6.1571744 6.3005562 0 0 1 6.154657 6.297979 6.1571744 6.3005562 0 0 1 -6.154657 6.314882 6.1571744 6.3005562 0 0 1 -6.154657-6.314882 6.1571744 6.3005562 0 0 1 6.154657-6.297979z"/><path d="m87.480108 90.956369a6.1571744 6.3005562 0 0 1 6.171159 6.297979 6.1571744 6.3005562 0 0 1 -6.171159 6.314882 6.1571744 6.3005562 0 0 1 -6.154656-6.314882 6.1571744 6.3005562 0 0 1 6.154656-6.297979z"/><path d="m62.861474 97.254348a6.1571744 6.3005562 0 0 1 6.154662 6.314882 6.1571744 6.3005562 0 0 1 -6.154662 6.29797 6.1571744 6.3005562 0 0 1 -6.154651-6.29797 6.1571744 6.3005562 0 0 1 6.154651-6.314882z"/></g></svg>
+<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m35.503779 1.2819066c-3.570424 0-6.435164 2.9483368-6.435164 6.6019028v4.3900146c0 .889114.169457 1.726301.478513 2.49893h-10.081759c-3.570424 0-6.435167 2.931453-6.435167 6.585021v7.969562c-.341543-.0568-.648813-.202614-1.006525-.202614h-4.2901096c-3.5704232 0-6.451665 2.948338-6.451665 6.601904v3.224972c0 3.653568 2.8812418 6.585016 6.451665 6.585016h4.2901096c.358169 0 .664563-.14568 1.006525-.202618v38.497043c-.341543-.05706-.648814-.202616-1.006525-.202616h-4.2901096c-3.5704232 0-6.451665 2.948332-6.451665 6.601908v3.224971c0 3.653575 2.8812418 6.585017 6.451665 6.585017h4.2901096c.358169 0 .664563-.145692 1.006525-.202612v9.725542c0 3.6536 2.864743 6.60193 6.435167 6.60193h9.603246v3.951c0 3.65357 2.86474 6.60192 6.435164 6.60192h3.15158c3.57042 0 6.451663-2.94836 6.451663-6.60192v-3.95104h37.224955v3.951c0 3.65358 2.86474 6.60193 6.435166 6.60193h3.151583c3.570418 0 6.451653-2.94836 6.451653-6.60193v-3.951h10.725281c3.57043 0 6.45166-2.94833 6.45166-6.60191v-9.607372c.14985.0105.27643.0846.42899.0846h4.29014c3.5704 0 6.45165-2.931432 6.45165-6.585011v-3.224992c0-3.653565-2.88125-6.601906-6.45165-6.601906h-4.29014c-.15231 0-.27938.07348-.42899.08472v-38.261071c.14985.01042.27643.08445.42899.08445h4.29014c3.5704 0 6.45165-2.931451 6.45165-6.585023v-3.224986c0-3.653566-2.88125-6.601906-6.45165-6.601906h-4.29014c-.15231 0-.27938.07392-.42899.08446v-7.851429c0-3.653567-2.88123-6.585019-6.45166-6.585021h-11.220281c.309043-.772641.494982-1.609791.494982-2.498929v-4.3900086c0-3.6535651-2.881246-6.601903-6.451662-6.601903h-3.15158c-3.570428 0-6.435167 2.9483379-6.435167 6.601903v4.3900146c0 .889115.16948 1.726301.478507 2.49893h-38.198448c.309083-.772642.495011-1.609792.495011-2.49893v-4.3900146c0-3.6535651-2.881243-6.601903-6.451663-6.601903z" fill="#f7f5cf" stroke="#b3b3b3" stroke-width="2.563805"/><g fill="#b3b3b3" stroke-width="8.546018"><path d="m62.861474 21.661698a27.707285 31.502779 0 0 1 27.143197 25.411422 18.471523 18.901669 0 0 1 15.955909 18.691329 18.471523 18.901669 0 0 1 -18.480472 18.893947h-49.25376a18.471523 18.901669 0 0 1 -18.463973-18.893947 18.471523 18.901669 0 0 1 15.922908-18.708215 27.707285 31.502779 0 0 1 27.176191-25.394536z"/><path d="m38.226348 90.956369a6.1571744 6.3005562 0 0 1 6.154657 6.297979 6.1571744 6.3005562 0 0 1 -6.154657 6.314882 6.1571744 6.3005562 0 0 1 -6.154657-6.314882 6.1571744 6.3005562 0 0 1 6.154657-6.297979z"/><path d="m87.480108 90.956369a6.1571744 6.3005562 0 0 1 6.171159 6.297979 6.1571744 6.3005562 0 0 1 -6.171159 6.314882 6.1571744 6.3005562 0 0 1 -6.154656-6.314882 6.1571744 6.3005562 0 0 1 6.154656-6.297979z"/><path d="m62.861474 97.254348a6.1571744 6.3005562 0 0 1 6.154662 6.314882 6.1571744 6.3005562 0 0 1 -6.154662 6.29797 6.1571744 6.3005562 0 0 1 -6.154651-6.29797 6.1571744 6.3005562 0 0 1 6.154651-6.314882z"/></g></svg>
diff --git a/editor/icons/GizmoDirectionalLight.svg b/editor/icons/GizmoDirectionalLight.svg
index 041a694773..d943be79f0 100644
--- a/editor/icons/GizmoDirectionalLight.svg
+++ b/editor/icons/GizmoDirectionalLight.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m64 4c-4.432 0-8 3.568-8 8v16c0 4.432 3.568 8 8 8s8-3.568 8-8v-16c0-4.432-3.568-8-8-8zm-36.77 15.223c-2.045 0-4.0893.78461-5.6562 2.3516-3.1339 3.1339-3.1339 8.1786 0 11.312l11.312 11.314c3.1339 3.1339 8.1806 3.1339 11.314 0s3.1339-8.1806 0-11.314l-11.314-11.312c-1.5669-1.5669-3.6113-2.3516-5.6562-2.3516zm73.539 0c-2.045 0-4.0893.78461-5.6562 2.3516l-11.314 11.312c-3.1339 3.1339-3.1339 8.1806 0 11.314s8.1806 3.1339 11.314 0l11.312-11.314c3.1339-3.1339 3.1339-8.1786 0-11.312-1.567-1.5669-3.6113-2.3516-5.6562-2.3516zm-36.77 20.777a24 24 0 0 0 -24 24 24 24 0 0 0 24 24 24 24 0 0 0 24-24 24 24 0 0 0 -24-24zm-52 16c-4.432 0-8 3.568-8 8s3.568 8 8 8h16c4.432 0 8-3.568 8-8s-3.568-8-8-8zm88 0c-4.432 0-8 3.568-8 8s3.568 8 8 8h16c4.432 0 8-3.568 8-8s-3.568-8-8-8zm-61.455 25.449c-2.045 0-4.0913.78266-5.6582 2.3496l-11.312 11.314c-3.1339 3.1339-3.1339 8.1786 0 11.312 3.1339 3.1339 8.1786 3.1339 11.312 0l11.314-11.312c3.1339-3.1339 3.1339-8.1806 0-11.314-1.5669-1.5669-3.6113-2.3496-5.6562-2.3496zm50.91 0c-2.045 0-4.0893.78266-5.6562 2.3496-3.1339 3.1339-3.1339 8.1806 0 11.314l11.314 11.312c3.1339 3.1339 8.1786 3.1339 11.312 0s3.1339-8.1786 0-11.312l-11.312-11.314c-1.5669-1.5669-3.6132-2.3496-5.6582-2.3496zm-25.455 10.551c-4.432 0-8 3.568-8 8v16c0 4.432 3.568 8 8 8s8-3.568 8-8v-16c0-4.432-3.568-8-8-8z" fill-opacity=".29412" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".98824" stroke-width="2"/><path d="m64 8c-2.216 0-4 1.784-4 4v16c0 2.216 1.784 4 4 4s4-1.784 4-4v-16c0-2.216-1.784-4-4-4zm-36.77 15.227c-1.0225 0-2.0447.39231-2.8281 1.1758-1.5669 1.5669-1.5669 4.0893 0 5.6562l11.312 11.314c1.5669 1.5669 4.0913 1.5669 5.6582 0s1.5669-4.0913 0-5.6582l-11.314-11.312c-.78348-.78348-1.8056-1.1758-2.8281-1.1758zm73.539 0c-1.0225 0-2.0446.39231-2.8281 1.1758l-11.314 11.312c-1.5669 1.5669-1.5669 4.0913 0 5.6582s4.0913 1.5669 5.6582 0l11.313-11.314c1.5669-1.5669 1.5669-4.0893 0-5.6562-.78348-.78348-1.8056-1.1758-2.8281-1.1758zm-36.77 20.773c-11.046.00001-20 8.9543-20 20 .000007 11.046 8.9543 20 20 20s20-8.9543 20-20c-.000008-11.046-8.9543-20-20-20zm-52 16c-2.216 0-4 1.784-4 4s1.784 4 4 4h16c2.216 0 4-1.784 4-4s-1.784-4-4-4zm88 0c-2.216 0-4 1.784-4 4s1.784 4 4 4h16c2.216 0 4-1.784 4-4s-1.784-4-4-4zm-61.455 25.453c-1.0225 0-2.0466.39035-2.8301 1.1738l-11.312 11.314c-1.5669 1.5669-1.5669 4.0893 0 5.6563 1.5669 1.5669 4.0893 1.5669 5.6562 0l11.314-11.313c1.5669-1.5669 1.5669-4.0913 0-5.6582-.78347-.78347-1.8056-1.1738-2.8281-1.1738zm50.91 0c-1.0225 0-2.0447.39035-2.8281 1.1738-1.5669 1.5669-1.5669 4.0913 0 5.6582l11.314 11.313c1.5669 1.5669 4.0893 1.5669 5.6563 0 1.5669-1.567 1.5669-4.0893 0-5.6563l-11.313-11.314c-.78347-.78347-1.8076-1.1738-2.8301-1.1738zm-25.455 10.547c-2.216 0-4 1.784-4 4v16c0 2.216 1.784 4 4 4s4-1.784 4-4v-16c0-2.216-1.784-4-4-4z" fill="#fefefe"/></svg>
+<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m64 4c-4.432 0-8 3.568-8 8v16c0 4.432 3.568 8 8 8s8-3.568 8-8v-16c0-4.432-3.568-8-8-8zm-36.77 15.223c-2.045 0-4.0893.78461-5.6562 2.3516-3.1339 3.1339-3.1339 8.1786 0 11.312l11.312 11.314c3.1339 3.1339 8.1806 3.1339 11.314 0s3.1339-8.1806 0-11.314l-11.314-11.312c-1.5669-1.5669-3.6113-2.3516-5.6562-2.3516zm73.539 0c-2.045 0-4.0893.78461-5.6562 2.3516l-11.314 11.312c-3.1339 3.1339-3.1339 8.1806 0 11.314s8.1806 3.1339 11.314 0l11.312-11.314c3.1339-3.1339 3.1339-8.1786 0-11.312-1.567-1.5669-3.6113-2.3516-5.6562-2.3516zm-36.77 20.777a24 24 0 0 0 -24 24 24 24 0 0 0 24 24 24 24 0 0 0 24-24 24 24 0 0 0 -24-24zm-52 16c-4.432 0-8 3.568-8 8s3.568 8 8 8h16c4.432 0 8-3.568 8-8s-3.568-8-8-8zm88 0c-4.432 0-8 3.568-8 8s3.568 8 8 8h16c4.432 0 8-3.568 8-8s-3.568-8-8-8zm-61.455 25.449c-2.045 0-4.0913.78266-5.6582 2.3496l-11.312 11.314c-3.1339 3.1339-3.1339 8.1786 0 11.312 3.1339 3.1339 8.1786 3.1339 11.312 0l11.314-11.312c3.1339-3.1339 3.1339-8.1806 0-11.314-1.5669-1.5669-3.6113-2.3496-5.6562-2.3496zm50.91 0c-2.045 0-4.0893.78266-5.6562 2.3496-3.1339 3.1339-3.1339 8.1806 0 11.314l11.314 11.312c3.1339 3.1339 8.1786 3.1339 11.312 0s3.1339-8.1786 0-11.312l-11.312-11.314c-1.5669-1.5669-3.6132-2.3496-5.6582-2.3496zm-25.455 10.551c-4.432 0-8 3.568-8 8v16c0 4.432 3.568 8 8 8s8-3.568 8-8v-16c0-4.432-3.568-8-8-8z" fill-opacity=".29412" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".98824" stroke-width="2"/><path d="m64 8c-2.216 0-4 1.784-4 4v16c0 2.216 1.784 4 4 4s4-1.784 4-4v-16c0-2.216-1.784-4-4-4zm-36.77 15.227c-1.0225 0-2.0447.39231-2.8281 1.1758-1.5669 1.5669-1.5669 4.0893 0 5.6562l11.312 11.314c1.5669 1.5669 4.0913 1.5669 5.6582 0s1.5669-4.0913 0-5.6582l-11.314-11.312c-.78348-.78348-1.8056-1.1758-2.8281-1.1758zm73.539 0c-1.0225 0-2.0446.39231-2.8281 1.1758l-11.314 11.312c-1.5669 1.5669-1.5669 4.0913 0 5.6582s4.0913 1.5669 5.6582 0l11.313-11.314c1.5669-1.5669 1.5669-4.0893 0-5.6562-.78348-.78348-1.8056-1.1758-2.8281-1.1758zm-36.77 20.773c-11.046.00001-20 8.9543-20 20 .000007 11.046 8.9543 20 20 20s20-8.9543 20-20c-.000008-11.046-8.9543-20-20-20zm-52 16c-2.216 0-4 1.784-4 4s1.784 4 4 4h16c2.216 0 4-1.784 4-4s-1.784-4-4-4zm88 0c-2.216 0-4 1.784-4 4s1.784 4 4 4h16c2.216 0 4-1.784 4-4s-1.784-4-4-4zm-61.455 25.453c-1.0225 0-2.0466.39035-2.8301 1.1738l-11.312 11.314c-1.5669 1.5669-1.5669 4.0893 0 5.6563 1.5669 1.5669 4.0893 1.5669 5.6562 0l11.314-11.313c1.5669-1.5669 1.5669-4.0913 0-5.6582-.78347-.78347-1.8056-1.1738-2.8281-1.1738zm50.91 0c-1.0225 0-2.0447.39035-2.8281 1.1738-1.5669 1.5669-1.5669 4.0913 0 5.6582l11.314 11.313c1.5669 1.5669 4.0893 1.5669 5.6563 0 1.5669-1.567 1.5669-4.0893 0-5.6563l-11.313-11.314c-.78347-.78347-1.8076-1.1738-2.8301-1.1738zm-25.455 10.547c-2.216 0-4 1.784-4 4v16c0 2.216 1.784 4 4 4s4-1.784 4-4v-16c0-2.216-1.784-4-4-4z" fill="#ffffff"/></svg>
diff --git a/editor/icons/GizmoLight.svg b/editor/icons/GizmoLight.svg
index ab828c800e..0f74ebbd3d 100644
--- a/editor/icons/GizmoLight.svg
+++ b/editor/icons/GizmoLight.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m64 2a44 44 0 0 0 -44 44 44 44 0 0 0 24 39.189v5.8105 5 3c0 5.0515 3.3756 9.2769 8 10.578v16.422h24v-16.422c4.6244-1.3012 8-5.5266 8-10.578v-3-5-5.8574a44 44 0 0 0 24-39.143 44 44 0 0 0 -44-44zm0 20a24 24 0 0 1 24 24 24 24 0 0 1 -24 24 24 24 0 0 1 -24-24 24 24 0 0 1 24-24z" fill-opacity=".29412" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".98824" stroke-width="2.2"/><path d="m64 6a40 40 0 0 0 -40 40 40 40 0 0 0 24 36.607v15.393a8 8 0 0 0 8 8h16a8 8 0 0 0 8-8v-15.363a40 40 0 0 0 24-36.637 40 40 0 0 0 -40-40zm0 12a28 28 0 0 1 28 28 28 28 0 0 1 -28 28 28 28 0 0 1 -28-28 28 28 0 0 1 28-28zm-8 96v8h16v-8z" fill="#fefefe"/></svg>
+<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m64 2a44 44 0 0 0 -44 44 44 44 0 0 0 24 39.189v5.8105 5 3c0 5.0515 3.3756 9.2769 8 10.578v16.422h24v-16.422c4.6244-1.3012 8-5.5266 8-10.578v-3-5-5.8574a44 44 0 0 0 24-39.143 44 44 0 0 0 -44-44zm0 20a24 24 0 0 1 24 24 24 24 0 0 1 -24 24 24 24 0 0 1 -24-24 24 24 0 0 1 24-24z" fill-opacity=".29412" stroke-linecap="round" stroke-linejoin="round" stroke-opacity=".98824" stroke-width="2.2"/><path d="m64 6a40 40 0 0 0 -40 40 40 40 0 0 0 24 36.607v15.393a8 8 0 0 0 8 8h16a8 8 0 0 0 8-8v-15.363a40 40 0 0 0 24-36.637 40 40 0 0 0 -40-40zm0 12a28 28 0 0 1 28 28 28 28 0 0 1 -28 28 28 28 0 0 1 -28-28 28 28 0 0 1 28-28zm-8 96v8h16v-8z" fill="#ffffff"/></svg>
diff --git a/editor/icons/GizmoSpotLight.svg b/editor/icons/GizmoSpotLight.svg
index 18696c2cdc..d1a576ce22 100644
--- a/editor/icons/GizmoSpotLight.svg
+++ b/editor/icons/GizmoSpotLight.svg
@@ -1 +1 @@
-<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m52 4c-6.5788 0-12 5.4212-12 12v26.625c-12.263 7.2822-19.978 19.75-20 33.369l-.005859 4.0059h28.578c1.7994 6.8632 8.0265 12 15.428 12s13.628-5.1368 15.428-12h28.576l-.00391-4.0039c-.01526-13.625-7.7323-26.099-20-33.385v-26.611c0-6.5788-5.4212-12-12-12zm-11.689 78.016c-1.536-.10738-3.1419.23676-4.5586 1.0547l-10.393 6c-3.7786 2.1816-5.1117 7.1503-2.9297 10.93 2.1816 3.7786 7.1503 5.1117 10.93 2.9297l10.393-6c3.7796-2.1822 5.1087-7.1521 2.9277-10.93-1.3629-2.3605-3.8057-3.8052-6.3691-3.9844zm47.379 0c-2.5634.1792-5.0063 1.6238-6.3691 3.9844-2.181 3.7776-.85187 8.7475 2.9277 10.93l10.393 6c3.7794 2.182 8.7481.8489 10.93-2.9297 2.182-3.7794.84891-8.7481-2.9297-10.93l-10.393-6c-1.4167-.81792-3.0225-1.1621-4.5586-1.0547zm-23.689 13.984c-4.3628 0-8 3.6372-8 8v12c0 4.3628 3.6372 8 8 8s8-3.6372 8-8v-12c0-4.3628-3.6372-8-8-8z" fill-opacity=".29412"/><path d="m52 8c-4.432 0-8 3.568-8 8v12 16.875a40 36 0 0 0 -20 31.125h28a12 12 0 0 0 12 12 12 12 0 0 0 12-12h28a40 36 0 0 0 -20-31.141v-20.859-8c0-4.432-3.568-8-8-8zm-11.969 78.006c-.76793-.053681-1.5596.1138-2.2793.5293l-10.393 6c-1.9191 1.108-2.5728 3.5457-1.4648 5.4648s3.5457 2.5728 5.4648 1.4648l10.393-6c1.9191-1.108 2.5709-3.5457 1.4629-5.4648-.6925-1.1994-1.9037-1.9047-3.1836-1.9941zm47.938 0c-1.2799.08947-2.4911.7947-3.1836 1.9941-1.108 1.9191-.45622 4.3568 1.4629 5.4648l10.393 6c1.9191 1.108 4.3568.45427 5.4648-1.4648s.45427-4.3568-1.4648-5.4648l-10.393-6c-.71967-.4155-1.5114-.58298-2.2793-.5293zm-23.969 13.994c-2.216 0-4 1.784-4 4v12c0 2.216 1.784 4 4 4s4-1.784 4-4v-12c0-2.216-1.784-4-4-4z" fill="#fefefe" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.1082"/></svg>
+<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="m52 4c-6.5788 0-12 5.4212-12 12v26.625c-12.263 7.2822-19.978 19.75-20 33.369l-.005859 4.0059h28.578c1.7994 6.8632 8.0265 12 15.428 12s13.628-5.1368 15.428-12h28.576l-.00391-4.0039c-.01526-13.625-7.7323-26.099-20-33.385v-26.611c0-6.5788-5.4212-12-12-12zm-11.689 78.016c-1.536-.10738-3.1419.23676-4.5586 1.0547l-10.393 6c-3.7786 2.1816-5.1117 7.1503-2.9297 10.93 2.1816 3.7786 7.1503 5.1117 10.93 2.9297l10.393-6c3.7796-2.1822 5.1087-7.1521 2.9277-10.93-1.3629-2.3605-3.8057-3.8052-6.3691-3.9844zm47.379 0c-2.5634.1792-5.0063 1.6238-6.3691 3.9844-2.181 3.7776-.85187 8.7475 2.9277 10.93l10.393 6c3.7794 2.182 8.7481.8489 10.93-2.9297 2.182-3.7794.84891-8.7481-2.9297-10.93l-10.393-6c-1.4167-.81792-3.0225-1.1621-4.5586-1.0547zm-23.689 13.984c-4.3628 0-8 3.6372-8 8v12c0 4.3628 3.6372 8 8 8s8-3.6372 8-8v-12c0-4.3628-3.6372-8-8-8z" fill-opacity=".29412"/><path d="m52 8c-4.432 0-8 3.568-8 8v12 16.875a40 36 0 0 0 -20 31.125h28a12 12 0 0 0 12 12 12 12 0 0 0 12-12h28a40 36 0 0 0 -20-31.141v-20.859-8c0-4.432-3.568-8-8-8zm-11.969 78.006c-.76793-.053681-1.5596.1138-2.2793.5293l-10.393 6c-1.9191 1.108-2.5728 3.5457-1.4648 5.4648s3.5457 2.5728 5.4648 1.4648l10.393-6c1.9191-1.108 2.5709-3.5457 1.4629-5.4648-.6925-1.1994-1.9037-1.9047-3.1836-1.9941zm47.938 0c-1.2799.08947-2.4911.7947-3.1836 1.9941-1.108 1.9191-.45622 4.3568 1.4629 5.4648l10.393 6c1.9191 1.108 4.3568.45427 5.4648-1.4648s.45427-4.3568-1.4648-5.4648l-10.393-6c-.71967-.4155-1.5114-.58298-2.2793-.5293zm-23.969 13.994c-2.216 0-4 1.784-4 4v12c0 2.216 1.784 4 4 4s4-1.784 4-4v-12c0-2.216-1.784-4-4-4z" fill="#ffffff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.1082"/></svg>
diff --git a/editor/icons/GraphEdit.svg b/editor/icons/GraphEdit.svg
index fbe7422f98..071c191532 100644
--- a/editor/icons/GraphEdit.svg
+++ b/editor/icons/GraphEdit.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -1-1.7305v-5.8555l4.793 4.793 1.4141-1.4141-4.793-4.793h5.8574a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm10.656 6.9297-.70703.70703 1.4141 1.4141.70703-.70703zm-1.4141 1.4141-3.8887 3.8887-.35352 1.7676 1.7676-.35352 3.8887-3.8887-1.4141-1.4141z" fill="#8eef97" transform="translate(0 1036.4)"/><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -1-1.7305v-5.8555l4.793 4.793 1.4141-1.4141-4.793-4.793h5.8574a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm10.656 6.9297-.70703.70703 1.4141 1.4141.70703-.70703zm-1.4141 1.4141-3.8887 3.8887-.35352 1.7676 1.7676-.35352 3.8887-3.8887-1.4141-1.4141z" fill="#8eef97" transform="translate(0 1036.4)"/></g></svg>
diff --git a/editor/icons/GraphNode.svg b/editor/icons/GraphNode.svg
index 061a81d951..b56fe6b609 100644
--- a/editor/icons/GraphNode.svg
+++ b/editor/icons/GraphNode.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -1-1.7305v-5.8555l4.0859 4.0859 1.4141-1.4141-4.0859-4.0859h5.8574a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm9.5 9a2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5 2.5 2.5 0 0 0 -2.5-2.5z" fill="#8eef97" transform="translate(0 1036.4)"/><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -1-1.7305v-5.8555l4.0859 4.0859 1.4141-1.4141-4.0859-4.0859h5.8574a2 2 0 0 0 1.7285 1 2 2 0 0 0 2-2 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm9.5 9a2.5 2.5 0 0 0 -2.5 2.5 2.5 2.5 0 0 0 2.5 2.5 2.5 2.5 0 0 0 2.5-2.5 2.5 2.5 0 0 0 -2.5-2.5z" fill="#8eef97" transform="translate(0 1036.4)"/></g></svg>
diff --git a/editor/icons/GuiDropdown.svg b/editor/icons/GuiDropdown.svg
index ef37cda6ff..9b9abe5b49 100644
--- a/editor/icons/GuiDropdown.svg
+++ b/editor/icons/GuiDropdown.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m4 1045.4 3 3 3-3" style="fill:none;stroke:#fff;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:.58824;stroke-width:2" transform="translate(0 -1038.4)"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg"><path d="m4 7 3 3 3-3" fill="none" stroke="#fff" stroke-opacity=".59" stroke-width="2"/></svg>
diff --git a/editor/icons/GuiScrollGrabber.svg b/editor/icons/GuiScrollGrabber.svg
index 935f9361dd..a8a0cf08c2 100644
--- a/editor/icons/GuiScrollGrabber.svg
+++ b/editor/icons/GuiScrollGrabber.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 11.999999" width="12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#fff" fill-opacity=".294118" r="3"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#fff" fill-opacity=".29" r="3"/></svg>
diff --git a/editor/icons/GuiScrollGrabberHl.svg b/editor/icons/GuiScrollGrabberHl.svg
index cec53330f0..0388063d25 100644
--- a/editor/icons/GuiScrollGrabberHl.svg
+++ b/editor/icons/GuiScrollGrabberHl.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 11.999999" width="12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#f9f9f9" fill-opacity=".73" r="3"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#f9f9f9" fill-opacity=".73" r="3"/></svg>
diff --git a/editor/icons/GuiScrollGrabberPressed.svg b/editor/icons/GuiScrollGrabberPressed.svg
index 13f8427d35..202b9c9412 100644
--- a/editor/icons/GuiScrollGrabberPressed.svg
+++ b/editor/icons/GuiScrollGrabberPressed.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 11.999999" width="12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#afafaf" fill-opacity=".72941" r="3"/></svg>
+<svg height="12" viewBox="0 0 12 11.999999" width="12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#b3b3b3" fill-opacity=".72941" r="3"/></svg>
diff --git a/editor/icons/GuiSliderGrabber.svg b/editor/icons/GuiSliderGrabber.svg
index ddd1b1d9b8..47342747bf 100644
--- a/editor/icons/GuiSliderGrabber.svg
+++ b/editor/icons/GuiSliderGrabber.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 15.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm0 2a5 5 0 0 1 .5.025391 5 5 0 0 1 .49414.074219 5 5 0 0 1 .48438.12305 5 5 0 0 1 .46875.17188 5 5 0 0 1 .44922.2168 5 5 0 0 1 .42578.26172 5 5 0 0 1 .39844.30273 5 5 0 0 1 .36524.33984 5 5 0 0 1 .33008.37695 5 5 0 0 1 .29102.40625 5 5 0 0 1 .24805.43359 5 5 0 0 1 .20508.45508 5 5 0 0 1 .1582.47461 5 5 0 0 1 .10938.48828 5 5 0 0 1 .060547.49609 5 5 0 0 1 .011719.35352 5 5 0 0 1 -.025391.5 5 5 0 0 1 -.074218.49414 5 5 0 0 1 -.12305.48438 5 5 0 0 1 -.17188.46875 5 5 0 0 1 -.2168.44922 5 5 0 0 1 -.26172.42578 5 5 0 0 1 -.30273.39844 5 5 0 0 1 -.33984.36524 5 5 0 0 1 -.37695.33008 5 5 0 0 1 -.40625.29102 5 5 0 0 1 -.43359.24805 5 5 0 0 1 -.45508.20508 5 5 0 0 1 -.47461.1582 5 5 0 0 1 -.48828.10938 5 5 0 0 1 -.49609.060547 5 5 0 0 1 -.35352.011719 5 5 0 0 1 -.5-.025391 5 5 0 0 1 -.49414-.074218 5 5 0 0 1 -.48438-.12305 5 5 0 0 1 -.46875-.17188 5 5 0 0 1 -.44922-.2168 5 5 0 0 1 -.42578-.26172 5 5 0 0 1 -.39844-.30273 5 5 0 0 1 -.36523-.33984 5 5 0 0 1 -.33008-.37695 5 5 0 0 1 -.29102-.40625 5 5 0 0 1 -.24805-.43359 5 5 0 0 1 -.20508-.45508 5 5 0 0 1 -.1582-.47461 5 5 0 0 1 -.10938-.48828 5 5 0 0 1 -.060547-.49609 5 5 0 0 1 -.011719-.35352 5 5 0 0 1 .025391-.5 5 5 0 0 1 .074219-.49414 5 5 0 0 1 .12305-.48438 5 5 0 0 1 .17188-.46875 5 5 0 0 1 .2168-.44922 5 5 0 0 1 .26172-.42578 5 5 0 0 1 .30273-.39844 5 5 0 0 1 .33984-.36523 5 5 0 0 1 .37695-.33008 5 5 0 0 1 .40625-.29102 5 5 0 0 1 .43359-.24805 5 5 0 0 1 .45508-.20508 5 5 0 0 1 .47461-.1582 5 5 0 0 1 .48828-.10938 5 5 0 0 1 .49609-.060547 5 5 0 0 1 .35352-.011719z" fill="#e0e0e0" fill-opacity=".289256" transform="translate(0 1036.4)"/><circle cx="8" cy="1044.4" r="3" style="fill:#fff;fill-opacity:.58824;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:.32549;stroke-width:3"/></g><circle cx="7.932204" cy="8" fill="#fff" fill-opacity=".78431" r="3" stroke-linejoin="round" stroke-opacity=".39216" stroke-width="3"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.84 0-7 3.16-7 7s3.16 7 7 7 7-3.16 7-7-3.16-7-7-7zm0 2c.167 0 .334.009.5.025.166.017.331.042.494.075.164.033.325.074.485.123.159.049.315.106.468.172.154.064.303.137.449.216.147.08.289.168.426.262.138.094.271.195.399.303.127.107.249.22.365.34s.226.245.33.377c.104.13.201.266.291.406s.173.285.248.433c.076.149.144.3.205.455.061.156.114.314.158.475.045.161.081.324.11.488.028.165.048.33.06.496.008.118.012.236.012.354 0 .167-.009.334-.025.5-.017.166-.042.331-.075.494-.032.164-.074.325-.123.485-.049.159-.106.315-.172.468-.064.154-.137.303-.216.449-.08.147-.168.289-.262.426-.094.138-.195.271-.303.399-.107.127-.22.249-.34.365s-.245.226-.377.33c-.13.104-.266.201-.406.291s-.285.173-.433.248c-.149.076-.3.144-.455.205-.156.061-.314.114-.475.158-.161.045-.324.081-.488.11-.165.028-.33.048-.496.06-.118.008-.236.012-.354.012-.167 0-.334-.009-.5-.025-.166-.017-.331-.042-.494-.075-.164-.032-.325-.074-.484-.123-.16-.049-.316-.106-.469-.172-.153-.064-.303-.137-.449-.216-.147-.08-.289-.168-.426-.262-.138-.094-.271-.195-.399-.303-.127-.107-.249-.22-.365-.34s-.226-.245-.33-.377c-.104-.13-.201-.266-.291-.406s-.173-.285-.248-.433c-.076-.149-.144-.3-.205-.455-.061-.156-.114-.314-.158-.475-.045-.161-.081-.324-.11-.488-.028-.165-.048-.33-.06-.496-.008-.118-.012-.236-.012-.354 0-.167.009-.334.025-.5.017-.166.042-.331.075-.494.033-.164.074-.325.123-.484.049-.16.106-.316.172-.469.064-.153.137-.303.216-.449.08-.147.168-.289.262-.426.094-.138.195-.271.303-.399.107-.127.22-.249.34-.365s.246-.226.377-.33c.13-.104.266-.201.406-.291s.285-.173.433-.248c.149-.076.3-.144.456-.205.155-.061.313-.114.474-.158.161-.045.324-.081.488-.11.165-.028.33-.048.496-.06.118-.008.236-.012.354-.012z" fill="#e0e0e0" fill-opacity=".29" fill-rule="nonzero"/><g fill="#fff"><circle cx="8" cy="8" fill-opacity=".59" r="3"/><circle cx="7.932" cy="8" fill-opacity=".78" r="3"/></g></svg>
diff --git a/editor/icons/GuiSliderGrabberHl.svg b/editor/icons/GuiSliderGrabberHl.svg
index 3af977ae4a..b7be27af0f 100644
--- a/editor/icons/GuiSliderGrabberHl.svg
+++ b/editor/icons/GuiSliderGrabberHl.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 15.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm0 2a5 5 0 0 1 .5.025391 5 5 0 0 1 .49414.074219 5 5 0 0 1 .48438.12305 5 5 0 0 1 .46875.17188 5 5 0 0 1 .44922.2168 5 5 0 0 1 .42578.26172 5 5 0 0 1 .39844.30273 5 5 0 0 1 .36524.33984 5 5 0 0 1 .33008.37695 5 5 0 0 1 .29102.40625 5 5 0 0 1 .24805.43359 5 5 0 0 1 .20508.45508 5 5 0 0 1 .1582.47461 5 5 0 0 1 .10938.48828 5 5 0 0 1 .060547.49609 5 5 0 0 1 .011719.35352 5 5 0 0 1 -.025391.5 5 5 0 0 1 -.074218.49414 5 5 0 0 1 -.12305.48438 5 5 0 0 1 -.17188.46875 5 5 0 0 1 -.2168.44922 5 5 0 0 1 -.26172.42578 5 5 0 0 1 -.30273.39844 5 5 0 0 1 -.33984.36524 5 5 0 0 1 -.37695.33008 5 5 0 0 1 -.40625.29102 5 5 0 0 1 -.43359.24805 5 5 0 0 1 -.45508.20508 5 5 0 0 1 -.47461.1582 5 5 0 0 1 -.48828.10938 5 5 0 0 1 -.49609.060547 5 5 0 0 1 -.35352.011719 5 5 0 0 1 -.5-.025391 5 5 0 0 1 -.49414-.074218 5 5 0 0 1 -.48438-.12305 5 5 0 0 1 -.46875-.17188 5 5 0 0 1 -.44922-.2168 5 5 0 0 1 -.42578-.26172 5 5 0 0 1 -.39844-.30273 5 5 0 0 1 -.36523-.33984 5 5 0 0 1 -.33008-.37695 5 5 0 0 1 -.29102-.40625 5 5 0 0 1 -.24805-.43359 5 5 0 0 1 -.20508-.45508 5 5 0 0 1 -.1582-.47461 5 5 0 0 1 -.10938-.48828 5 5 0 0 1 -.060547-.49609 5 5 0 0 1 -.011719-.35352 5 5 0 0 1 .025391-.5 5 5 0 0 1 .074219-.49414 5 5 0 0 1 .12305-.48438 5 5 0 0 1 .17188-.46875 5 5 0 0 1 .2168-.44922 5 5 0 0 1 .26172-.42578 5 5 0 0 1 .30273-.39844 5 5 0 0 1 .33984-.36523 5 5 0 0 1 .37695-.33008 5 5 0 0 1 .40625-.29102 5 5 0 0 1 .43359-.24805 5 5 0 0 1 .45508-.20508 5 5 0 0 1 .47461-.1582 5 5 0 0 1 .48828-.10938 5 5 0 0 1 .49609-.060547 5 5 0 0 1 .35352-.011719z" fill="#e0e0e0" transform="translate(0 1036.4)"/><circle cx="8" cy="1044.4" r="3" style="fill:#fff;fill-opacity:.58824;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:.32549;stroke-width:3"/></g><circle cx="7.932204" cy="8" fill="#fff" fill-opacity=".78431" r="3" stroke-linejoin="round" stroke-opacity=".39216" stroke-width="3"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.84 0-7 3.16-7 7s3.16 7 7 7 7-3.16 7-7-3.16-7-7-7zm0 2c.167 0 .334.009.5.025.166.017.331.042.494.075.164.033.325.074.485.123.159.049.315.106.468.172.154.064.303.137.449.216.147.08.289.168.426.262.138.094.271.195.399.303.127.107.249.22.365.34s.226.245.33.377c.104.13.201.266.291.406s.173.285.248.433c.076.149.144.3.205.455.061.156.114.314.158.475.045.161.081.324.11.488.028.165.048.33.06.496.008.118.012.236.012.354 0 .167-.009.334-.025.5-.017.166-.042.331-.075.494-.032.164-.074.325-.123.485-.049.159-.106.315-.172.468-.064.154-.137.303-.216.449-.08.147-.168.289-.262.426-.094.138-.195.271-.303.399-.107.127-.22.249-.34.365s-.245.226-.377.33c-.13.104-.266.201-.406.291s-.285.173-.433.248c-.149.076-.3.144-.455.205-.156.061-.314.114-.475.158-.161.045-.324.081-.488.11-.165.028-.33.048-.496.06-.118.008-.236.012-.354.012-.167 0-.334-.009-.5-.025-.166-.017-.331-.042-.494-.075-.164-.032-.325-.074-.484-.123-.16-.049-.316-.106-.469-.172-.153-.064-.303-.137-.449-.216-.147-.08-.289-.168-.426-.262-.138-.094-.271-.195-.399-.303-.127-.107-.249-.22-.365-.34s-.226-.245-.33-.377c-.104-.13-.201-.266-.291-.406s-.173-.285-.248-.433c-.076-.149-.144-.3-.205-.455-.061-.156-.114-.314-.158-.475-.045-.161-.081-.324-.11-.488-.028-.165-.048-.33-.06-.496-.008-.118-.012-.236-.012-.354 0-.167.009-.334.025-.5.017-.166.042-.331.075-.494.033-.164.074-.325.123-.484.049-.16.106-.316.172-.469.064-.153.137-.303.216-.449.08-.147.168-.289.262-.426.094-.138.195-.271.303-.399.107-.127.22-.249.34-.365s.246-.226.377-.33c.13-.104.266-.201.406-.291s.285-.173.433-.248c.149-.076.3-.144.456-.205.155-.061.313-.114.474-.158.161-.045.324-.081.488-.11.165-.028.33-.048.496-.06.118-.008.236-.012.354-.012z" fill="#e0e0e0" fill-rule="nonzero"/><g fill="#fff"><circle cx="8" cy="8" fill-opacity=".59" r="3"/><circle cx="7.932" cy="8" fill-opacity=".78" r="3"/></g></svg>
diff --git a/editor/icons/GuiToggleOn.svg b/editor/icons/GuiToggleOn.svg
index 37b47e8de4..0e20128730 100644
--- a/editor/icons/GuiToggleOn.svg
+++ b/editor/icons/GuiToggleOn.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 38 15.999999" width="38" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-4 0-7 3.0000002-7 7.0000002 0 3.9999998 3 6.9999998 7 6.9999998h22c4 0 7-3 7-6.9999998 0-4-3-7.0000002-7-7.0000002-7.333334 0-14.55609 0-22 0z" fill="#699ce8"/><circle cx="30" cy="8" fill="#fefefe" r="5"/></svg>
+<svg height="16" viewBox="0 0 38 15.999999" width="38" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-4 0-7 3.0000002-7 7.0000002 0 3.9999998 3 6.9999998 7 6.9999998h22c4 0 7-3 7-6.9999998 0-4-3-7.0000002-7-7.0000002-7.333334 0-14.55609 0-22 0z" fill="#699ce8"/><circle cx="30" cy="8" fill="#ffffff" r="5"/></svg>
diff --git a/editor/icons/GuiToggleOnMirrored.svg b/editor/icons/GuiToggleOnMirrored.svg
index fa7f602ee7..affbb5c7a8 100644
--- a/editor/icons/GuiToggleOnMirrored.svg
+++ b/editor/icons/GuiToggleOnMirrored.svg
@@ -1 +1 @@
-<svg height="26" width="42" xmlns="http://www.w3.org/2000/svg"><path d="m31 5c4.986 0 9 3.568 9 8s-4.014 8-9 8h-20c-4.986 0-9-3.568-9-8s4.014-8 9-8z" fill="#699ce8"/><circle cx="10" cy="13" fill="#fefefe" r="5"/></svg>
+<svg height="26" width="42" xmlns="http://www.w3.org/2000/svg"><path d="m31 5c4.986 0 9 3.568 9 8s-4.014 8-9 8h-20c-4.986 0-9-3.568-9-8s4.014-8 9-8z" fill="#699ce8"/><circle cx="10" cy="13" fill="#ffffff" r="5"/></svg>
diff --git a/editor/icons/GuiTreeArrowDown.svg b/editor/icons/GuiTreeArrowDown.svg
index 7b320152ff..ad8a625f18 100644
--- a/editor/icons/GuiTreeArrowDown.svg
+++ b/editor/icons/GuiTreeArrowDown.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m3 1045.4 3 3 3-3" style="fill:none;stroke:#fff;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:.39216;stroke-width:2" transform="translate(0 -1040.4)"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><path d="m3 5 3 3 3-3" fill="none" stroke="#fff" stroke-opacity=".39" stroke-width="2"/></svg>
diff --git a/editor/icons/GuiTreeArrowLeft.svg b/editor/icons/GuiTreeArrowLeft.svg
index d0f7b36fab..2cc20c8459 100644
--- a/editor/icons/GuiTreeArrowLeft.svg
+++ b/editor/icons/GuiTreeArrowLeft.svg
@@ -1 +1 @@
-<svg height="12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m7 9-3-3 3-3" style="fill:none;stroke:#fff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:.392"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><path d="m7 9-3-3 3-3" fill="none" stroke="#fff" stroke-opacity=".39" stroke-width="2"/></svg>
diff --git a/editor/icons/GuiTreeArrowRight.svg b/editor/icons/GuiTreeArrowRight.svg
index cf1b5dac7c..14314bb365 100644
--- a/editor/icons/GuiTreeArrowRight.svg
+++ b/editor/icons/GuiTreeArrowRight.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 12" width="12" xmlns="http://www.w3.org/2000/svg"><path d="m4 1049.4 3-3-3-3" style="fill:none;stroke:#fff;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:.39216;stroke-width:2" transform="translate(0 -1040.4)"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><path d="m4 9 3-3-3-3" fill="none" stroke="#fff" stroke-opacity=".39" stroke-width="2"/></svg>
diff --git a/editor/icons/GuiTreeUpdown.svg b/editor/icons/GuiTreeUpdown.svg
index c6b9014e82..feff99f618 100644
--- a/editor/icons/GuiTreeUpdown.svg
+++ b/editor/icons/GuiTreeUpdown.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m6.9844 1.002a1.0001 1.0001 0 0 0 -.69141.29102l-3 3a1 1 0 0 0 0 1.4141 1 1 0 0 0 1.4141 0l2.293-2.293 2.293 2.293a1 1 0 0 0 1.4141 0 1 1 0 0 0 0-1.4141l-3-3a1.0001 1.0001 0 0 0 -.72266-.29102zm3 6.998a1 1 0 0 0 -.69141.29297l-2.293 2.293-2.293-2.293a1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l3 3a1.0001 1.0001 0 0 0 1.4141 0l3-3a1 1 0 0 0 0-1.4141 1 1 0 0 0 -.72266-.29297z" fill="#fff" fill-opacity=".58824"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg"><path d="m6.984 1.002c-.259.004-.507.108-.691.291l-3 3c-.388.388-.388 1.026 0 1.414s1.026.388 1.414 0l2.293-2.293 2.293 2.293c.388.388 1.026.388 1.414 0s.388-1.026 0-1.414l-3-3c-.191-.191-.452-.296-.722-.291zm3 6.998c-.259.004-.507.109-.691.293l-2.293 2.293-2.293-2.293c-.191-.19-.451-.295-.721-.291-.26.003-.509.108-.693.291-.388.388-.388 1.026 0 1.414l3 3c.388.388 1.026.388 1.414 0l3-3c.388-.388.388-1.026 0-1.414-.191-.191-.452-.297-.723-.293z" fill="#fff" fill-opacity=".59" fill-rule="nonzero"/></svg>
diff --git a/editor/icons/HFlowContainer.svg b/editor/icons/HFlowContainer.svg
index 0ab03f686e..dedf6e54f2 100644
--- a/editor/icons/HFlowContainer.svg
+++ b/editor/icons/HFlowContainer.svg
@@ -1 +1 @@
-<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2H3zm0 2h10v10H3V3zm2 1c-.554 0-1 .446-1 1s.446 1 1 1h2c.554 0 1-.446 1-1s-.446-1-1-1H5zm4.996 0c-.554 0-1 .446-1 1s.446 1 1 1H11c.554 0 1-.446 1-1s-.446-1-1-1H9.996zM5 7c-.554 0-1 .446-1 1s.446 1 1 1 1-.446 1-1-.446-1-1-1zm3 0c-.554 0-1 .446-1 1s.446 1 1 1h3c.554 0 1-.446 1-1s-.446-1-1-1H8zm-3.004 3c-.554 0-1 .446-1 1s.446 1 1 1H9c.554 0 1-.446 1-1s-.446-1-1-1H4.996z" style="fill:#8eef97;fill-opacity:1"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.097 0-2 .903-2 2v10c0 1.097.903 2 2 2h10c1.097 0 2-.903 2-2v-10c0-1.097-.903-2-2-2zm0 2h10v10h-10zm2 1c-.554 0-1 .446-1 1s.446 1 1 1h2c.554 0 1-.446 1-1s-.446-1-1-1zm4.996 0c-.554 0-1 .446-1 1s.446 1 1 1h1.004c.554 0 1-.446 1-1s-.446-1-1-1zm-4.996 3c-.554 0-1 .446-1 1s.446 1 1 1 1-.446 1-1-.446-1-1-1zm3 0c-.554 0-1 .446-1 1s.446 1 1 1h3c.554 0 1-.446 1-1s-.446-1-1-1zm-3.004 3c-.554 0-1 .446-1 1s.446 1 1 1h4.004c.554 0 1-.446 1-1s-.446-1-1-1z" fill="#8eef97" fill-rule="nonzero"/></svg>
diff --git a/editor/icons/Heart.svg b/editor/icons/Heart.svg
index 4f46908760..00edf90729 100644
--- a/editor/icons/Heart.svg
+++ b/editor/icons/Heart.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 14c-.1249999 0-.25-.046875-.34375-.140625l-4.875-4.703125c-.0625-.054687-1.7812496-1.6249999-1.7812496-3.5 0-2.2890626 1.3984372-3.6562499 3.7343748-3.6562499 1.3671873 0 2.6484373 1.390625 3.2656248 1.9999999.6171875-.6093749 1.8984375-1.9999999 3.265625-1.9999999 2.335938 0 3.734375 1.3671873 3.734375 3.6562499 0 1.8750001-1.71875 3.4453125-1.789062 3.5156251l-4.867188 4.6874999c-.09375.09375-.2187499.140625-.34375.140625z" fill="#ff7070"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 14c-.1249999 0-.25-.046875-.34375-.140625l-4.875-4.703125c-.0625-.054687-1.7812496-1.6249999-1.7812496-3.5 0-2.2890626 1.3984372-3.6562499 3.7343748-3.6562499 1.3671873 0 2.6484373 1.390625 3.2656248 1.9999999.6171875-.6093749 1.8984375-1.9999999 3.265625-1.9999999 2.335938 0 3.734375 1.3671873 3.734375 3.6562499 0 1.8750001-1.71875 3.4453125-1.789062 3.5156251l-4.867188 4.6874999c-.09375.09375-.2187499.140625-.34375.140625z" fill="#fc7f7f"/></svg>
diff --git a/editor/icons/HeightMapShape3D.svg b/editor/icons/HeightMapShape3D.svg
index 0ffff96850..e1b3af88e5 100644
--- a/editor/icons/HeightMapShape3D.svg
+++ b/editor/icons/HeightMapShape3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="8" y2="11"><stop offset="0" stop-color="#68b6ff"/><stop offset="1" stop-color="#a2d2ff"/></linearGradient><g transform="translate(0 -1)"><path d="m1 1044.4 7 3 7-3-7-3z" fill="#a2d2ff" fill-rule="evenodd" transform="translate(0 -1033.4)"/><path d="m3 11c1-1 2-2 2-4s1-3 3-3 3 1 3 3 1 3 2 4z" fill="url(#a)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="8" y2="11"><stop offset="0" stop-color="#5fb2ff"/><stop offset="1" stop-color="#a2d2ff"/></linearGradient><g transform="translate(0 -1)"><path d="m1 1044.4 7 3 7-3-7-3z" fill="#a2d2ff" fill-rule="evenodd" transform="translate(0 -1033.4)"/><path d="m3 11c1-1 2-2 2-4s1-3 3-3 3 1 3 3 1 3 2 4z" fill="url(#a)"/></g></svg>
diff --git a/editor/icons/Help.svg b/editor/icons/Help.svg
index 65f3100164..ace4e79bf3 100644
--- a/editor/icons/Help.svg
+++ b/editor/icons/Help.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5.0293 1c-.99969-.010925-2.0096.31165-3.0293 1v7c2.0172-1.3529 4.0167-1.3136 6 0 1.9833-1.3136 3.9828-1.3529 6 0v-7c-1.0197-.68835-2.0296-1.0109-3.0293-1-.6613.007227-1.3175.1735-1.9707.46289v4.5371h-1v-4c-.98156-.64465-1.971-.98908-2.9707-1zm-5.0293 9v6h2a3 3 0 0 0 3-3 3 3 0 0 0 -3-3zm5 3a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0 -3-3 3 3 0 0 0 -3 3zm6 0a3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2h-1a3 3 0 0 0 -3 3zm-9-1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1-1 1 1 0 0 1 1-1z" style="fill:#e0e0e0;fill-opacity:.58824;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:.32549;stroke-width:2"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m5.029 1c-.999-.011-2.009.312-3.029 1v7c2.017-1.353 4.017-1.314 6 0 1.983-1.314 3.983-1.353 6 0v-7c-1.02-.688-2.03-1.011-3.029-1-.662.007-1.318.173-1.971.463v4.537h-1v-4c-.982-.645-1.971-.989-2.971-1zm-5.029 9v6h2c1.646 0 3-1.354 3-3s-1.354-3-3-3zm5 3c0 1.646 1.354 3 3 3s3-1.354 3-3-1.354-3-3-3-3 1.354-3 3zm6 0c0 1.646 1.354 3 3 3h1v-2h-1c-.549 0-1-.451-1-1s.451-1 1-1h1v-2h-1c-1.646 0-3 1.354-3 3zm-9-1c.549 0 1 .451 1 1s-.451 1-1 1zm6 0c.549 0 1 .451 1 1s-.451 1-1 1-1-.451-1-1 .451-1 1-1z" fill="#e0e0e0" fill-opacity=".59" fill-rule="nonzero"/></svg>
diff --git a/editor/icons/ImmediateMesh.svg b/editor/icons/ImmediateMesh.svg
index 9521530876..f94ef8c323 100644
--- a/editor/icons/ImmediateMesh.svg
+++ b/editor/icons/ImmediateMesh.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 2v2h5v-2zm5 2v3h2v-3zm2-2v2h5v-2zm-2 7v3h2v-3zm-5 3v2h5v-2zm7 0v2h5v-2z" fill="#ffca5f" transform="scale(.93749994)"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m2 2v2h5v-2zm5 2v3h2v-3zm2-2v2h5v-2zm-2 7v3h2v-3zm-5 3v2h5v-2zm7 0v2h5v-2z" fill="#ffca5f" fill-rule="nonzero"/></svg>
diff --git a/editor/icons/ImportCheck.svg b/editor/icons/ImportCheck.svg
index 0e6b0a7105..d17506afea 100644
--- a/editor/icons/ImportCheck.svg
+++ b/editor/icons/ImportCheck.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1044.4 4 4 8-8" fill="none" stroke="#45ff8b" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1044.4 4 4 8-8" fill="none" stroke="#5fff97" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"/></svg>
diff --git a/editor/icons/ImportFail.svg b/editor/icons/ImportFail.svg
index 6e34dfc405..582b244614 100644
--- a/editor/icons/ImportFail.svg
+++ b/editor/icons/ImportFail.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2.9902 1.9902a1.0001 1.0001 0 0 0 -.69727 1.7168l4.293 4.293-4.293 4.293a1.0001 1.0001 0 1 0 1.4141 1.4141l4.293-4.293 4.293 4.293a1.0001 1.0001 0 1 0 1.4141-1.4141l-4.293-4.293 4.293-4.293a1.0001 1.0001 0 0 0 -.72656-1.7148 1.0001 1.0001 0 0 0 -.6875.30078l-4.293 4.293-4.293-4.293a1.0001 1.0001 0 0 0 -.7168-.30273z" fill="#ff5d5d" fill-rule="evenodd"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2.9902 1.9902a1.0001 1.0001 0 0 0 -.69727 1.7168l4.293 4.293-4.293 4.293a1.0001 1.0001 0 1 0 1.4141 1.4141l4.293-4.293 4.293 4.293a1.0001 1.0001 0 1 0 1.4141-1.4141l-4.293-4.293 4.293-4.293a1.0001 1.0001 0 0 0 -.72656-1.7148 1.0001 1.0001 0 0 0 -.6875.30078l-4.293 4.293-4.293-4.293a1.0001 1.0001 0 0 0 -.7168-.30273z" fill="#ff5f5f" fill-rule="evenodd"/></svg>
diff --git a/editor/icons/KeyBlendShape.svg b/editor/icons/KeyBlendShape.svg
index 42f7341942..11932bd847 100644
--- a/editor/icons/KeyBlendShape.svg
+++ b/editor/icons/KeyBlendShape.svg
@@ -1,44 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- height="10"
- viewBox="0 0 10 10"
- width="10"
- version="1.1"
- id="svg80"
- sodipodi:docname="KeyBlendShape.svg"
- inkscape:version="1.1 (1:1.1+202106031931+af4d65493e)"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:svg="http://www.w3.org/2000/svg">
- <defs
- id="defs84" />
- <sodipodi:namedview
- id="namedview82"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageshadow="2"
- inkscape:pageopacity="0.0"
- inkscape:pagecheckerboard="0"
- showgrid="false"
- inkscape:zoom="84.4"
- inkscape:cx="2.6599526"
- inkscape:cy="5.0059242"
- inkscape:window-width="1848"
- inkscape:window-height="1016"
- inkscape:window-x="72"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg80" />
- <rect
- fill="#3cf34e"
- height="6.1027"
- ry=".76286"
- transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)"
- width="6.1027"
- x="-740.13947"
- y="741.10779"
- id="rect78"
- style="fill:#5ad5c4;fill-opacity:1" />
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#5ad5c4" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg>
diff --git a/editor/icons/KeyInvalid.svg b/editor/icons/KeyInvalid.svg
index 4a04c1ee65..4cfc72dc3f 100644
--- a/editor/icons/KeyInvalid.svg
+++ b/editor/icons/KeyInvalid.svg
@@ -1 +1 @@
-<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m.46447 1046.2 2.1213 2.1213-2.1213 2.1213 1.4142 1.4142 2.1213-2.1213 2.1213 2.1213 1.4142-1.4142-2.1213-2.1213 2.1213-2.1213-1.4142-1.4142-2.1213 2.1213-2.1213-2.1213-1.4142 1.4142z" fill="#ff5d5d" transform="translate(0 -1044.4)"/></svg>
+<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m.46447 1046.2 2.1213 2.1213-2.1213 2.1213 1.4142 1.4142 2.1213-2.1213 2.1213 2.1213 1.4142-1.4142-2.1213-2.1213 2.1213-2.1213-1.4142-1.4142-2.1213 2.1213-2.1213-2.1213-1.4142 1.4142z" fill="#ff5f5f" transform="translate(0 -1044.4)"/></svg>
diff --git a/editor/icons/KeyTrackBlendShape.svg b/editor/icons/KeyTrackBlendShape.svg
index e82f0d6a6f..2594fad3d3 100644
--- a/editor/icons/KeyTrackBlendShape.svg
+++ b/editor/icons/KeyTrackBlendShape.svg
@@ -1,45 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- height="10"
- viewBox="0 0 10 10"
- width="10"
- version="1.1"
- id="svg12"
- sodipodi:docname="KeyTrackBlendShape.svg"
- inkscape:version="1.1 (1:1.1+202106031931+af4d65493e)"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:svg="http://www.w3.org/2000/svg">
- <defs
- id="defs16" />
- <sodipodi:namedview
- id="namedview14"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageshadow="2"
- inkscape:pageopacity="0.0"
- inkscape:pagecheckerboard="0"
- showgrid="false"
- inkscape:zoom="29.839906"
- inkscape:cx="-3.5690461"
- inkscape:cy="9.0985541"
- inkscape:window-width="1848"
- inkscape:window-height="1016"
- inkscape:window-x="72"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg12" />
- <ellipse
- style="fill:none;fill-opacity:0.401212;stroke:none;stroke-width:4.7811;stroke-linejoin:round"
- id="path921"
- cx="-0.88986981"
- cy="6.0959954"
- rx="1.2495773"
- ry="1.0867468" />
- <path
- id="path1910"
- style="color:#000000;fill:#5ad5c4;stroke-linejoin:round;-inkscape-stroke:none"
- d="m 4.5230825,1.1341567 c -2.1310744,0.017055 -3.86718737,1.7635044 -3.86718737,3.8984375 0,1.8778511 1.34348597,3.4523891 3.11718737,3.8164061 L 3.95277,7.5794693 C 2.7929991,7.3095662 1.9351921,6.2780435 1.9351921,5.0325942 c 0,-1.4262775 1.123493,-2.5732858 2.5390622,-2.6152344 v 0.017578 h 0.2011719 l 0.1796875,-1.28125 H 4.5230825 v -0.011719 c 0,-0.00263 -2.64e-5,-0.00518 0,-0.00781 z m 1.6816406,0.019531 -0.1796875,1.28125 h 1.3085937 c 0.078866,0 0.1230469,0.044181 0.1230469,0.1230469 v 4.9882815 c 0,0.07887 -0.044181,0.121093 -0.1230469,0.121094 H 5.2887075 L 5.10902,8.9486103 h 2.2246093 c 0.7663818,0 1.4042969,-0.635962 1.4042969,-1.402344 V 2.5579848 c 0,-0.7663818 -0.637915,-1.4042969 -1.4042969,-1.4042969 z" />
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><ellipse cx="-.88987" cy="6.095995" fill="none" rx="1.249577" ry="1.086747"/><path d="m4.5230825 1.1341567c-2.1310744.017055-3.86718737 1.7635044-3.86718737 3.8984375 0 1.8778511 1.34348597 3.4523891 3.11718737 3.8164061l.1796875-1.269531c-1.1597709-.2699031-2.0175779-1.3014258-2.0175779-2.5468751 0-1.4262775 1.123493-2.5732858 2.5390622-2.6152344v.017578h.2011719l.1796875-1.28125h-.3320312v-.011719c0-.00263-.0000264-.00518 0-.00781zm1.6816406.019531-.1796875 1.28125h1.3085937c.078866 0 .1230469.044181.1230469.1230469v4.9882815c0 .07887-.044181.121093-.1230469.121094h-2.0449218l-.1796875 1.2812502h2.2246093c.7663818 0 1.4042969-.635962 1.4042969-1.402344v-4.9882815c0-.7663818-.637915-1.4042969-1.4042969-1.4042969z" fill="#5ad5c4" stroke-linejoin="round"/></svg>
diff --git a/editor/icons/KeyTrackPosition.svg b/editor/icons/KeyTrackPosition.svg
index 05c6e88841..300b0439e5 100644
--- a/editor/icons/KeyTrackPosition.svg
+++ b/editor/icons/KeyTrackPosition.svg
@@ -1,47 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- height="10"
- viewBox="0 0 10 10"
- width="10"
- version="1.1"
- id="svg12"
- sodipodi:docname="KeyTrackPosition.svg"
- inkscape:version="1.1 (1:1.1+202106031931+af4d65493e)"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:svg="http://www.w3.org/2000/svg">
- <defs
- id="defs16" />
- <sodipodi:namedview
- id="namedview14"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageshadow="2"
- inkscape:pageopacity="0.0"
- inkscape:pagecheckerboard="0"
- showgrid="false"
- inkscape:zoom="42.2"
- inkscape:cx="12.78436"
- inkscape:cy="6.1729858"
- inkscape:window-width="1848"
- inkscape:window-height="1016"
- inkscape:window-x="72"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg12" />
- <ellipse
- style="fill:none;fill-opacity:0.401212;stroke:none;stroke-width:4.7811;stroke-linejoin:round"
- id="path921"
- cx="-0.88986981"
- cy="6.0959954"
- rx="1.2495773"
- ry="1.0867468" />
- <path
- d="M 4.949661,0.60426977 A 0.6444116,0.6444116 0 0 0 4.504153,0.79178767 L 3.215459,2.0804819 4.12663,2.9916532 4.95977,2.1585124 5.792911,2.9916532 6.704083,2.0804819 5.415388,0.79178767 A 0.6444116,0.6444116 0 0 0 4.949744,0.60426977 Z M 1.926771,3.3691634 0.638077,4.6578577 a 0.6444116,0.6444116 0 0 0 0,0.9111713 L 1.926771,6.8577233 2.837942,5.946552 2.004801,5.1134111 2.837942,4.2802702 1.926771,3.3690989 Z m 6.065948,0 -0.911171,0.9111713 0.83314,0.8331409 -0.83314,0.8331408 0.911171,0.9111714 1.288694,-1.2886944 a 0.6444116,0.6444116 0 0 0 0,-0.9111713 L 7.992719,3.3692278 Z M 4.959777,3.8247361 A 1.2886943,1.2886943 0 0 0 3.671083,5.1134305 1.2886943,1.2886943 0 0 0 4.959777,6.4021248 1.2886943,1.2886943 0 0 0 6.248471,5.1134305 1.2886943,1.2886943 0 0 0 4.959777,3.8247361 Z m -0.83314,3.4105296 -0.911172,0.9111715 1.288694,1.288694 a 0.6444116,0.6444116 0 0 0 0.911171,0 L 6.704025,8.1464372 5.792853,7.2352657 4.959712,8.0684062 4.126572,7.2352657 Z"
- fill="#e0e0e0"
- fill-opacity="0.99608"
- id="path1400"
- style="fill:#ea7940;fill-opacity:1;stroke-width:0.644347" />
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><ellipse cx="-.88987" cy="6.095995" fill="none" rx="1.249577" ry="1.086747"/><path d="m4.949661.60426977a.6444116.6444116 0 0 0 -.445508.1875179l-1.288694 1.28869423.911171.9111713.83314-.8331408.833141.8331408.911172-.9111713-1.288695-1.28869423a.6444116.6444116 0 0 0 -.465644-.1875179zm-3.02289 2.76489363-1.288694 1.2886943a.6444116.6444116 0 0 0 0 .9111713l1.288694 1.2886943.911171-.9111713-.833141-.8331409.833141-.8331409-.911171-.9111713zm6.065948 0-.911171.9111713.83314.8331409-.83314.8331408.911171.9111714 1.288694-1.2886944a.6444116.6444116 0 0 0 0-.9111713l-1.288694-1.2886943zm-3.032942.4555727a1.2886943 1.2886943 0 0 0 -1.288694 1.2886944 1.2886943 1.2886943 0 0 0 1.288694 1.2886943 1.2886943 1.2886943 0 0 0 1.288694-1.2886943 1.2886943 1.2886943 0 0 0 -1.288694-1.2886944zm-.83314 3.4105296-.911172.9111715 1.288694 1.288694a.6444116.6444116 0 0 0 .911171 0l1.288695-1.288694-.911172-.9111715-.833141.8331405-.83314-.8331405z" fill="#ea7940" stroke-width=".644347"/></svg>
diff --git a/editor/icons/KeyTrackRotation.svg b/editor/icons/KeyTrackRotation.svg
index d05e381eb2..cfaa9ef80b 100644
--- a/editor/icons/KeyTrackRotation.svg
+++ b/editor/icons/KeyTrackRotation.svg
@@ -1,47 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- height="10"
- viewBox="0 0 10 10"
- width="10"
- version="1.1"
- id="svg12"
- sodipodi:docname="KeyTrackRotation.svg"
- inkscape:version="1.1 (1:1.1+202106031931+af4d65493e)"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:svg="http://www.w3.org/2000/svg">
- <defs
- id="defs16" />
- <sodipodi:namedview
- id="namedview14"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageshadow="2"
- inkscape:pageopacity="0.0"
- inkscape:pagecheckerboard="0"
- showgrid="false"
- inkscape:zoom="42.2"
- inkscape:cx="1.9075829"
- inkscape:cy="5.8175355"
- inkscape:window-width="1848"
- inkscape:window-height="1016"
- inkscape:window-x="72"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg12" />
- <ellipse
- style="fill:none;fill-opacity:0.401212;stroke:none;stroke-width:4.7811;stroke-linejoin:round"
- id="path921"
- cx="-0.88986981"
- cy="6.0959954"
- rx="1.2495773"
- ry="1.0867468" />
- <path
- d="m 5.0711986,0.88214062 a 4.1086779,4.1086779 0 0 0 -0.178839,0.00115 4.1086779,4.1086779 0 0 0 -0.409265,0.033245 A 4.1086779,4.1086779 0 0 0 0.99001362,4.1883346 4.1086779,4.1086779 0 0 0 2.1467236,7.9244144 h -0.648877 v 1.1739077 h 2.347816 a 0.58701268,0.58701268 0 0 0 0.569756,-0.729119 l -0.586953,-2.3478164 -1.139514,0.2854534 0.165082,0.6580347 a 2.9347699,2.9347699 0 0 1 -0.769204,-1.9752178 2.9347699,2.9347699 0 0 1 2.93477,-2.93477 2.9347699,2.9347699 0 0 1 2.93477,2.93477 2.9347699,2.9347699 0 0 1 -0.860944,2.0738257 l 0.831127,0.8311266 A 4.1086779,4.1086779 0 0 0 8.7040866,3.1726236 4.1086779,4.1086779 0 0 0 5.0711336,0.88215292 Z m -0.05159,2.93359608 a 1.173908,1.173908 0 0 0 -1.173907,1.173908 1.173908,1.173908 0 0 0 1.173907,1.173908 1.173908,1.173908 0 0 0 1.173909,-1.173908 1.173908,1.173908 0 0 0 -1.173909,-1.173908 z"
- fill="#e0e0e0"
- fill-opacity="0.99608"
- id="path1165"
- style="fill:#ff2b88;fill-opacity:1;stroke-width:0.586954" />
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><ellipse cx="-.88987" cy="6.095995" fill="none" rx="1.249577" ry="1.086747"/><path d="m5.0711986.88214062a4.1086779 4.1086779 0 0 0 -.178839.00115 4.1086779 4.1086779 0 0 0 -.409265.033245 4.1086779 4.1086779 0 0 0 -3.49308098 3.27179898 4.1086779 4.1086779 0 0 0 1.15670998 3.7360798h-.648877v1.1739077h2.347816a.58701268.58701268 0 0 0 .569756-.729119l-.586953-2.3478164-1.139514.2854534.165082.6580347a2.9347699 2.9347699 0 0 1 -.769204-1.9752178 2.9347699 2.9347699 0 0 1 2.93477-2.93477 2.9347699 2.9347699 0 0 1 2.93477 2.93477 2.9347699 2.9347699 0 0 1 -.860944 2.0738257l.831127.8311266a4.1086779 4.1086779 0 0 0 .779534-4.7219857 4.1086779 4.1086779 0 0 0 -3.632953-2.29047068zm-.05159 2.93359608a1.173908 1.173908 0 0 0 -1.173907 1.173908 1.173908 1.173908 0 0 0 1.173907 1.173908 1.173908 1.173908 0 0 0 1.173909-1.173908 1.173908 1.173908 0 0 0 -1.173909-1.173908z" fill="#ff2b88" stroke-width=".586954"/></svg>
diff --git a/editor/icons/KeyTrackScale.svg b/editor/icons/KeyTrackScale.svg
index 9269ccbca2..73fe1cb5f0 100644
--- a/editor/icons/KeyTrackScale.svg
+++ b/editor/icons/KeyTrackScale.svg
@@ -1,47 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- height="10"
- viewBox="0 0 10 10"
- width="10"
- version="1.1"
- id="svg12"
- sodipodi:docname="KeyTrackScale.svg"
- inkscape:version="1.1 (1:1.1+202106031931+af4d65493e)"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:svg="http://www.w3.org/2000/svg">
- <defs
- id="defs16" />
- <sodipodi:namedview
- id="namedview14"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageshadow="2"
- inkscape:pageopacity="0.0"
- inkscape:pagecheckerboard="0"
- showgrid="false"
- inkscape:zoom="42.2"
- inkscape:cx="1.9075829"
- inkscape:cy="5.8175355"
- inkscape:window-width="1848"
- inkscape:window-height="1016"
- inkscape:window-x="72"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg12" />
- <ellipse
- style="fill:none;fill-opacity:0.401212;stroke:none;stroke-width:4.7811;stroke-linejoin:round"
- id="path921"
- cx="-0.88986981"
- cy="6.0959954"
- rx="1.2495773"
- ry="1.0867468" />
- <path
- d="M 5.5742494,0.94786723 A 0.58774585,0.58774585 0 0 0 4.9865036,1.535613 0.58774585,0.58774585 0 0 0 5.5742494,2.1233589 h 1.519852 L 6.334146,2.8833142 7.1652774,3.7144456 7.9252328,2.9544903 V 4.4743422 A 0.58774585,0.58774585 0 0 0 8.5129787,5.0620881 0.58774585,0.58774585 0 0 0 9.1007245,4.4743422 V 1.535613 A 0.58780462,0.58780462 0 0 0 8.5129787,0.94786723 Z M 4.9865036,3.8865964 A 1.1754917,1.1754917 0 0 0 3.8110119,5.0620881 1.1754917,1.1754917 0 0 0 4.9865036,6.2375798 1.1754917,1.1754917 0 0 0 6.1619953,5.0620881 1.1754917,1.1754917 0 0 0 4.9865036,3.8865964 Z M 1.4600285,5.0620881 A 0.58774585,0.58774585 0 0 0 0.8722826,5.6498339 V 8.5885638 A 0.58780462,0.58780462 0 0 0 1.4600285,9.1763092 H 4.3987577 A 0.58774585,0.58774585 0 0 0 4.9865036,8.5885638 0.58774585,0.58774585 0 0 0 4.3987577,8.0008173 H 2.8789057 L 3.6388611,7.2408619 2.8077297,6.4097305 2.0477743,7.1696859 V 5.6498339 A 0.58774585,0.58774585 0 0 0 1.4600285,5.0620881 Z"
- fill="#e0e0e0"
- fill-opacity="0.99608"
- id="path7"
- style="fill:#eac840;fill-opacity:1;stroke-width:0.587745" />
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><ellipse cx="-.88987" cy="6.095995" fill="none" rx="1.249577" ry="1.086747"/><path d="m5.5742494.94786723a.58774585.58774585 0 0 0 -.5877458.58774577.58774585.58774585 0 0 0 .5877458.5877459h1.519852l-.7599554.7599553.8311314.8311314.7599554-.7599553v1.5198519a.58774585.58774585 0 0 0 .5877459.5877459.58774585.58774585 0 0 0 .5877458-.5877459v-2.9387292a.58780462.58780462 0 0 0 -.5877458-.58774577zm-.5877458 2.93872917a1.1754917 1.1754917 0 0 0 -1.1754917 1.1754917 1.1754917 1.1754917 0 0 0 1.1754917 1.1754917 1.1754917 1.1754917 0 0 0 1.1754917-1.1754917 1.1754917 1.1754917 0 0 0 -1.1754917-1.1754917zm-3.5264751 1.1754917a.58774585.58774585 0 0 0 -.5877459.5877458v2.9387299a.58780462.58780462 0 0 0 .5877459.5877454h2.9387292a.58774585.58774585 0 0 0 .5877459-.5877454.58774585.58774585 0 0 0 -.5877459-.5877465h-1.519852l.7599554-.7599554-.8311314-.8311314-.7599554.7599554v-1.519852a.58774585.58774585 0 0 0 -.5877458-.5877458z" fill="#eac840" stroke-width=".587745"/></svg>
diff --git a/editor/icons/KeyXPosition.svg b/editor/icons/KeyXPosition.svg
index 5816a241c9..59c14cd820 100644
--- a/editor/icons/KeyXPosition.svg
+++ b/editor/icons/KeyXPosition.svg
@@ -1,43 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- height="10"
- viewBox="0 0 10 10"
- width="10"
- version="1.1"
- id="svg1678"
- sodipodi:docname="KeyXPosition.svg"
- inkscape:version="1.1 (1:1.1+202106031931+af4d65493e)"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:svg="http://www.w3.org/2000/svg">
- <defs
- id="defs1682" />
- <sodipodi:namedview
- id="namedview1680"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageshadow="2"
- inkscape:pageopacity="0.0"
- inkscape:pagecheckerboard="0"
- showgrid="false"
- inkscape:zoom="84.4"
- inkscape:cx="4.9940758"
- inkscape:cy="5.0059242"
- inkscape:window-width="1848"
- inkscape:window-height="1016"
- inkscape:window-x="72"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg1678" />
- <rect
- fill="#ea7940"
- height="6.1027"
- ry=".76286"
- transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)"
- width="6.1027"
- x="-740.13947"
- y="741.10779"
- id="rect1676" />
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#ea7940" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 0 -1042.4)" width="6.1027" x="-740.13947" y="741.10779"/></svg>
diff --git a/editor/icons/KeyXRotation.svg b/editor/icons/KeyXRotation.svg
index 6cd5a67ac0..4494c301bb 100644
--- a/editor/icons/KeyXRotation.svg
+++ b/editor/icons/KeyXRotation.svg
@@ -1,44 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- height="10"
- viewBox="0 0 10 10"
- width="10"
- version="1.1"
- id="svg1678"
- sodipodi:docname="KeyXRotation.svg"
- inkscape:version="1.1 (1:1.1+202106031931+af4d65493e)"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:svg="http://www.w3.org/2000/svg">
- <defs
- id="defs1682" />
- <sodipodi:namedview
- id="namedview1680"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageshadow="2"
- inkscape:pageopacity="0.0"
- inkscape:pagecheckerboard="0"
- showgrid="false"
- inkscape:zoom="84.4"
- inkscape:cx="0.32582938"
- inkscape:cy="5.0059242"
- inkscape:window-width="1848"
- inkscape:window-height="1016"
- inkscape:window-x="72"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg1678" />
- <rect
- fill="#ea7940"
- height="6.1027002"
- ry="0.76286"
- transform="rotate(-45,-1258.2881,-521.2)"
- width="6.1030002"
- x="-740.13947"
- y="741.10779"
- id="rect1676"
- style="fill:#ee3c94;fill-opacity:1" />
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#ff2b88" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 .000003 -1042.399994)" width="6.103" x="-740.13947" y="741.10779"/></svg>
diff --git a/editor/icons/KeyXScale.svg b/editor/icons/KeyXScale.svg
index 588fa5d2f3..cb6011cd83 100644
--- a/editor/icons/KeyXScale.svg
+++ b/editor/icons/KeyXScale.svg
@@ -1,44 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- height="10"
- viewBox="0 0 10 10"
- width="10"
- version="1.1"
- id="svg1678"
- sodipodi:docname="KeyXScale.svg"
- inkscape:version="1.1 (1:1.1+202106031931+af4d65493e)"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:svg="http://www.w3.org/2000/svg">
- <defs
- id="defs1682" />
- <sodipodi:namedview
- id="namedview1680"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageshadow="2"
- inkscape:pageopacity="0.0"
- inkscape:pagecheckerboard="0"
- showgrid="false"
- inkscape:zoom="84.4"
- inkscape:cx="2.6658768"
- inkscape:cy="5.0059242"
- inkscape:window-width="1473"
- inkscape:window-height="752"
- inkscape:window-x="122"
- inkscape:window-y="114"
- inkscape:window-maximized="0"
- inkscape:current-layer="svg1678" />
- <rect
- fill="#ea7940"
- height="6.1027002"
- ry="0.76286"
- transform="rotate(-45,-1258.2881,-521.2)"
- width="6.1030002"
- x="-740.13947"
- y="741.10779"
- id="rect1676"
- style="fill:#dbbf4f;fill-opacity:1" />
-</svg>
+<svg height="10" viewBox="0 0 10 10" width="10" xmlns="http://www.w3.org/2000/svg"><rect fill="#eac840" height="6.1027" ry=".76286" transform="matrix(.70710678 -.70710678 .70710678 .70710678 .000003 -1042.399994)" width="6.103" x="-740.13947" y="741.10779"/></svg>
diff --git a/editor/icons/MaterialPreviewCube.svg b/editor/icons/MaterialPreviewCube.svg
index 29baa9f030..c4af05ffb0 100644
--- a/editor/icons/MaterialPreviewCube.svg
+++ b/editor/icons/MaterialPreviewCube.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m8 1-7 3v8l7 3 7-3v-8z" fill="#d5d5d5" transform="translate(0 1036.4)"/><path d="m1 1040.4 7 3 7-3-7-3z" fill="#fff"/><path d="m8 1051.4-7-3v-8l7 3z" fill="#e0e0e0"/><path d="m8 1051.4 7-3v-8l-7 3z" fill="#d5d5d5"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m8 1-7 3v8l7 3 7-3v-8z" fill="#d6d6d6" transform="translate(0 1036.4)"/><path d="m1 1040.4 7 3 7-3-7-3z" fill="#fff"/><path d="m8 1051.4-7-3v-8l7 3z" fill="#e0e0e0"/><path d="m8 1051.4 7-3v-8l-7 3z" fill="#d6d6d6"/></g></svg>
diff --git a/editor/icons/MaterialPreviewCubeOff.svg b/editor/icons/MaterialPreviewCubeOff.svg
index 14564c558e..e573e170ad 100644
--- a/editor/icons/MaterialPreviewCubeOff.svg
+++ b/editor/icons/MaterialPreviewCubeOff.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m8 1-7 3v8l7 3 7-3v-8z" fill="#d5d5d5" transform="translate(0 1036.4)"/><path d="m1 1040.4 7 3 7-3-7-3z" fill="#fff"/><path d="m8 1051.4-7-3v-8l7 3z" fill="#e0e0e0"/><path d="m8 1051.4 7-3v-8l-7 3z" fill="#d5d5d5"/><path d="m8 1037.4-7 3v8l7 3 7-3v-8z" fill-opacity=".23529"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m8 1-7 3v8l7 3 7-3v-8z" fill="#d6d6d6" transform="translate(0 1036.4)"/><path d="m1 1040.4 7 3 7-3-7-3z" fill="#fff"/><path d="m8 1051.4-7-3v-8l7 3z" fill="#e0e0e0"/><path d="m8 1051.4 7-3v-8l-7 3z" fill="#d6d6d6"/><path d="m8 1037.4-7 3v8l7 3 7-3v-8z" fill-opacity=".23529"/></g></svg>
diff --git a/editor/icons/MaterialPreviewLight1Off.svg b/editor/icons/MaterialPreviewLight1Off.svg
index 2f84612e82..f51b0bbcb2 100644
--- a/editor/icons/MaterialPreviewLight1Off.svg
+++ b/editor/icons/MaterialPreviewLight1Off.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v2h2v-2zm-3.2422 1.3438-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm8.4844 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-4.2422 1.6562a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0 -4-4zm-1 1h2v1 5h-1v-5h-1zm-6 2v2h2v-2zm12 0v2h2v-2zm-9.2422 3.8281-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm8.4844 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-5.2422 2.1719v2h2v-2z" fill-opacity=".23529"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v2h2v-2zm-3.2422 1.3438-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm8.4844 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-4.2422 1.6562a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0 -4-4zm-1 1h2v1 5h-1v-5h-1zm-6 2v2h2v-2zm12 0v2h2v-2zm-9.2422 3.8281-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm8.4844 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-5.2422 2.1719v2h2v-2z" fill="#e0e0e0"/><path d="m7 1v2h2v-2zm-3.2422 1.3438-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm8.4844 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-4.2422 1.6562a4 4 0 0 0 -4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0 -4-4zm-1 1h2v1 5h-1v-5h-1zm-6 2v2h2v-2zm12 0v2h2v-2zm-9.2422 3.8281-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm8.4844 0-1.4141 1.4141 1.4141 1.4141 1.4141-1.4141zm-5.2422 2.1719v2h2v-2z" fill-opacity=".23529"/></svg>
diff --git a/editor/icons/MaterialPreviewSphereOff.svg b/editor/icons/MaterialPreviewSphereOff.svg
index 52bb095210..e958e3f0a8 100644
--- a/editor/icons/MaterialPreviewSphereOff.svg
+++ b/editor/icons/MaterialPreviewSphereOff.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm-2 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill-opacity=".23529"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm-2 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill="#e0e0e0"/><path d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0 -7-7zm-2 2a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2z" fill-opacity=".23529"/></svg>
diff --git a/editor/icons/NavigationAgent2D.svg b/editor/icons/NavigationAgent2D.svg
index 28760be4a1..3f1d571a7e 100644
--- a/editor/icons/NavigationAgent2D.svg
+++ b/editor/icons/NavigationAgent2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 4.2333332 4.2333335" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2.9999997.0000126-5 2-5 5s3.0000003 6 5 9c2-3 5.007143-6.0296693 5-9 0-3-2-4.9999874-5-5zm0 2.5a2.4999999 2.4999999 0 0 1 2.5 2.5 2.4999999 2.4999999 0 0 1 -2.5 2.5 2.4999999 2.4999999 0 0 1 -2.5-2.5 2.4999999 2.4999999 0 0 1 2.5-2.5z" fill="#e0e0e0" transform="scale(.26458333)"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3 0-5 2-5 5s3 6 5 9c2-3 5.007-6.03 5-9 0-3-2-5-5-5zm0 2.5c1.371 0 2.5 1.129 2.5 2.5s-1.129 2.5-2.5 2.5-2.5-1.129-2.5-2.5 1.129-2.5 2.5-2.5z" fill="#e0e0e0" fill-rule="nonzero"/></svg>
diff --git a/editor/icons/NavigationAgent3D.svg b/editor/icons/NavigationAgent3D.svg
index da76adaa99..947b2129c3 100644
--- a/editor/icons/NavigationAgent3D.svg
+++ b/editor/icons/NavigationAgent3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 4.2333332 4.2333335" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="scale(.26458333)"><path d="m9 1c-1.3712923 0-2.308408.4294811-2.9394531 1.0742188-.6678822.6627728-1.3395938 1.3233299-2.0097657 1.984375-.0455468 1.7412784.7567781 4.3277129 2.3652344 4.84375.1781835.3171398.3844475.6487461.5839844.9765624v5.1210938l2-2c2-3 4-5.9999874 4-8s-1-4-4-4z" fill="#fff" fill-opacity=".392157"/><path d="m7 3c-3 0-4 1.9999874-4 4s2.0000003 5 4 8c2.0000001-3 4-5.9999874 4-8s-1-4-4-4zm0 2a1.9999999 1.9999999 0 0 1 2 2 1.9999999 1.9999999 0 0 1 -2 2 1.9999999 1.9999999 0 0 1 -2-2 1.9999999 1.9999999 0 0 1 2-2z" fill="#e0e0e0"/></g></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero"><path d="m9 1c-1.371 0-2.308.429-2.939 1.074-.668.663-1.34 1.324-2.01 1.985-.046 1.741.757 4.327 2.365 4.843.178.317.384.649.584.977v5.121l2-2c2-3 4-6 4-8s-1-4-4-4z" fill="#fff" fill-opacity=".39"/><path d="m7 3c-3 0-4 2-4 4s2 5 4 8c2-3 4-6 4-8s-1-4-4-4zm0 2c1.097 0 2 .903 2 2s-.903 2-2 2-2-.903-2-2 .903-2 2-2z" fill="#e0e0e0"/></g></svg>
diff --git a/editor/icons/NavigationObstacle2D.svg b/editor/icons/NavigationObstacle2D.svg
index fab41e2f43..8fcb5617dd 100644
--- a/editor/icons/NavigationObstacle2D.svg
+++ b/editor/icons/NavigationObstacle2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 4.2333332 4.2333335" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 .875c-.625 0-1.2499999.3749906-1.5 1.125l-2.9999999 10h8.9999999l-3-10c-.2499999-.7500094-.875-1.125-1.5-1.125zm-1.5 4.125h3l1 4h-5zm-4.5 8c-1 0-1 2 0 2h12c1 0 1-2 0-2z" fill="#e0e0e0" transform="scale(.26458333)"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m8 .875c-.625 0-1.25.375-1.5 1.125l-3 10h9l-3-10c-.25-.75-.875-1.125-1.5-1.125zm-1.5 4.125h3l1 4h-5zm-4.5 8c-1 0-1 2 0 2h12c1 0 1-2 0-2z" fill="#e0e0e0" fill-rule="nonzero"/></svg>
diff --git a/editor/icons/NavigationObstacle3D.svg b/editor/icons/NavigationObstacle3D.svg
index 10b09107cd..c5e58eebf7 100644
--- a/editor/icons/NavigationObstacle3D.svg
+++ b/editor/icons/NavigationObstacle3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 4.2333332 4.2333335" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="scale(.26458333)"><path d="m4.6074219 8.3789062c-1.7979243.927604-3.60742192 2.0716858-3.6074219 2.6210938 0 .999987 6.0000005 4 7 4 1.0000006 0 7-3.000013 7-4 0-.549408-1.809498-1.6934898-3.607422-2.6210938l.607422 1.6210938c2 4.000025-9.9999999 4.000025-8 0z" fill="#fff" fill-opacity=".392157"/><path d="m8 .875c-.375 0-.7499997.3749906-1 1.125l-3 8c-1.9999998 4.000025 10 4.000025 8 0l-3-8c-.2499997-.7500094-.625-1.125-1-1.125zm-1.5 4.125c.9999999.4999937 2.0000001.4999937 3 0l1 3.5c-1.4999996.9999874-3.4999996.9999874-5 0z" fill="#e0e0e0"/></g></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero"><path d="m4.607 8.379c-1.798.928-3.607 2.072-3.607 2.621 0 1 6 4 7 4s7-3 7-4c0-.549-1.809-1.693-3.607-2.621l.607 1.621c2 4-10 4-8 0z" fill="#fff" fill-opacity=".39"/><path d="m8 .875c-.375 0-.75.375-1 1.125l-3 8c-2 4 10 4 8 0l-3-8c-.25-.75-.625-1.125-1-1.125zm-1.5 4.125c1 .5 2 .5 3 0l1 3.5c-1.5 1-3.5 1-5 0z" fill="#e0e0e0"/></g></svg>
diff --git a/editor/icons/NodeDisabled.svg b/editor/icons/NodeDisabled.svg
index b2d51fc4fb..f0cc586103 100644
--- a/editor/icons/NodeDisabled.svg
+++ b/editor/icons/NodeDisabled.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4z" fill="#999"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4z" fill="#919191"/></svg>
diff --git a/editor/icons/OccluderPolygon2D.svg b/editor/icons/OccluderPolygon2D.svg
index ae5d2f4a1d..7ab4240d2f 100644
--- a/editor/icons/OccluderPolygon2D.svg
+++ b/editor/icons/OccluderPolygon2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m1 1045.4 6 6h8v-8l-6-6h-8z" fill="#3552b1"/><path d="m1 1037.4h8l-3 4 3 4h-8z" fill="#8da5f3" fill-opacity=".98824"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m1 1045.4 6 6h8v-8l-6-6h-8z" fill="#4b70ea"/><path d="m1 1037.4h8l-3 4 3 4h-8z" fill="#8da5f3" fill-opacity=".98824"/></g></svg>
diff --git a/editor/icons/OverbrightIndicator.svg b/editor/icons/OverbrightIndicator.svg
index f618980d51..35ad59fbfb 100644
--- a/editor/icons/OverbrightIndicator.svg
+++ b/editor/icons/OverbrightIndicator.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m.5.5v10l10-10z" fill="#fff" stroke="#000"/><path d="m0 12 12-12h-1.714286l-10.285714 10.285714z" fill="#000003" stroke-width="2"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m.5.5v10l10-10z" fill="#fff" stroke="#000000"/><path d="m0 12 12-12h-1.714286l-10.285714 10.285714z" fill="#000003" stroke-width="2"/></svg>
diff --git a/editor/icons/PackedByteArray.svg b/editor/icons/PackedByteArray.svg
index 95534e4410..448e25c478 100644
--- a/editor/icons/PackedByteArray.svg
+++ b/editor/icons/PackedByteArray.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2h-2zm12 0v2h2v8h-2v2h4v-12h-2z" fill="#e0e0e0"/><path d="m5 3a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v4h2a3 3 0 0 0 1-.17578v.17578h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4h-2v3a1 1 0 0 1 -1 1v-4h-2z" fill="#69ec9e"/><path d="m6 9v-6h2v4a1 1 0 0 0 1-1v-3h2v4a1 1 0 0 0 1-1v-3h2v3a3 3 0 0 1 -3 3h-2v-.1758a3 3 0 0 1 -1 .1758z" fill="#fff" fill-opacity=".39216"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2h-2zm12 0v2h2v8h-2v2h4v-12h-2z" fill="#e0e0e0"/><path d="m5 3a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1h1v4h2a3 3 0 0 0 1-.17578v.17578h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4h-2v3a1 1 0 0 1 -1 1v-4h-2z" fill="#5fff97"/><path d="m6 9v-6h2v4a1 1 0 0 0 1-1v-3h2v4a1 1 0 0 0 1-1v-3h2v3a3 3 0 0 1 -3 3h-2v-.1758a3 3 0 0 1 -1 .1758z" fill="#fff" fill-opacity=".39216"/></svg>
diff --git a/editor/icons/PackedColorArray.svg b/editor/icons/PackedColorArray.svg
index 588002f188..6911ff1d34 100644
--- a/editor/icons/PackedColorArray.svg
+++ b/editor/icons/PackedColorArray.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m6 3.5a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2z" fill="#ff4545"/><path d="m13 3.5a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1z" fill="#70bfff"/><path d="m7 1.5v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5z" fill="#7aff70"/></svg>
+<svg height="12" viewBox="0 0 16 12" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v12h4v-2h-2v-8h2v-2zm12 0v2h2v8h-2v2h4v-12z" fill="#e0e0e0"/><path d="m6 3.5a3 3 0 0 0 -3 3 3 3 0 0 0 3 3h1v-2h-1a1 1 0 0 1 -1-1 1 1 0 0 1 1-1h1v-2z" fill="#ff4545"/><path d="m13 3.5a3 3 0 0 0 -3 3v3h2v-3a1 1 0 0 1 1-1z" fill="#45d7ff"/><path d="m7 1.5v5a3 3 0 0 0 3 3v-2a1 1 0 0 1 -1-1v-5z" fill="#80ff45"/></svg>
diff --git a/editor/icons/PageFirst.svg b/editor/icons/PageFirst.svg
index 76078691ef..ab5cd2c789 100644
--- a/editor/icons/PageFirst.svg
+++ b/editor/icons/PageFirst.svg
@@ -1,47 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- height="12"
- viewBox="0 0 12 12"
- width="12"
- version="1.1"
- id="svg4"
- sodipodi:docname="PageFirst.svg"
- inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:svg="http://www.w3.org/2000/svg">
- <defs
- id="defs8" />
- <sodipodi:namedview
- id="namedview6"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageshadow="2"
- inkscape:pageopacity="0.0"
- inkscape:pagecheckerboard="0"
- showgrid="true"
- inkscape:zoom="74.25"
- inkscape:cx="18.053872"
- inkscape:cy="6.5252525"
- inkscape:window-width="3838"
- inkscape:window-height="1582"
- inkscape:window-x="0"
- inkscape:window-y="16"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg4">
- <inkscape:grid
- type="xygrid"
- id="grid989" />
- </sodipodi:namedview>
- <path
- d="M 6,9 3,6 6,3"
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- id="path2" />
- <path
- d="M 9,9 V 3"
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- id="path2211"
- sodipodi:nodetypes="cc" />
-</svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#e0e0e0" stroke-width="2"><path d="m6 9-3-3 3-3"/><path d="m9 9v-6"/></g></svg>
diff --git a/editor/icons/PageLast.svg b/editor/icons/PageLast.svg
index 17c874e8c9..0bc8504e11 100644
--- a/editor/icons/PageLast.svg
+++ b/editor/icons/PageLast.svg
@@ -1,47 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- height="12"
- viewBox="0 0 12 12"
- width="12"
- version="1.1"
- id="svg4"
- sodipodi:docname="PageLast.svg"
- inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:svg="http://www.w3.org/2000/svg">
- <defs
- id="defs8" />
- <sodipodi:namedview
- id="namedview6"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageshadow="2"
- inkscape:pageopacity="0.0"
- inkscape:pagecheckerboard="0"
- showgrid="true"
- inkscape:zoom="74.25"
- inkscape:cx="18.053872"
- inkscape:cy="6.5252525"
- inkscape:window-width="3838"
- inkscape:window-height="1582"
- inkscape:window-x="0"
- inkscape:window-y="16"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg4">
- <inkscape:grid
- type="xygrid"
- id="grid989" />
- </sodipodi:namedview>
- <path
- d="m 6.0000414,9 3,-3 -3,-3"
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- id="path2" />
- <path
- d="M 3.0000414,9 V 3"
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- id="path2211"
- sodipodi:nodetypes="cc" />
-</svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#e0e0e0" stroke-width="2"><path d="m6 9 3-3-3-3"/><path d="m3 9v-6"/></g></svg>
diff --git a/editor/icons/PageNext.svg b/editor/icons/PageNext.svg
index 89ff6219bb..2c3d032d63 100644
--- a/editor/icons/PageNext.svg
+++ b/editor/icons/PageNext.svg
@@ -1,42 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- height="12"
- viewBox="0 0 12 12"
- width="12"
- version="1.1"
- id="svg4"
- sodipodi:docname="PageNext.svg"
- inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:svg="http://www.w3.org/2000/svg">
- <defs
- id="defs8" />
- <sodipodi:namedview
- id="namedview6"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageshadow="2"
- inkscape:pageopacity="0.0"
- inkscape:pagecheckerboard="0"
- showgrid="true"
- inkscape:zoom="105.00536"
- inkscape:cx="4.5854803"
- inkscape:cy="5.9377923"
- inkscape:window-width="3838"
- inkscape:window-height="1582"
- inkscape:window-x="0"
- inkscape:window-y="16"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg4">
- <inkscape:grid
- type="xygrid"
- id="grid989" />
- </sodipodi:namedview>
- <path
- d="m 4.5000207,9 3,-3 -3,-3"
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- id="path2" />
-</svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><path d="m4.5 9 3-3-3-3" fill="none" stroke="#e0e0e0" stroke-width="2"/></svg>
diff --git a/editor/icons/PagePrevious.svg b/editor/icons/PagePrevious.svg
index a2fa84da0c..37adc85d7a 100644
--- a/editor/icons/PagePrevious.svg
+++ b/editor/icons/PagePrevious.svg
@@ -1,42 +1 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- height="12"
- viewBox="0 0 12 12"
- width="12"
- version="1.1"
- id="svg4"
- sodipodi:docname="PagePrevious.svg"
- inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:svg="http://www.w3.org/2000/svg">
- <defs
- id="defs8" />
- <sodipodi:namedview
- id="namedview6"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageshadow="2"
- inkscape:pageopacity="0.0"
- inkscape:pagecheckerboard="0"
- showgrid="true"
- inkscape:zoom="105.00536"
- inkscape:cx="4.5854803"
- inkscape:cy="5.9377923"
- inkscape:window-width="3838"
- inkscape:window-height="1582"
- inkscape:window-x="0"
- inkscape:window-y="16"
- inkscape:window-maximized="1"
- inkscape:current-layer="svg4">
- <inkscape:grid
- type="xygrid"
- id="grid989" />
- </sodipodi:namedview>
- <path
- d="m 7.4999793,9 -3,-3 3,-3"
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
- id="path2" />
-</svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><path d="m7.5 9-3-3 3-3" fill="none" stroke="#e0e0e0" stroke-width="2"/></svg>
diff --git a/editor/icons/ParallaxBackground.svg b/editor/icons/ParallaxBackground.svg
index 9d13f3a65d..f188230fcc 100644
--- a/editor/icons/ParallaxBackground.svg
+++ b/editor/icons/ParallaxBackground.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/><path d="m2 2a1 1 0 0 0 -1 1v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-10a1 1 0 0 0 -1-1zm0 1h12v10h-12zm5 2-3 3 3 3zm2 0v6l3-3z" fill="#e0e0e0" fill-opacity=".99608" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m2 2a1 1 0 0 0 -1 1v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-10a1 1 0 0 0 -1-1zm0 1h12v10h-12zm5 2-3 3 3 3zm2 0v6l3-3z" fill="#e0e0e0" fill-opacity=".99608" transform="translate(0 1036.4)"/></g></svg>
diff --git a/editor/icons/ParallaxLayer.svg b/editor/icons/ParallaxLayer.svg
index 0768e941ad..58968b77fb 100644
--- a/editor/icons/ParallaxLayer.svg
+++ b/editor/icons/ParallaxLayer.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 1h10c.55228.0000096.99999.44772 1 1v10c-.00001.55228-.44772.99999-1 1h-10c-.55228-.00001-.99999-.44772-1-1v-10c.0000096-.55228.44772-.99999 1-1zm4 3-3 3 3 3zm2 0v6l3-3z" fill="#8da5f3" fill-opacity=".98824" fill-rule="evenodd" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 1h10c.55228.0000096.99999.44772 1 1v10c-.00001.55228-.44772.99999-1 1h-10c-.55228-.00001-.99999-.44772-1-1v-10c.0000096-.55228.44772-.99999 1-1zm4 3-3 3 3 3zm2 0v6l3-3z" fill="#8da5f3" fill-opacity=".98824" fill-rule="evenodd" transform="translate(0 1036.4)"/></g></svg>
diff --git a/editor/icons/PlayOverlay.svg b/editor/icons/PlayOverlay.svg
index 9b3299d1b9..9ff59b1170 100644
--- a/editor/icons/PlayOverlay.svg
+++ b/editor/icons/PlayOverlay.svg
@@ -1 +1 @@
-<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><rect fill="#044b94" fill-opacity=".6" height="64" rx="5" width="64"/><path d="m16 16 32 16-32 16" fill="#f2f2f2"/></svg>
+<svg height="64" viewBox="0 0 64 64" width="64" xmlns="http://www.w3.org/2000/svg"><rect fill="#699ce8" fill-opacity=".75" height="64" rx="5" width="64"/><path d="m16 16 32 16-32 16" fill="#ffffff"/></svg>
diff --git a/editor/icons/RectangleShape2D.svg b/editor/icons/RectangleShape2D.svg
index f0d6c54dc9..2d6a503255 100644
--- a/editor/icons/RectangleShape2D.svg
+++ b/editor/icons/RectangleShape2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><rect fill="none" height="8" rx=".000017" stroke="#68b6ff" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2" width="12" x="2" y="4"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><rect fill="none" height="8" rx=".000017" stroke="#5fb2ff" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="2" width="12" x="2" y="4"/></svg>
diff --git a/editor/icons/ReverseGradient.svg b/editor/icons/ReverseGradient.svg
index 12f80d12dd..55bc5a1678 100644
--- a/editor/icons/ReverseGradient.svg
+++ b/editor/icons/ReverseGradient.svg
@@ -1 +1 @@
-<?xml version="1.0" encoding="UTF-8"?><svg version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><linearGradient id="b" x1=".26458" x2="3.9688" y1=".79375" y2=".79375" gradientTransform="scale(3.7795)" gradientUnits="userSpaceOnUse"><stop stop-color="#ccc" offset="0"/><stop stop-color="#ccc" stop-opacity="0" offset="1"/></linearGradient><linearGradient id="a" x1=".26458" x2="3.9688" y1="3.4396" y2="3.4396" gradientTransform="matrix(3.7795 0 0 3.7795 -16 -1.1865e-7)" gradientUnits="userSpaceOnUse"><stop stop-color="#ccc" offset="0"/><stop stop-color="#ccc" stop-opacity="0" offset="1"/></linearGradient></defs><g><rect x="1" y="1" width="14" height="4" ry="1" fill="url(#b)"/><rect transform="scale(-1,1)" x="-15" y="11" width="14" height="4" ry="1" fill="url(#a)" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.7795"/><path d="m6 6 2 4 2-4z" fill="#ccc"/></g></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a"><stop offset="0" stop-color="#e0e0e0"/><stop offset="1" stop-color="#e0e0e0" stop-opacity="0"/></linearGradient><linearGradient id="b" gradientUnits="userSpaceOnUse" x1=".99998" x2="15.00008" xlink:href="#a" y1="2.99998" y2="2.99998"/><linearGradient id="c" gradientTransform="matrix(-14.0001 0 0 14.0001 15 13)" gradientUnits="userSpaceOnUse" x1="0" x2="1" xlink:href="#a" y1="0" y2="0"/><path d="m1 1h14v4h-14z" fill="url(#b)"/><path d="m1 11h14v4h-14z" fill="url(#c)"/><path d="m6 6 2 4 2-4z" fill="#e0e0e0" fill-rule="nonzero"/></svg>
diff --git a/editor/icons/Ruler.svg b/editor/icons/Ruler.svg
index 2f026ed365..caf2f7f15c 100644
--- a/editor/icons/Ruler.svg
+++ b/editor/icons/Ruler.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 4.2333 4.2333" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v7.5 6.5h14zm3 7 4 4h-4z" fill="#e0e0e0" transform="scale(.26458)"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h14zm3 7 4 4h-4z" fill="#e0e0e0" fill-rule="nonzero"/></svg>
diff --git a/editor/icons/Script.svg b/editor/icons/Script.svg
index 2a47c67def..997a4b5e06 100644
--- a/editor/icons/Script.svg
+++ b/editor/icons/Script.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1a1 1 0 0 0 -1 1v10h-1v-2h-2v2a1 1 0 0 0 .5.86523 1 1 0 0 0 .5.13477v1h7a2 2 0 0 0 2-2v-8h3v-2a2 2 0 0 0 -2-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b4b4b4" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1a1 1 0 0 0 -1 1v10h-1v-2h-2v2a1 1 0 0 0 .5.86523 1 1 0 0 0 .5.13477v1h7a2 2 0 0 0 2-2v-8h3v-2a2 2 0 0 0 -2-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b3b3b3" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/></g></svg>
diff --git a/editor/icons/ScriptCreate.svg b/editor/icons/ScriptCreate.svg
index 564dcddc2e..70e13e14c4 100644
--- a/editor/icons/ScriptCreate.svg
+++ b/editor/icons/ScriptCreate.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h5 1v-1h-1v-4h2v-2h2v-3h3v-2c0-1.1046-.89543-2-2-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b4b4b4" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/><path d="m13 1049.4h2v-2h-2v-2h-2v2h-2v2h2v2h2z" fill="#5fff97" fill-rule="evenodd"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h5 1v-1h-1v-4h2v-2h2v-3h3v-2c0-1.1046-.89543-2-2-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b3b3b3" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/><path d="m13 1049.4h2v-2h-2v-2h-2v2h-2v2h2v2h2z" fill="#5fff97" fill-rule="evenodd"/></g></svg>
diff --git a/editor/icons/ScriptExtend.svg b/editor/icons/ScriptExtend.svg
index 5aa39e21a9..96291e8aa2 100644
--- a/editor/icons/ScriptExtend.svg
+++ b/editor/icons/ScriptExtend.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h7c.73866 0 1.3763-.40437 1.7227-1h-3.7227v-4h4v-5h3v-2c0-1.1046-.89543-2-2-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b4b4b4" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/><path d="m16 1048.4-3-3v2h-4v2h4v2z" fill="#68b6ff" fill-rule="evenodd"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h7c.73866 0 1.3763-.40437 1.7227-1h-3.7227v-4h4v-5h3v-2c0-1.1046-.89543-2-2-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b3b3b3" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/><path d="m16 1048.4-3-3v2h-4v2h4v2z" fill="#5fb2ff" fill-rule="evenodd"/></g></svg>
diff --git a/editor/icons/ScriptRemove.svg b/editor/icons/ScriptRemove.svg
index 9af184c946..392d38e06d 100644
--- a/editor/icons/ScriptRemove.svg
+++ b/editor/icons/ScriptRemove.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h5.6348l-1.584-1.584 1.4141-1.4141-1.4141-1.416 3.5352-3.5352 1.4141 1.4141v-.46484-3h3v-2c0-1.1046-.89543-2-2-2h-7z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b4b4b4" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/><path d="m13.414 1048.4 1.4142-1.4142-1.4142-1.4142-1.4142 1.4142-1.4142-1.4142-1.4142 1.4142 1.4142 1.4142-1.4142 1.4142 1.4142 1.4142 1.4142-1.4142 1.4142 1.4142 1.4142-1.4142z" fill="#ff5f5f" fill-rule="evenodd"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m6 1v1c-.55228 0-1 .44772-1 1v10h-1v-2h-2v2c.0002826.35698.19084.68674.5.86523.15194.088045.32439.13452.5.13477v1h5.6348l-1.584-1.584 1.4141-1.4141-1.4141-1.416 3.5352-3.5352 1.4141 1.4141v-.46484-3h3v-2c0-1.1046-.89543-2-2-2h-7z" fill="#e0e0e0" transform="translate(0 1036.4)"/><path d="m6 1c-1.1046 0-2 .89543-2 2v7h-2-1v1 2c0 1.1046.89543 2 2 2s2-.89543 2-2v-10c0-.55228.44772-1 1-1s1 .44772 1 1v1 1 1h1 4v-1h-4v-1-1c0-1.1046-.89543-2-2-2zm-4 10h2v2c0 .55228-.44772 1-1 1s-1-.44772-1-1z" fill="#b3b3b3" transform="translate(0 1036.4)"/><circle cx="3" cy="1048.4" fill="#e0e0e0"/><path d="m13.414 1048.4 1.4142-1.4142-1.4142-1.4142-1.4142 1.4142-1.4142-1.4142-1.4142 1.4142 1.4142 1.4142-1.4142 1.4142 1.4142 1.4142 1.4142-1.4142 1.4142 1.4142 1.4142-1.4142z" fill="#ff5f5f" fill-rule="evenodd"/></g></svg>
diff --git a/editor/icons/SegmentShape2D.svg b/editor/icons/SegmentShape2D.svg
index 3fcbd78625..b6763f7429 100644
--- a/editor/icons/SegmentShape2D.svg
+++ b/editor/icons/SegmentShape2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.4 12-12" style="fill:none;stroke:#68b6ff;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-width:2" transform="translate(0 -1036.4)"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m2 14 12-12" fill="none" stroke="#5fb2ff" stroke-width="2"/></svg>
diff --git a/editor/icons/SeparationRayShape2D.svg b/editor/icons/SeparationRayShape2D.svg
index aa8cee1210..6966e75bc6 100644
--- a/editor/icons/SeparationRayShape2D.svg
+++ b/editor/icons/SeparationRayShape2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a1 1 0 0 0 -1 1v9.5859l-1.293-1.293a1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l3 3a1.0001 1.0001 0 0 0 .0039062.003907 1 1 0 0 0 .050781.044921 1.0001 1.0001 0 0 0 .03125.027344 1 1 0 0 0 .048828.035156 1.0001 1.0001 0 0 0 .023438.015625 1 1 0 0 0 .076172.044922 1.0001 1.0001 0 0 0 .0058593.003906 1 1 0 0 0 .013672.007813 1.0001 1.0001 0 0 0 .078125.035156 1 1 0 0 0 .074219.025391 1.0001 1.0001 0 0 0 .025391.009766 1 1 0 0 0 .039062.009765 1.0001 1.0001 0 0 0 .068359.013672 1.0001 1.0001 0 0 0 .097656.011719 1.0001 1.0001 0 0 0 .0078125 0 1 1 0 0 0 .0625.003906 1 1 0 0 0 .015625-.001953 1.0001 1.0001 0 0 0 .083984-.003906 1 1 0 0 0 .015625-.001953 1.0001 1.0001 0 0 0 .083984-.013672 1.0001 1.0001 0 0 0 .052734-.013672 1 1 0 0 0 .058594-.015625 1.0001 1.0001 0 0 0 .078125-.029297 1 1 0 0 0 .013672-.00586 1.0001 1.0001 0 0 0 .076172-.037109 1 1 0 0 0 .013672-.007812 1.0001 1.0001 0 0 0 .072266-.044922 1 1 0 0 0 .011719-.007813 1.0001 1.0001 0 0 0 .068359-.052734 1 1 0 0 0 .011719-.009766 1.0001 1.0001 0 0 0 .050781-.046875l.0097657-.011719 2.9902-2.9883a1 1 0 0 0 0-1.4141 1 1 0 0 0 -1.4141 0l-1.293 1.293v-9.5859a1 1 0 0 0 -1-1z" fill="#68b6ff" fill-rule="evenodd"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a1 1 0 0 0 -1 1v9.5859l-1.293-1.293a1 1 0 0 0 -.7207-.29102 1 1 0 0 0 -.69336.29102 1 1 0 0 0 0 1.4141l3 3a1.0001 1.0001 0 0 0 .0039062.003907 1 1 0 0 0 .050781.044921 1.0001 1.0001 0 0 0 .03125.027344 1 1 0 0 0 .048828.035156 1.0001 1.0001 0 0 0 .023438.015625 1 1 0 0 0 .076172.044922 1.0001 1.0001 0 0 0 .0058593.003906 1 1 0 0 0 .013672.007813 1.0001 1.0001 0 0 0 .078125.035156 1 1 0 0 0 .074219.025391 1.0001 1.0001 0 0 0 .025391.009766 1 1 0 0 0 .039062.009765 1.0001 1.0001 0 0 0 .068359.013672 1.0001 1.0001 0 0 0 .097656.011719 1.0001 1.0001 0 0 0 .0078125 0 1 1 0 0 0 .0625.003906 1 1 0 0 0 .015625-.001953 1.0001 1.0001 0 0 0 .083984-.003906 1 1 0 0 0 .015625-.001953 1.0001 1.0001 0 0 0 .083984-.013672 1.0001 1.0001 0 0 0 .052734-.013672 1 1 0 0 0 .058594-.015625 1.0001 1.0001 0 0 0 .078125-.029297 1 1 0 0 0 .013672-.00586 1.0001 1.0001 0 0 0 .076172-.037109 1 1 0 0 0 .013672-.007812 1.0001 1.0001 0 0 0 .072266-.044922 1 1 0 0 0 .011719-.007813 1.0001 1.0001 0 0 0 .068359-.052734 1 1 0 0 0 .011719-.009766 1.0001 1.0001 0 0 0 .050781-.046875l.0097657-.011719 2.9902-2.9883a1 1 0 0 0 0-1.4141 1 1 0 0 0 -1.4141 0l-1.293 1.293v-9.5859a1 1 0 0 0 -1-1z" fill="#5fb2ff" fill-rule="evenodd"/></svg>
diff --git a/editor/icons/ShapeCast2D.svg b/editor/icons/ShapeCast2D.svg
index dcdba92f45..36065705b0 100644
--- a/editor/icons/ShapeCast2D.svg
+++ b/editor/icons/ShapeCast2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#a5b7f3"><path d="m7 1v9h-3l4 5 4-5h-3v-9z"/><circle cx="7.990566" cy="4.8202" r="4.009434"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#8da5f3"><path d="m7 1v9h-3l4 5 4-5h-3v-9z"/><circle cx="7.990566" cy="4.8202" r="4.009434"/></g></svg>
diff --git a/editor/icons/SphereShape3D.svg b/editor/icons/SphereShape3D.svg
index cc526abcec..6aceee5864 100644
--- a/editor/icons/SphereShape3D.svg
+++ b/editor/icons/SphereShape3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" fill="#68b6ff" r="7"/><circle cx="6" cy="5" fill="#a2d2ff" r="2"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="8" cy="8" fill="#5fb2ff" r="7"/><circle cx="6" cy="5" fill="#a2d2ff" r="2"/></svg>
diff --git a/editor/icons/StaticBody2D.svg b/editor/icons/StaticBody2D.svg
index ba61605522..359d4d858c 100644
--- a/editor/icons/StaticBody2D.svg
+++ b/editor/icons/StaticBody2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m29 1042.4h1v1h-1z" fill="#fefeff"/><path d="m3 1a2 2 0 0 0 -1.4141.58594 2 2 0 0 0 -.58594 1.4141v10a2 2 0 0 0 .58594 1.4141 2 2 0 0 0 1.4141.58594h10a2 2 0 0 0 2-2v-10a2 2 0 0 0 -2-2h-10zm0 1h10a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-10a1 1 0 0 1 1-1zm0 1v2h2v-2zm8 0v2h2v-2zm-8 8v2h2v-2zm8 0v2h2v-2z" fill="#8da5f3" fill-opacity=".98824" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 1a2 2 0 0 0 -1.4141.58594 2 2 0 0 0 -.58594 1.4141v10a2 2 0 0 0 .58594 1.4141 2 2 0 0 0 1.4141.58594h10a2 2 0 0 0 2-2v-10a2 2 0 0 0 -2-2h-10zm0 1h10a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-10a1 1 0 0 1 -1-1v-10a1 1 0 0 1 1-1zm0 1v2h2v-2zm8 0v2h2v-2zm-8 8v2h2v-2zm8 0v2h2v-2z" fill="#8da5f3" fill-opacity=".98824" transform="translate(0 1036.4)"/></g></svg>
diff --git a/editor/icons/StatusError.svg b/editor/icons/StatusError.svg
index a9639c8749..278d77d8bf 100644
--- a/editor/icons/StatusError.svg
+++ b/editor/icons/StatusError.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.866 0-7 3.134-7 7s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm-2.8281 2.7578 2.8281 2.8281 2.8281-2.8281 1.4141 1.4141-2.8281 2.8281 2.8281 2.8281-1.4141 1.4141-2.8281-2.8281-2.8281 2.8281-1.4141-1.4141 2.8281-2.8281-2.8281-2.8281 1.4141-1.4141z" fill="#ff5d5d"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.866 0-7 3.134-7 7s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm-2.8281 2.7578 2.8281 2.8281 2.8281-2.8281 1.4141 1.4141-2.8281 2.8281 2.8281 2.8281-1.4141 1.4141-2.8281-2.8281-2.8281 2.8281-1.4141-1.4141 2.8281-2.8281-2.8281-2.8281 1.4141-1.4141z" fill="#ff5f5f"/></svg>
diff --git a/editor/icons/StatusSuccess.svg b/editor/icons/StatusSuccess.svg
index 6e7988100f..d8a05fc329 100644
--- a/editor/icons/StatusSuccess.svg
+++ b/editor/icons/StatusSuccess.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.866 0-7 3.134-7 7s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm3.293 3.877 1.4141 1.4141-5.707 5.709-3.707-3.709 1.4141-1.4141 2.293 2.293z" fill="#45ff8b"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-3.866 0-7 3.134-7 7s3.134 7 7 7 7-3.134 7-7-3.134-7-7-7zm3.293 3.877 1.4141 1.4141-5.707 5.709-3.707-3.709 1.4141-1.4141 2.293 2.293z" fill="#5fff97"/></svg>
diff --git a/editor/icons/TerrainMatchCorners.svg b/editor/icons/TerrainMatchCorners.svg
index b9dfcf67d2..0d5cfe710c 100644
--- a/editor/icons/TerrainMatchCorners.svg
+++ b/editor/icons/TerrainMatchCorners.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-width="70.7093"><path d="m15 1h-6v3h3v3h3z" fill="#ffa62a"/><path d="m1 1h6v3h-2.9999996l-.0000004 3h-3.0000004z" fill="#1aab1a"/><path d="m1 15h5.9999999v-3h-3v-3h-2.9999999z" fill="#ffa62a"/><path d="m15.000001 15h-6v-3h2.999999l.000001-2.9999997h3z" fill="#1aab1a"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-width="70.7093"><path d="m15 1h-6v3h3v3h3z" fill="#ffca5f"/><path d="m1 1h6v3h-2.9999996l-.0000004 3h-3.0000004z" fill="#77ce57"/><path d="m1 15h5.9999999v-3h-3v-3h-2.9999999z" fill="#ffca5f"/><path d="m15.000001 15h-6v-3h2.999999l.000001-2.9999997h3z" fill="#77ce57"/></g></svg>
diff --git a/editor/icons/TerrainMatchCornersAndSides.svg b/editor/icons/TerrainMatchCornersAndSides.svg
index 81153005bd..a54ad8fd7c 100644
--- a/editor/icons/TerrainMatchCornersAndSides.svg
+++ b/editor/icons/TerrainMatchCornersAndSides.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1h4v3h-1l-1 1-1-1h-1z" fill="#ffa62a" stroke-width="70.7093"/><path d="m1 15h4v-3h-1v-1h-3z" fill="#1aab1a" stroke-width="70.7093"/><path d="m6 15h4v-3h-1l-1-1-1 1h-1z" fill="#ffa62a" stroke-width="99.998"/><g stroke-width="70.7093"><path d="m1 10v-4h3v1l1 1-1 1v1z" fill="#ffa62a"/><path d="m15 10v-4h-3v1l-1 1 1 1v1z" fill="#ffa62a"/><g fill="#1aab1a"><path d="m15 15h-4v-3h1v-1h3z"/><path d="m15 1h-4v3h1v1h3z"/><path d="m1 1h4.0000004v3h-1v1h-3.0000004z"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1h4v3h-1l-1 1-1-1h-1z" fill="#ffca5f" stroke-width="70.7093"/><path d="m1 15h4v-3h-1v-1h-3z" fill="#77ce57" stroke-width="70.7093"/><path d="m6 15h4v-3h-1l-1-1-1 1h-1z" fill="#ffca5f" stroke-width="99.998"/><g stroke-width="70.7093"><path d="m1 10v-4h3v1l1 1-1 1v1z" fill="#ffca5f"/><path d="m15 10v-4h-3v1l-1 1 1 1v1z" fill="#ffca5f"/><g fill="#77ce57"><path d="m15 15h-4v-3h1v-1h3z"/><path d="m15 1h-4v3h1v1h3z"/><path d="m1 1h4.0000004v3h-1v1h-3.0000004z"/></g></g></svg>
diff --git a/editor/icons/TerrainMatchSides.svg b/editor/icons/TerrainMatchSides.svg
index 1e2ec75ea7..ca3ec872fa 100644
--- a/editor/icons/TerrainMatchSides.svg
+++ b/editor/icons/TerrainMatchSides.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-width="70.7093"><path d="m1 14v-12l3 3v2l1 1-1 1v2z" fill="#1aab1a"/><path d="m15 14v-12l-3 2.7057075v2l-1 1.0000001 1 1v1.9999994z" fill="#1aab1a"/><g fill="#ffa62a"><path d="m2 15h12l-3-3h-2l-1-1-1 1h-2z"/><path d="m14 1h-12l2.9999992 3h1.9999998l1.000001.9999999 1-.9999999h1.999999z"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-width="70.7093"><path d="m1 14v-12l3 3v2l1 1-1 1v2z" fill="#77ce57"/><path d="m15 14v-12l-3 2.7057075v2l-1 1.0000001 1 1v1.9999994z" fill="#77ce57"/><g fill="#ffca5f"><path d="m2 15h12l-3-3h-2l-1-1-1 1h-2z"/><path d="m14 1h-12l2.9999992 3h1.9999998l1.000001.9999999 1-.9999999h1.999999z"/></g></g></svg>
diff --git a/editor/icons/TextEdit.svg b/editor/icons/TextEdit.svg
index 67a5145373..a749c17c91 100644
--- a/editor/icons/TextEdit.svg
+++ b/editor/icons/TextEdit.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m29 1042.4h1v1h-1z" fill="#fefeff"/><path d="m3 1c-1.1046 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm1 1v4h1v-4z" fill="#8eef97" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><path d="m3 1c-1.1046 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.8954 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10zm1 1v4h1v-4z" fill="#8eef97" transform="translate(0 1036.4)"/></g></svg>
diff --git a/editor/icons/Texture3D.svg b/editor/icons/Texture3D.svg
index 795dd62ba5..a313613b26 100644
--- a/editor/icons/Texture3D.svg
+++ b/editor/icons/Texture3D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" transform="translate(-.359546 .287637)"><path d="m2 1c-.5522847 0-1 .4477153-1 1v12c0 .552285.4477153 1 1 1h12c.552285 0 1-.447715 1-1v-12c0-.5522847-.447715-1-1-1zm1 2h10v8h-10z" fill-opacity=".99608" transform="translate(.359546 -.287637)"/><g fill-opacity=".996078" stroke-width=".203212" transform="scale(.9167105 1.0908569)"><path d="m5.8175194 8.9717502q-.2194689 0-.4633233-.032514-.2438544-.0243854-.4714519-.0731562-.2275974-.0487709-.4145524-.1056703-.1869551-.0568993-.2926253-.1056702l.2357259-1.0079315q.2113405.089413.5364797.1950835.3332677.097542.8209765.097542.5608651 0 .8209764-.2113404.2601114-.2113405.2601114-.5689936 0-.219469-.097542-.3657816-.089413-.1544415-.2519826-.2438547-.1625696-.0975418-.3901671-.1300557-.2194689-.0406424-.4714518-.0406424h-.4714519v-.9754176h.5364797q.1788266 0 .3413962-.032514.1706981-.032514.3007537-.1056703.1300557-.081285.203212-.2113404.081285-.1381842.081285-.3413962 0-.1544411-.065028-.2682398-.0650278-.1137987-.1706981-.186955-.0975417-.0731563-.2357259-.1056702-.1300557-.0406424-.2682398-.0406424-.3495247 0-.6502784.1056702-.2926253.1056703-.5364797.2601114l-.4308095-.8860043q.1300557-.0812848.3007538-.1706981.1788266-.0894133.390167-.1625696.2113405-.0731563.4470664-.1219272.2438544-.048771.5120943-.048771.4958373 0 .8534904.1219272.3657816.1137987.6015075.3332677.2357259.2113405.3495246.5039657.1137987.2844968.1137987.625893 0 .3332677-.186955.6502784-.186955.3088822-.5039657.4714518.4389379.1788266.6746638.5364797.2438544.3495246.2438544.8453619 0 .3901671-.1300557.7234347-.1300557.3251393-.406424.5689937-.2763683.235726-.7071777.3739101-.422681.1300557-1.0079316.1300557z"/><path d="m10.502445 7.817506q.08941.00813.203212.016257.121927 0 .284497 0 .951032 0 1.406227-.4795803.463323-.4795803.463323-1.3249422 0-.8860044-.438938-1.3411992-.438938-.4551949-1.38997-.4551949-.130055 0-.26824.00813-.138184 0-.260111.016257zm3.665945-1.7882655q0 .7315631-.227598 1.2761713-.227597.5446082-.650278.9022613-.414553.3576531-1.01606.5364797-.601508.1788265-1.349328.1788265-.341396 0-.796591-.032514-.4551948-.0243853-.8941328-.1137986v-5.486724q.438938-.081285.9103898-.1056702.47958-.032514.820976-.032514.723435 0 1.308686.1625696.593379.1625696 1.01606.5120943.422681.3495246.650278.8941328.227598.5446081.227598 1.3086853z"/></g></g></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" fill-rule="nonzero"><path d="m2 1c-.552 0-1 .448-1 1v12c0 .552.448 1 1 1h12c.552 0 1-.448 1-1v-12c0-.552-.448-1-1-1zm1 2h10v8h-10z"/><g fill-opacity=".99"><path d="m4.973 10.075c-.134 0-.275-.012-.424-.036-.149-.018-.293-.044-.432-.08-.14-.035-.266-.074-.381-.115-.114-.041-.203-.08-.268-.115l.216-1.1c.129.065.293.136.492.213.204.071.455.106.753.106.342 0 .593-.076.752-.23s.239-.361.239-.621c0-.159-.03-.292-.09-.399-.054-.112-.131-.201-.231-.266-.099-.071-.218-.118-.357-.142-.134-.029-.279-.044-.432-.044h-.433v-1.064h.492c.109 0 .214-.012.313-.036.104-.023.196-.062.276-.115.079-.059.141-.136.186-.23.05-.101.075-.225.075-.373 0-.112-.02-.21-.06-.292-.04-.083-.092-.151-.157-.204-.059-.054-.131-.092-.216-.116-.079-.029-.161-.044-.246-.044-.213 0-.412.038-.596.115-.178.077-.342.172-.491.284l-.395-.966c.079-.06.171-.122.275-.187.11-.065.229-.124.358-.177s.266-.098.41-.133c.149-.035.305-.053.469-.053.303 0 .564.044.783.133.223.083.407.204.551.363.144.154.251.337.321.55.069.207.104.435.104.683 0 .242-.057.479-.172.709-.114.225-.268.396-.462.515.269.13.475.325.619.585.149.254.223.561.223.922 0 .284-.039.547-.119.789-.079.237-.203.443-.372.621-.169.171-.385.307-.649.408-.258.094-.566.142-.924.142z"/><path d="m9.268 8.815c.055.006.117.012.186.018h.261c.581 0 1.011-.174 1.289-.523.284-.349.425-.831.425-1.445 0-.645-.134-1.132-.402-1.463-.269-.331-.693-.497-1.274-.497-.08 0-.162.003-.246.009-.085 0-.164.006-.239.018zm3.361-1.95c0 .532-.07.996-.209 1.392s-.338.724-.596.984c-.253.26-.564.455-.931.585-.368.13-.78.195-1.237.195-.209 0-.452-.011-.731-.035-.278-.018-.551-.059-.819-.124v-5.986c.268-.059.546-.097.834-.115.293-.023.544-.035.753-.035.442 0 .842.059 1.2.177.362.118.673.305.931.559s.457.579.596.975.209.872.209 1.428z"/></g></g></svg>
diff --git a/editor/icons/TimelineIndicator.svg b/editor/icons/TimelineIndicator.svg
index d63026b9e2..3f89206814 100644
--- a/editor/icons/TimelineIndicator.svg
+++ b/editor/icons/TimelineIndicator.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 0h10l-4 4h-2z" fill="#fefefe"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 0h10l-4 4h-2z" fill="#ffffff"/></svg>
diff --git a/editor/icons/ToolTriangle.svg b/editor/icons/ToolTriangle.svg
index 51dee03f60..a682e8a36b 100644
--- a/editor/icons/ToolTriangle.svg
+++ b/editor/icons/ToolTriangle.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-26.001 -1046.2683)"><path d="m27.695915 1056.3022s7.457627-8.0678 7.118644-7.8644 5.830509 11.7288 5.830509 11.7288z" fill="#e0e0e0"/><g fill="#4b4b4b" stroke="#e0e0e0" stroke-width=".512"><circle cx="34.662014" cy="1048.5903" r="1.607564"/><circle cx="39.933205" cy="1059.6581" r="1.607564"/><circle cx="28.17049" cy="1056.2683" r="1.607564"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-26.001 -1046.2683)"><path d="m27.695915 1056.3022s7.457627-8.0678 7.118644-7.8644 5.830509 11.7288 5.830509 11.7288z" fill="#e0e0e0"/><g fill="#414042" stroke="#e0e0e0" stroke-width=".512"><circle cx="34.662014" cy="1048.5903" r="1.607564"/><circle cx="39.933205" cy="1059.6581" r="1.607564"/><circle cx="28.17049" cy="1056.2683" r="1.607564"/></g></g></svg>
diff --git a/editor/icons/TransitionEndAutoBig.svg b/editor/icons/TransitionEndAutoBig.svg
index 22f3414d34..97774d7d6d 100644
--- a/editor/icons/TransitionEndAutoBig.svg
+++ b/editor/icons/TransitionEndAutoBig.svg
@@ -1 +1 @@
-<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#77ce57" stroke="#41562e"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" transform="matrix(1.4099529 0 0 1.4099529 -4.197589 -1462.5094)"/><rect height="14.194397" ry="1.075597" stroke-width="1.409953" width="4.325911" x="14.371336" y="3.007612"/></g></svg>
+<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#77ce57" stroke="#414042"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" transform="matrix(1.4099529 0 0 1.4099529 -4.197589 -1462.5094)"/><rect height="14.194397" ry="1.075597" stroke-width="1.409953" width="4.325911" x="14.371336" y="3.007612"/></g></svg>
diff --git a/editor/icons/TransitionEndBig.svg b/editor/icons/TransitionEndBig.svg
index 641f9c55d0..6cfcf44bf0 100644
--- a/editor/icons/TransitionEndBig.svg
+++ b/editor/icons/TransitionEndBig.svg
@@ -1 +1 @@
-<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" stroke="#424242"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" stroke-width=".999944" transform="matrix(1.4203458 0 0 1.4203458 -4.29479 -1473.1325)"/><rect height="14.299023" ry="1.083525" stroke-width="1.420266" width="4.357798" x="14.411009" y="3.186887"/></g></svg>
+<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" stroke="#414042"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" stroke-width=".999944" transform="matrix(1.4203458 0 0 1.4203458 -4.29479 -1473.1325)"/><rect height="14.299023" ry="1.083525" stroke-width="1.420266" width="4.357798" x="14.411009" y="3.186887"/></g></svg>
diff --git a/editor/icons/TransitionImmediateAutoBig.svg b/editor/icons/TransitionImmediateAutoBig.svg
index fe5e0903b5..36a49621eb 100644
--- a/editor/icons/TransitionImmediateAutoBig.svg
+++ b/editor/icons/TransitionImmediateAutoBig.svg
@@ -1 +1 @@
-<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill="#77ce57" fill-rule="evenodd" stroke="#41562e" transform="matrix(1.571031 0 0 1.571031 -2.725768 -1630.6239)"/></svg>
+<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill="#77ce57" fill-rule="evenodd" stroke="#414042" transform="matrix(1.571031 0 0 1.571031 -2.725768 -1630.6239)"/></svg>
diff --git a/editor/icons/TransitionImmediateBig.svg b/editor/icons/TransitionImmediateBig.svg
index 2365518cc3..aa79e63457 100644
--- a/editor/icons/TransitionImmediateBig.svg
+++ b/editor/icons/TransitionImmediateBig.svg
@@ -1 +1 @@
-<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill="#e0e0e0" fill-rule="evenodd" stroke="#404040" transform="matrix(1.571031 0 0 1.571031 -2.725768 -1630.6239)"/></svg>
+<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill="#e0e0e0" fill-rule="evenodd" stroke="#414042" transform="matrix(1.571031 0 0 1.571031 -2.725768 -1630.6239)"/></svg>
diff --git a/editor/icons/TransitionSyncAutoBig.svg b/editor/icons/TransitionSyncAutoBig.svg
index 27cb637667..440d4c4770 100644
--- a/editor/icons/TransitionSyncAutoBig.svg
+++ b/editor/icons/TransitionSyncAutoBig.svg
@@ -1 +1 @@
-<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#77ce57" stroke="#41562e"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" transform="matrix(1.4099529 0 0 1.4099529 2.175293 -1462.5094)"/><rect height="14.194397" ry="1.075597" stroke-width="1.409953" width="4.325911" x="1.625573" y="3.007612"/></g></svg>
+<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#77ce57" stroke="#414042"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" transform="matrix(1.4099529 0 0 1.4099529 2.175293 -1462.5094)"/><rect height="14.194397" ry="1.075597" stroke-width="1.409953" width="4.325911" x="1.625573" y="3.007612"/></g></svg>
diff --git a/editor/icons/TransitionSyncBig.svg b/editor/icons/TransitionSyncBig.svg
index 27ae519739..c6ef188e98 100644
--- a/editor/icons/TransitionSyncBig.svg
+++ b/editor/icons/TransitionSyncBig.svg
@@ -1 +1 @@
-<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" stroke="#424242"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" stroke-width=".999944" transform="matrix(1.4203458 0 0 1.4203458 1.874702 -1473.1325)"/><rect height="14.299023" ry="1.083525" stroke-width="1.420266" width="4.357798" x="1.461856" y="3.186887"/></g></svg>
+<svg height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg"><g fill="#e0e0e0" stroke="#414042"><path d="m4.9883 1039.4c-.5469.01-.98717.4511-.98828.998v8c.0001163.7986.89011 1.275 1.5547.8321l6-4c.59362-.3959.59362-1.2682 0-1.6641l-6-4c-.1678-.1111-.3652-.1689-.56641-.166z" fill-rule="evenodd" stroke-width=".999944" transform="matrix(1.4203458 0 0 1.4203458 1.874702 -1473.1325)"/><rect height="14.299023" ry="1.083525" stroke-width="1.420266" width="4.357798" x="1.461856" y="3.186887"/></g></svg>
diff --git a/editor/icons/VFlowContainer.svg b/editor/icons/VFlowContainer.svg
index 9023bf2245..ccb0bea883 100644
--- a/editor/icons/VFlowContainer.svg
+++ b/editor/icons/VFlowContainer.svg
@@ -1 +1 @@
-<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2H3zm0 2h10v10H3V3zm7.998.998c-.554 0-1 .446-1 1v4.004c0 .554.446 1 1 1s1-.446 1-1V4.998c0-.554-.446-1-1-1zm-6 .004c-.554 0-1 .446-1 1v2c0 .554.446 1 1 1s1-.446 1-1v-2c0-.554-.446-1-1-1zm3 0c-.554 0-1 .446-1 1s.446 1 1 1 1-.446 1-1-.446-1-1-1zm0 3c-.554 0-1 .446-1 1v3c0 .554.446 1 1 1s1-.446 1-1v-3c0-.554-.446-1-1-1zm-3 1.996c-.554 0-1 .446-1 1v1.004c0 .554.446 1 1 1s1-.446 1-1V9.998c0-.554-.446-1-1-1z" style="fill:#8eef97;fill-opacity:1"/></svg>
+<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.097 0-2 .903-2 2v10c0 1.097.903 2 2 2h10c1.097 0 2-.903 2-2v-10c0-1.097-.903-2-2-2zm0 2h10v10h-10zm7.998.998c-.554 0-1 .446-1 1v4.004c0 .554.446 1 1 1s1-.446 1-1v-4.004c0-.554-.446-1-1-1zm-6 .004c-.554 0-1 .446-1 1v2c0 .554.446 1 1 1s1-.446 1-1v-2c0-.554-.446-1-1-1zm3 0c-.554 0-1 .446-1 1s.446 1 1 1 1-.446 1-1-.446-1-1-1zm0 3c-.554 0-1 .446-1 1v3c0 .554.446 1 1 1s1-.446 1-1v-3c0-.554-.446-1-1-1zm-3 1.996c-.554 0-1 .446-1 1v1.004c0 .554.446 1 1 1s1-.446 1-1v-1.004c0-.554-.446-1-1-1z" fill="#8eef97" fill-rule="nonzero"/></svg>
diff --git a/editor/icons/VisualShaderGraphTextureUniform.svg b/editor/icons/VisualShaderGraphTextureUniform.svg
index ed9e084fd3..c95a72601f 100644
--- a/editor/icons/VisualShaderGraphTextureUniform.svg
+++ b/editor/icons/VisualShaderGraphTextureUniform.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 0c-1.1045695 0-2 .8954-2 2v10c0 1.1046.8954305 2 2 2h10c1.104569 0 2-.8954 2-2v-10c0-1.1046-.895431-2-2-2zm0 2h10v10h-10zm9 2-4 4-2-2-2 3h8z" fill="#eae068"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 0c-1.1045695 0-2 .8954-2 2v10c0 1.1046.8954305 2 2 2h10c1.104569 0 2-.8954 2-2v-10c0-1.1046-.895431-2-2-2zm0 2h10v10h-10zm9 2-4 4-2-2-2 3h8z" fill="#eac968"/></svg>
diff --git a/editor/icons/VisualShaderNodeColorConstant.svg b/editor/icons/VisualShaderNodeColorConstant.svg
index cbc5b3a471..d327012a1f 100644
--- a/editor/icons/VisualShaderNodeColorConstant.svg
+++ b/editor/icons/VisualShaderNodeColorConstant.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g fill-opacity=".392157" transform="translate(0 -1038.3622)"><path d="m7 1039.3622a4.0000172 4.0000172 0 0 0 -4 4 4.0000172 4.0000172 0 0 0 .03906.5195 4.0000172 4.0000172 0 0 0 -2.039062 3.4805 4.0000172 4.0000172 0 0 0 4 4 4.0000172 4.0000172 0 0 0 1.998047-.541 4.0000172 4.0000172 0 0 0 2.001953.541 4.0000172 4.0000172 0 0 0 4-4 4.0000172 4.0000172 0 0 0 -2.037109-3.4824 4.0000172 4.0000172 0 0 0 .03711-.5176 4.0000172 4.0000172 0 0 0 -4-4z" fill="#fff"/><path d="m7 1040.3622a3 3 0 0 0 -3 3 3 3 0 0 0 .210937 1.1055 3 3 0 0 0 -2.210937 2.8945 3 3 0 0 0 3 3 3 3 0 0 0 2-.7676 3 3 0 0 0 2 .7676 3 3 0 0 0 3-3 3 3 0 0 0 -2.2148438-2.8906 3 3 0 0 0 .2148438-1.1094 3 3 0 0 0 -3-3z" fill="#fff"/><circle cx="7" cy="1043.3622" fill="#f00" r="3"/><circle cx="5" cy="1047.3622" fill="#00f" r="3"/><circle cx="9" cy="1047.3622" fill="#0f0" r="3"/><circle cx="7" cy="1043.3622" fill="#f00" r="3"/><circle cx="5" cy="1047.3622" fill="#00f" r="3"/><circle cx="9" cy="1047.3622" fill="#0f0" r="3"/></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g fill-opacity=".392157" transform="translate(0 -1038.3622)"><path d="m7 1039.3622a4.0000172 4.0000172 0 0 0 -4 4 4.0000172 4.0000172 0 0 0 .03906.5195 4.0000172 4.0000172 0 0 0 -2.039062 3.4805 4.0000172 4.0000172 0 0 0 4 4 4.0000172 4.0000172 0 0 0 1.998047-.541 4.0000172 4.0000172 0 0 0 2.001953.541 4.0000172 4.0000172 0 0 0 4-4 4.0000172 4.0000172 0 0 0 -2.037109-3.4824 4.0000172 4.0000172 0 0 0 .03711-.5176 4.0000172 4.0000172 0 0 0 -4-4z" fill="#fff"/><path d="m7 1040.3622a3 3 0 0 0 -3 3 3 3 0 0 0 .210937 1.1055 3 3 0 0 0 -2.210937 2.8945 3 3 0 0 0 3 3 3 3 0 0 0 2-.7676 3 3 0 0 0 2 .7676 3 3 0 0 0 3-3 3 3 0 0 0 -2.2148438-2.8906 3 3 0 0 0 .2148438-1.1094 3 3 0 0 0 -3-3z" fill="#ffffff"/><circle cx="7" cy="1043.3622" fill="#ff0000" r="3"/><circle cx="5" cy="1047.3622" fill="#0000ff" r="3"/><circle cx="9" cy="1047.3622" fill="#00ff00" r="3"/><circle cx="7" cy="1043.3622" fill="#ff0000" r="3"/><circle cx="5" cy="1047.3622" fill="#0000ff" r="3"/><circle cx="9" cy="1047.3622" fill="#00ff00" r="3"/></g></svg>
diff --git a/editor/icons/VisualShaderNodeColorOp.svg b/editor/icons/VisualShaderNodeColorOp.svg
index 7b6cd8149b..005da8b6e1 100644
--- a/editor/icons/VisualShaderNodeColorOp.svg
+++ b/editor/icons/VisualShaderNodeColorOp.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1038.3622)"><g fill="#fff"><path d="m4 1050.3622h6v-10h-6z" fill-rule="evenodd" stroke="#fff" stroke-linejoin="round" stroke-width="2"/><path d="m1 1041.3622h2v2h-2z"/><path d="m1 1047.3622h2v2h-2z"/><path d="m11 1044.3622h2v2h-2z"/></g><g fill-opacity=".862745"><path d="m5 1041.3622h4v2h-4z" fill="#ff4646"/><path d="m5 1044.3622h4v2h-4z" fill="#46ff46"/><path d="m5 1047.3622h4v2h-4z" fill="#4646ff"/></g></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1038.3622)"><g fill="#ffffff"><path d="m4 1050.3622h6v-10h-6z" fill-rule="evenodd" stroke="#ffffff" stroke-linejoin="round" stroke-width="2"/><path d="m1 1041.3622h2v2h-2z"/><path d="m1 1047.3622h2v2h-2z"/><path d="m11 1044.3622h2v2h-2z"/></g><g fill-opacity=".862745"><path d="m5 1041.3622h4v2h-4z" fill="#ff0000"/><path d="m5 1044.3622h4v2h-4z" fill="#00ff00"/><path d="m5 1047.3622h4v2h-4z" fill="#0000ff"/></g></g></svg>
diff --git a/editor/icons/VisualShaderNodeColorUniform.svg b/editor/icons/VisualShaderNodeColorUniform.svg
index ce89b16583..db41e5eca3 100644
--- a/editor/icons/VisualShaderNodeColorUniform.svg
+++ b/editor/icons/VisualShaderNodeColorUniform.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1038.3622)"><path d="m2 1038.3622c-1.10457 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.104569 0 2-.8954 2-2v-10c0-1.1046-.895431-2-2-2z" fill="#fff"/><g fill-opacity=".392157"><path d="m7 2a3 3 0 0 0 -3 3 3 3 0 0 0 .2109375 1.1054688 3 3 0 0 0 -2.2109375 2.8945312 3 3 0 0 0 3 3 3 3 0 0 0 2-.767578 3 3 0 0 0 2 .767578 3 3 0 0 0 3-3 3 3 0 0 0 -2.2148438-2.890625 3 3 0 0 0 .2148438-1.109375 3 3 0 0 0 -3-3z" fill="#fff" transform="translate(0 1038.3622)"/><circle cx="7" cy="1043.3622" fill="#f00" r="3"/><circle cx="5" cy="1047.3622" fill="#00f" r="3"/><circle cx="9" cy="1047.3622" fill="#0f0" r="3"/><circle cx="7" cy="1043.3622" fill="#f00" r="3"/><circle cx="5" cy="1047.3622" fill="#00f" r="3"/><circle cx="9" cy="1047.3622" fill="#0f0" r="3"/></g></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1038.3622)"><path d="m2 1038.3622c-1.10457 0-2 .8954-2 2v10c0 1.1046.89543 2 2 2h10c1.104569 0 2-.8954 2-2v-10c0-1.1046-.895431-2-2-2z" fill="#fff"/><g fill-opacity=".392157"><path d="m7 2a3 3 0 0 0 -3 3 3 3 0 0 0 .2109375 1.1054688 3 3 0 0 0 -2.2109375 2.8945312 3 3 0 0 0 3 3 3 3 0 0 0 2-.767578 3 3 0 0 0 2 .767578 3 3 0 0 0 3-3 3 3 0 0 0 -2.2148438-2.890625 3 3 0 0 0 .2148438-1.109375 3 3 0 0 0 -3-3z" fill="#ffffff" transform="translate(0 1038.3622)"/><circle cx="7" cy="1043.3622" fill="#ff0000" r="3"/><circle cx="5" cy="1047.3622" fill="#0000ff" r="3"/><circle cx="9" cy="1047.3622" fill="#00ff00" r="3"/><circle cx="7" cy="1043.3622" fill="#ff0000" r="3"/><circle cx="5" cy="1047.3622" fill="#0000ff" r="3"/><circle cx="9" cy="1047.3622" fill="#00ff00" r="3"/></g></g></svg>
diff --git a/editor/icons/VisualShaderNodeCurveTexture.svg b/editor/icons/VisualShaderNodeCurveTexture.svg
index c0ee634ca4..e468acf8ca 100644
--- a/editor/icons/VisualShaderNodeCurveTexture.svg
+++ b/editor/icons/VisualShaderNodeCurveTexture.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1038.3622)"><path d="m2 1049.3622c8 0 9 0 9-9" fill="none" stroke="#f6f6f6" stroke-linecap="round" stroke-width="2"/><path d="m11 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-5 5a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#68d0ea" transform="translate(0 1038.3622)"/></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1038.3622)"><path d="m2 1049.3622c8 0 9 0 9-9" fill="none" stroke="#f9f9f9" stroke-linecap="round" stroke-width="2"/><path d="m11 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-5 5a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#5fb2ff" transform="translate(0 1038.3622)"/></g></svg>
diff --git a/editor/icons/VisualShaderNodeCurveXYZTexture.svg b/editor/icons/VisualShaderNodeCurveXYZTexture.svg
index c0ee634ca4..e468acf8ca 100644
--- a/editor/icons/VisualShaderNodeCurveXYZTexture.svg
+++ b/editor/icons/VisualShaderNodeCurveXYZTexture.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1038.3622)"><path d="m2 1049.3622c8 0 9 0 9-9" fill="none" stroke="#f6f6f6" stroke-linecap="round" stroke-width="2"/><path d="m11 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-5 5a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#68d0ea" transform="translate(0 1038.3622)"/></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1038.3622)"><path d="m2 1049.3622c8 0 9 0 9-9" fill="none" stroke="#f9f9f9" stroke-linecap="round" stroke-width="2"/><path d="m11 4a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm-5 5a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#5fb2ff" transform="translate(0 1038.3622)"/></g></svg>
diff --git a/editor/icons/VisualShaderNodeExpression.svg b/editor/icons/VisualShaderNodeExpression.svg
index 8a930d4078..710ba818b7 100644
--- a/editor/icons/VisualShaderNodeExpression.svg
+++ b/editor/icons/VisualShaderNodeExpression.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ac73f1"><path d="m4.859536 3.0412379c-2.0539867 0-3.7190721 1.6650852-3.7190721 3.719072v6.1984521h2.4793814v-2.479381h2.4793814v-2.4793803h-2.4793814v-1.2396908c0-.6846622.5550285-1.2396907 1.2396907-1.2396907h1.2396907v-2.4793813z"/><path d="m7.5889175 3.0000003 2.5000005 4.9999997-2.5000005 5h2.5000005l1.135249-2.727 1.36475 2.727h2.499999l-2.499999-5 2.499999-4.9999997h-2.499999l-1.13525 2.7269998-1.364749-2.7269998zm7.4999985 9.9999997v-6.25z"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#cf68ea"><path d="m4.859536 3.0412379c-2.0539867 0-3.7190721 1.6650852-3.7190721 3.719072v6.1984521h2.4793814v-2.479381h2.4793814v-2.4793803h-2.4793814v-1.2396908c0-.6846622.5550285-1.2396907 1.2396907-1.2396907h1.2396907v-2.4793813z"/><path d="m7.5889175 3.0000003 2.5000005 4.9999997-2.5000005 5h2.5000005l1.135249-2.727 1.36475 2.727h2.499999l-2.499999-5 2.499999-4.9999997h-2.499999l-1.13525 2.7269998-1.364749-2.7269998zm7.4999985 9.9999997v-6.25z"/></g></svg>
diff --git a/editor/icons/VisualShaderNodeInput.svg b/editor/icons/VisualShaderNodeInput.svg
index ec347100d7..0c4de2e681 100644
--- a/editor/icons/VisualShaderNodeInput.svg
+++ b/editor/icons/VisualShaderNodeInput.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><circle cx="7" cy="7" fill="#f6f6f6" r="6"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><circle cx="7" cy="7" fill="#f9f9f9" r="6"/></svg>
diff --git a/editor/icons/VisualShaderNodeTexture2DArrayUniform.svg b/editor/icons/VisualShaderNodeTexture2DArrayUniform.svg
index ed9e084fd3..c95a72601f 100644
--- a/editor/icons/VisualShaderNodeTexture2DArrayUniform.svg
+++ b/editor/icons/VisualShaderNodeTexture2DArrayUniform.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 0c-1.1045695 0-2 .8954-2 2v10c0 1.1046.8954305 2 2 2h10c1.104569 0 2-.8954 2-2v-10c0-1.1046-.895431-2-2-2zm0 2h10v10h-10zm9 2-4 4-2-2-2 3h8z" fill="#eae068"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 0c-1.1045695 0-2 .8954-2 2v10c0 1.1046.8954305 2 2 2h10c1.104569 0 2-.8954 2-2v-10c0-1.1046-.895431-2-2-2zm0 2h10v10h-10zm9 2-4 4-2-2-2 3h8z" fill="#eac968"/></svg>
diff --git a/editor/icons/VisualShaderNodeTexture3DUniform.svg b/editor/icons/VisualShaderNodeTexture3DUniform.svg
index ed9e084fd3..c95a72601f 100644
--- a/editor/icons/VisualShaderNodeTexture3DUniform.svg
+++ b/editor/icons/VisualShaderNodeTexture3DUniform.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 0c-1.1045695 0-2 .8954-2 2v10c0 1.1046.8954305 2 2 2h10c1.104569 0 2-.8954 2-2v-10c0-1.1046-.895431-2-2-2zm0 2h10v10h-10zm9 2-4 4-2-2-2 3h8z" fill="#eae068"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 0c-1.1045695 0-2 .8954-2 2v10c0 1.1046.8954305 2 2 2h10c1.104569 0 2-.8954 2-2v-10c0-1.1046-.895431-2-2-2zm0 2h10v10h-10zm9 2-4 4-2-2-2 3h8z" fill="#eac968"/></svg>
diff --git a/editor/icons/VisualShaderNodeTextureUniform.svg b/editor/icons/VisualShaderNodeTextureUniform.svg
index ed9e084fd3..c95a72601f 100644
--- a/editor/icons/VisualShaderNodeTextureUniform.svg
+++ b/editor/icons/VisualShaderNodeTextureUniform.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 0c-1.1045695 0-2 .8954-2 2v10c0 1.1046.8954305 2 2 2h10c1.104569 0 2-.8954 2-2v-10c0-1.1046-.895431-2-2-2zm0 2h10v10h-10zm9 2-4 4-2-2-2 3h8z" fill="#eae068"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 0c-1.1045695 0-2 .8954-2 2v10c0 1.1046.8954305 2 2 2h10c1.104569 0 2-.8954 2-2v-10c0-1.1046-.895431-2-2-2zm0 2h10v10h-10zm9 2-4 4-2-2-2 3h8z" fill="#eac968"/></svg>
diff --git a/editor/icons/VisualShaderNodeTextureUniformTriplanar.svg b/editor/icons/VisualShaderNodeTextureUniformTriplanar.svg
index ed9e084fd3..c95a72601f 100644
--- a/editor/icons/VisualShaderNodeTextureUniformTriplanar.svg
+++ b/editor/icons/VisualShaderNodeTextureUniformTriplanar.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 0c-1.1045695 0-2 .8954-2 2v10c0 1.1046.8954305 2 2 2h10c1.104569 0 2-.8954 2-2v-10c0-1.1046-.895431-2-2-2zm0 2h10v10h-10zm9 2-4 4-2-2-2 3h8z" fill="#eae068"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 0c-1.1045695 0-2 .8954-2 2v10c0 1.1046.8954305 2 2 2h10c1.104569 0 2-.8954 2-2v-10c0-1.1046-.895431-2-2-2zm0 2h10v10h-10zm9 2-4 4-2-2-2 3h8z" fill="#eac968"/></svg>
diff --git a/editor/icons/VisualShaderNodeTransformCompose.svg b/editor/icons/VisualShaderNodeTransformCompose.svg
index 6c7b28cda3..774f9e77b1 100644
--- a/editor/icons/VisualShaderNodeTransformCompose.svg
+++ b/editor/icons/VisualShaderNodeTransformCompose.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="1.000747" x2="13.014989" y1="1045.3622" y2="1045.3622"><stop offset="0" stop-color="#b8ea68"/><stop offset="1" stop-color="#ea686c"/></linearGradient><path d="m1.9909808 1039.3524a1.0001 1.0001 0 0 0 -.697265 1.7168l3.2929683 3.293h-2.5859373a1.0001 1.0001 0 1 0 0 2h2.5859373l-3.2929683 3.293a1.0001 1.0001 0 1 0 1.414062 1.414l4.7070313-4.707h4.5859379a1.0001 1.0001 0 1 0 0-2h-4.5859379l-4.7070313-4.707a1.0001 1.0001 0 0 0 -.716797-.3028z" fill="url(#a)" fill-rule="evenodd" transform="translate(0 -1038.3622)"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="1.000747" x2="13.014989" y1="1045.3622" y2="1045.3622"><stop offset="0" stop-color="#77ce57"/><stop offset="1" stop-color="#ea686c"/></linearGradient><path d="m1.9909808 1039.3524a1.0001 1.0001 0 0 0 -.697265 1.7168l3.2929683 3.293h-2.5859373a1.0001 1.0001 0 1 0 0 2h2.5859373l-3.2929683 3.293a1.0001 1.0001 0 1 0 1.414062 1.414l4.7070313-4.707h4.5859379a1.0001 1.0001 0 1 0 0-2h-4.5859379l-4.7070313-4.707a1.0001 1.0001 0 0 0 -.716797-.3028z" fill="url(#a)" fill-rule="evenodd" transform="translate(0 -1038.3622)"/></svg>
diff --git a/editor/icons/VisualShaderNodeTransformDecompose.svg b/editor/icons/VisualShaderNodeTransformDecompose.svg
index 276b3ea7c8..9594bcb263 100644
--- a/editor/icons/VisualShaderNodeTransformDecompose.svg
+++ b/editor/icons/VisualShaderNodeTransformDecompose.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientTransform="matrix(-1 0 0 1 13.999754 1038.3622)" gradientUnits="userSpaceOnUse" x1="1" x2="13.014242" y1="7" y2="7"><stop offset="0" stop-color="#b8ea68"/><stop offset="1" stop-color="#ea686c"/></linearGradient><path d="m12.00952 1039.3524a1.0001 1.0001 0 0 1 .697265 1.7168l-3.2929683 3.293h2.5859373a1.0001 1.0001 0 1 1 0 2h-2.5859373l3.2929683 3.293a1.0001 1.0001 0 1 1 -1.414062 1.414l-4.7070313-4.707h-4.5859377a1.0001 1.0001 0 1 1 0-2h4.5859377l4.7070313-4.707a1.0001 1.0001 0 0 1 .716797-.3028z" fill="url(#a)" fill-rule="evenodd" transform="translate(0 -1038.3622)"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientTransform="matrix(-1 0 0 1 13.999754 1038.3622)" gradientUnits="userSpaceOnUse" x1="1" x2="13.014242" y1="7" y2="7"><stop offset="0" stop-color="#77ce57"/><stop offset="1" stop-color="#ea686c"/></linearGradient><path d="m12.00952 1039.3524a1.0001 1.0001 0 0 1 .697265 1.7168l-3.2929683 3.293h2.5859373a1.0001 1.0001 0 1 1 0 2h-2.5859373l3.2929683 3.293a1.0001 1.0001 0 1 1 -1.414062 1.414l-4.7070313-4.707h-4.5859377a1.0001 1.0001 0 1 1 0-2h4.5859377l4.7070313-4.707a1.0001 1.0001 0 0 1 .716797-.3028z" fill="url(#a)" fill-rule="evenodd" transform="translate(0 -1038.3622)"/></svg>
diff --git a/editor/icons/VisualShaderNodeTransformVecMult.svg b/editor/icons/VisualShaderNodeTransformVecMult.svg
index fe133b6ffe..611f027402 100644
--- a/editor/icons/VisualShaderNodeTransformVecMult.svg
+++ b/editor/icons/VisualShaderNodeTransformVecMult.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1038.3622)"><path d="m9 1042.3622 2 6 2-6" fill="none" stroke="#b8ea68" stroke-linejoin="round" stroke-width="2"/><circle cx="7" cy="1046.3622" fill="#b8ea68" r="1"/><path d="m1 1049.3621v-7l2 3 2-3v7" fill="none" stroke="#ea686c" stroke-linejoin="round" stroke-width="2"/></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1038.3622)"><path d="m9 1042.3622 2 6 2-6" fill="none" stroke="#77ce57" stroke-linejoin="round" stroke-width="2"/><circle cx="7" cy="1046.3622" fill="#77ce57" r="1"/><path d="m1 1049.3621v-7l2 3 2-3v7" fill="none" stroke="#ea686c" stroke-linejoin="round" stroke-width="2"/></g></svg>
diff --git a/editor/icons/VisualShaderNodeVec3Uniform.svg b/editor/icons/VisualShaderNodeVec3Uniform.svg
index 6e0175230c..eed10289c0 100644
--- a/editor/icons/VisualShaderNodeVec3Uniform.svg
+++ b/editor/icons/VisualShaderNodeVec3Uniform.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 0c-1.1045695 0-2 .8954305-2 2v10c0 1.104569.8954305 2 2 2h10c1.104569 0 2-.895431 2-2v-10c0-1.1045695-.895431-2-2-2zm6 0 3 3-3 3v-2h-5v-2h5zm-3.65625 5.6289062.5136719.8574219 2.1425781 3.5703129 2.1425781-3.5703129.5136719-.8574219 1.714844 1.0292969-.513672.8574219-3.0000001 5c-.3885014.647055-1.3263424.647055-1.7148438 0l-3-5-.5136719-.8574219z" fill="#b8ea68"/><path d="m23 0v2h-5v2h5v2l3-3zm-3.65625 5.6289062-1.714844 1.0292969.513672.8574219 3 5c.388501.647056 1.326343.647056 1.714844 0l3-5 .513672-.8574219-1.714844-1.0292969-.513672.8574219-2.142578 3.5703129-2.142578-3.5703129z" fill-rule="evenodd"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 0c-1.1045695 0-2 .8954305-2 2v10c0 1.104569.8954305 2 2 2h10c1.104569 0 2-.895431 2-2v-10c0-1.1045695-.895431-2-2-2zm6 0 3 3-3 3v-2h-5v-2h5zm-3.65625 5.6289062.5136719.8574219 2.1425781 3.5703129 2.1425781-3.5703129.5136719-.8574219 1.714844 1.0292969-.513672.8574219-3.0000001 5c-.3885014.647055-1.3263424.647055-1.7148438 0l-3-5-.5136719-.8574219z" fill="#77ce57"/><path d="m23 0v2h-5v2h5v2l3-3zm-3.65625 5.6289062-1.714844 1.0292969.513672.8574219 3 5c.388501.647056 1.326343.647056 1.714844 0l3-5 .513672-.8574219-1.714844-1.0292969-.513672.8574219-2.142578 3.5703129-2.142578-3.5703129z" fill-rule="evenodd"/></svg>
diff --git a/editor/icons/VisualShaderNodeVectorCompose.svg b/editor/icons/VisualShaderNodeVectorCompose.svg
index 8e12ab2ff6..2c4c1fb8b9 100644
--- a/editor/icons/VisualShaderNodeVectorCompose.svg
+++ b/editor/icons/VisualShaderNodeVectorCompose.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="1" x2="13.014242" y1="7" y2="7"><stop offset="0" stop-color="#cf68ea"/><stop offset="1" stop-color="#b8ea68"/></linearGradient><path d="m1.9902344.99023438a1.0001 1.0001 0 0 0 -.6972656 1.71679682l3.2929687 3.2929688h-2.5859375a1.0001 1.0001 0 1 0 0 2h2.5859375l-3.2929687 3.292969a1.0001 1.0001 0 1 0 1.4140624 1.414062l4.7070313-4.707031h4.5859375a1.0001 1.0001 0 1 0 0-2h-4.5859375l-4.7070313-4.7070312a1.0001 1.0001 0 0 0 -.7167968-.30273442z" fill="url(#a)" fill-rule="evenodd"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="1" x2="13.014242" y1="7" y2="7"><stop offset="0" stop-color="#cf68ea"/><stop offset="1" stop-color="#77ce57"/></linearGradient><path d="m1.9902344.99023438a1.0001 1.0001 0 0 0 -.6972656 1.71679682l3.2929687 3.2929688h-2.5859375a1.0001 1.0001 0 1 0 0 2h2.5859375l-3.2929687 3.292969a1.0001 1.0001 0 1 0 1.4140624 1.414062l4.7070313-4.707031h4.5859375a1.0001 1.0001 0 1 0 0-2h-4.5859375l-4.7070313-4.7070312a1.0001 1.0001 0 0 0 -.7167968-.30273442z" fill="url(#a)" fill-rule="evenodd"/></svg>
diff --git a/editor/icons/VisualShaderNodeVectorDecompose.svg b/editor/icons/VisualShaderNodeVectorDecompose.svg
index 4bd2dc2138..5fb8661300 100644
--- a/editor/icons/VisualShaderNodeVectorDecompose.svg
+++ b/editor/icons/VisualShaderNodeVectorDecompose.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientTransform="matrix(-1 0 0 1 13.999754 1038.3622)" gradientUnits="userSpaceOnUse" x1="1" x2="13.014242" y1="7" y2="7"><stop offset="0" stop-color="#cf68ea"/><stop offset="1" stop-color="#b8ea68"/></linearGradient><path d="m12.00952 1039.3524a1.0001 1.0001 0 0 1 .697265 1.7168l-3.2929685 3.293h2.5859375a1.0001 1.0001 0 1 1 0 2h-2.5859375l3.2929685 3.293a1.0001 1.0001 0 1 1 -1.414062 1.414l-4.7070315-4.707h-4.5859375a1.0001 1.0001 0 1 1 0-2h4.5859375l4.7070315-4.707a1.0001 1.0001 0 0 1 .716797-.3028z" fill="url(#a)" fill-rule="evenodd" transform="translate(0 -1038.3622)"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientTransform="matrix(-1 0 0 1 13.999754 1038.3622)" gradientUnits="userSpaceOnUse" x1="1" x2="13.014242" y1="7" y2="7"><stop offset="0" stop-color="#cf68ea"/><stop offset="1" stop-color="#77ce57"/></linearGradient><path d="m12.00952 1039.3524a1.0001 1.0001 0 0 1 .697265 1.7168l-3.2929685 3.293h2.5859375a1.0001 1.0001 0 1 1 0 2h-2.5859375l3.2929685 3.293a1.0001 1.0001 0 1 1 -1.414062 1.414l-4.7070315-4.707h-4.5859375a1.0001 1.0001 0 1 1 0-2h4.5859375l4.7070315-4.707a1.0001 1.0001 0 0 1 .716797-.3028z" fill="url(#a)" fill-rule="evenodd" transform="translate(0 -1038.3622)"/></svg>
diff --git a/editor/icons/VisualShaderNodeVectorDistance.svg b/editor/icons/VisualShaderNodeVectorDistance.svg
index 74a46047bf..b7185f25fb 100644
--- a/editor/icons/VisualShaderNodeVectorDistance.svg
+++ b/editor/icons/VisualShaderNodeVectorDistance.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.3622 10-10" fill="none" stroke="#b8ea68" stroke-linecap="round" stroke-width="2" transform="translate(0 -1038.3622)"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m2 1050.3622 10-10" fill="none" stroke="#77ce57" stroke-linecap="round" stroke-width="2" transform="translate(0 -1038.3622)"/></svg>
diff --git a/editor/icons/VisualShaderNodeVectorFunc.svg b/editor/icons/VisualShaderNodeVectorFunc.svg
index dcd4cee3e4..e452bc3d49 100644
--- a/editor/icons/VisualShaderNodeVectorFunc.svg
+++ b/editor/icons/VisualShaderNodeVectorFunc.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g fill="#b8ea68" transform="translate(0 -1038.3622)"><path d="m6 1042.3622h2v4.999982h-2z"/><path d="m9.0703125 1a3 3 0 0 0 -1.5703125.4023438 3 3 0 0 0 -1.5 2.5976562h2a1 1 0 0 1 1-1 1 1 0 0 1 1 1h2a3 3 0 0 0 -1.5-2.5976562 3 3 0 0 0 -1.4296875-.4023438z" transform="translate(0 1038.3622)"/><path d="m10 1042.3622h2v1.000017h-2z"/><path d="m2 10a3 3 0 0 0 1.5 2.597656 3 3 0 0 0 3 0 3 3 0 0 0 1.5-2.597656h-2a1 1 0 0 1 -1 1 1 1 0 0 1 -1-1z" transform="translate(0 1038.3622)"/><path d="m6-1048.3622h2v1.000017h-2z" transform="scale(1 -1)"/><path d="m4 1044.3622h6v2h-6z"/></g></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><g fill="#77ce57" transform="translate(0 -1038.3622)"><path d="m6 1042.3622h2v4.999982h-2z"/><path d="m9.0703125 1a3 3 0 0 0 -1.5703125.4023438 3 3 0 0 0 -1.5 2.5976562h2a1 1 0 0 1 1-1 1 1 0 0 1 1 1h2a3 3 0 0 0 -1.5-2.5976562 3 3 0 0 0 -1.4296875-.4023438z" transform="translate(0 1038.3622)"/><path d="m10 1042.3622h2v1.000017h-2z"/><path d="m2 10a3 3 0 0 0 1.5 2.597656 3 3 0 0 0 3 0 3 3 0 0 0 1.5-2.597656h-2a1 1 0 0 1 -1 1 1 1 0 0 1 -1-1z" transform="translate(0 1038.3622)"/><path d="m6-1048.3622h2v1.000017h-2z" transform="scale(1 -1)"/><path d="m4 1044.3622h6v2h-6z"/></g></svg>
diff --git a/editor/icons/VisualShaderNodeVectorLen.svg b/editor/icons/VisualShaderNodeVectorLen.svg
index 71faffdc3f..dce4890927 100644
--- a/editor/icons/VisualShaderNodeVectorLen.svg
+++ b/editor/icons/VisualShaderNodeVectorLen.svg
@@ -1 +1 @@
-<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m8 1038.3614v2h-5v2h5v2l3-3zm-3.65625 5.6289-1.714844 1.0293.513672.8574 3 5c.388501.647 1.326343.647 1.714844 0l3-5 .513672-.8574-1.714844-1.0293-.513672.8574-2.142578 3.5703-2.142578-3.5703z" fill="#b8ea68" fill-rule="evenodd" transform="translate(0 -1038.3622)"/></svg>
+<svg height="14" viewBox="0 0 14 14" width="14" xmlns="http://www.w3.org/2000/svg"><path d="m8 1038.3614v2h-5v2h5v2l3-3zm-3.65625 5.6289-1.714844 1.0293.513672.8574 3 5c.388501.647 1.326343.647 1.714844 0l3-5 .513672-.8574-1.714844-1.0293-.513672.8574-2.142578 3.5703-2.142578-3.5703z" fill="#77ce57" fill-rule="evenodd" transform="translate(0 -1038.3622)"/></svg>
diff --git a/editor/icons/WorldBoundaryShape2D.svg b/editor/icons/WorldBoundaryShape2D.svg
index f1dbe97c6f..70defbebd8 100644
--- a/editor/icons/WorldBoundaryShape2D.svg
+++ b/editor/icons/WorldBoundaryShape2D.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke="#68b6ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"><path d="m1 1037.4 14 14" fill="#68b6ff" fill-rule="evenodd" stroke-opacity=".39216"/><g fill="none"><path d="m3 1039.4 10 10" stroke-opacity=".58824"/><path d="m5 1041.4 6 6"/></g></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke="#5fb2ff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" transform="translate(0 -1036.4)"><path d="m1 1037.4 14 14" fill="#5fb2ff" fill-rule="evenodd" stroke-opacity=".39216"/><g fill="none"><path d="m3 1039.4 10 10" stroke-opacity=".58824"/><path d="m5 1041.4 6 6"/></g></g></svg>
diff --git a/editor/import/collada.cpp b/editor/import/collada.cpp
index 2cc534d96d..b40a810763 100644
--- a/editor/import/collada.cpp
+++ b/editor/import/collada.cpp
@@ -411,8 +411,9 @@ Vector<String> Collada::_read_string_array(XMLParser &parser) {
}
Transform3D Collada::_read_transform(XMLParser &parser) {
- if (parser.is_empty())
+ if (parser.is_empty()) {
return Transform3D();
+ }
Vector<String> array;
while (parser.read() == OK) {
diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp
index 7ca61e83e7..d63366638e 100644
--- a/editor/import/resource_importer_layered_texture.cpp
+++ b/editor/import/resource_importer_layered_texture.cpp
@@ -517,7 +517,7 @@ bool ResourceImporterLayeredTexture::are_import_settings_valid(const String &p_p
String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]);
bool test = ProjectSettings::get_singleton()->get(setting_path);
if (test) {
- if (formats_imported.find(compression_formats[index]) == -1) {
+ if (!formats_imported.has(compression_formats[index])) {
valid = false;
break;
}
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index af9a2f9ebe..0fefa0f3c4 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -282,7 +282,8 @@ bool ResourceImporterScene::get_option_visibility(const String &p_path, const St
}
}
- if (p_option == "meshes/lightmap_texel_size" && int(p_options["meshes/light_baking"]) < 3) {
+ if (p_option == "meshes/lightmap_texel_size" && int(p_options["meshes/light_baking"]) != 2) {
+ // Only display the lightmap texel size import option when using the Static Lightmaps light baking mode.
return false;
}
@@ -1476,7 +1477,7 @@ void ResourceImporterScene::get_import_options(const String &p_path, List<Import
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/ensure_tangents"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/generate_lods"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "meshes/create_shadow_meshes"), true));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/light_baking", PROPERTY_HINT_ENUM, "Disabled,Static (VoxelGI/SDFGI),Static Lightmaps,Dynamic (VoxelGI only)", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "meshes/light_baking", PROPERTY_HINT_ENUM, "Disabled,Static (VoxelGI/SDFGI),Static Lightmaps (VoxelGI/SDFGI/LightmapGI),Dynamic (VoxelGI only)", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "meshes/lightmap_texel_size", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 0.1));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "skins/use_named_skins"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import"), true));
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index f21012258c..69c705ed5a 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -628,7 +628,7 @@ bool ResourceImporterTexture::are_import_settings_valid(const String &p_path) co
String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]);
bool test = ProjectSettings::get_singleton()->get(setting_path);
if (test) {
- if (formats_imported.find(compression_formats[index]) == -1) {
+ if (!formats_imported.has(compression_formats[index])) {
valid = false;
break;
}
diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp
index 419688fd9f..f809747410 100644
--- a/editor/import_dock.cpp
+++ b/editor/import_dock.cpp
@@ -447,7 +447,7 @@ static bool _find_owners(EditorFileSystemDirectory *efsd, const String &p_path)
for (int i = 0; i < efsd->get_file_count(); i++) {
Vector<String> deps = efsd->get_file_deps(i);
- if (deps.find(p_path) != -1) {
+ if (deps.has(p_path)) {
return true;
}
}
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index 348ef4ecc7..c6bde4c98a 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -147,12 +147,15 @@ void AbstractPolygon2DEditor::_menu_option(int p_option) {
void AbstractPolygon2DEditor::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ button_create->set_icon(get_theme_icon(SNAME("CurveCreate"), SNAME("EditorIcons")));
+ button_edit->set_icon(get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons")));
+ button_delete->set_icon(get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons")));
+ } break;
case NOTIFICATION_READY: {
disable_polygon_editing(false, String());
- button_create->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveCreate"), SNAME("EditorIcons")));
- button_edit->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons")));
- button_delete->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons")));
button_edit->set_pressed(true);
get_tree()->connect("node_removed", callable_mp(this, &AbstractPolygon2DEditor::_node_removed));
diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp
index c0029312a7..f9df8db419 100644
--- a/editor/plugins/animation_blend_space_2d_editor.cpp
+++ b/editor/plugins/animation_blend_space_2d_editor.cpp
@@ -180,7 +180,7 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
selected_point = -1;
for (int i = 0; i < points.size(); i++) {
- if (making_triangle.find(i) != -1) {
+ if (making_triangle.has(i)) {
continue;
}
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index b889742b19..e46c81b77e 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -898,6 +898,9 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima
}
void AnimationNodeBlendTreeEditor::_node_renamed_focus_out(Node *le, Ref<AnimationNode> p_node) {
+ if (le == nullptr) {
+ return; // The text_submitted signal triggered the graph update and freed the LineEdit.
+ }
_node_renamed(le->call("get_text"), p_node);
}
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h
index 8e63e39fd5..1e55cc8598 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.h
+++ b/editor/plugins/animation_blend_tree_editor_plugin.h
@@ -75,7 +75,7 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
String type;
Ref<Script> script;
int input_port_count;
- AddOption(const String &p_name = String(), const String &p_type = String(), bool p_input_port_count = 0) :
+ AddOption(const String &p_name = String(), const String &p_type = String(), int p_input_port_count = 0) :
name(p_name),
type(p_type),
input_port_count(p_input_port_count) {
diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp
index 94990636da..649fc53b3a 100644
--- a/editor/plugins/animation_state_machine_editor.cpp
+++ b/editor/plugins/animation_state_machine_editor.cpp
@@ -755,7 +755,7 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
//now scroll it to draw
state_machine_draw->draw_style_box(sb, nr.node);
- if (playing && (blend_from == name || current == name || travel_path.find(name) != -1)) {
+ if (playing && (blend_from == name || current == name || travel_path.has(name))) {
state_machine_draw->draw_style_box(playing_overlay, nr.node);
}
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 1aae82f66f..d496804bf2 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -882,10 +882,39 @@ void CanvasItemEditor::_selection_menu_hide() {
}
void CanvasItemEditor::_add_node_pressed(int p_result) {
- if (p_result == AddNodeOption::ADD_NODE) {
- SceneTreeDock::get_singleton()->open_add_child_dialog();
- } else if (p_result == AddNodeOption::ADD_INSTANCE) {
- SceneTreeDock::get_singleton()->open_instance_child_dialog();
+ List<Node *> nodes_to_move;
+
+ switch (p_result) {
+ case ADD_NODE: {
+ SceneTreeDock::get_singleton()->open_add_child_dialog();
+ } break;
+ case ADD_INSTANCE: {
+ SceneTreeDock::get_singleton()->open_instance_child_dialog();
+ } break;
+ case ADD_PASTE: {
+ nodes_to_move = SceneTreeDock::get_singleton()->paste_nodes();
+ [[fallthrough]];
+ }
+ case ADD_MOVE: {
+ if (p_result == ADD_MOVE) {
+ nodes_to_move = EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list();
+ }
+ if (nodes_to_move.is_empty()) {
+ return;
+ }
+
+ undo_redo->create_action(TTR("Move Node(s) to Position"));
+ for (Node *node : nodes_to_move) {
+ CanvasItem *ci = Object::cast_to<CanvasItem>(node);
+ if (ci) {
+ Transform2D xform = ci->get_global_transform_with_canvas().affine_inverse() * ci->get_transform();
+ undo_redo->add_do_method(ci, "_edit_set_position", xform.xform(node_create_position));
+ undo_redo->add_undo_method(ci, "_edit_set_position", ci->_edit_get_position());
+ }
+ }
+ undo_redo->commit_action();
+ _reset_create_position();
+ } break;
}
}
@@ -2194,10 +2223,26 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
}
if (b.is_valid() && b->is_pressed() && b->get_button_index() == MouseButton::RIGHT) {
+ add_node_menu->clear();
+ add_node_menu->add_icon_item(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), TTR("Add Node Here"), ADD_NODE);
+ add_node_menu->add_icon_item(get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), TTR("Instantiate Scene Here"), ADD_INSTANCE);
+ for (Node *node : SceneTreeDock::get_singleton()->get_node_clipboard()) {
+ if (Object::cast_to<CanvasItem>(node)) {
+ add_node_menu->add_icon_item(get_theme_icon(SNAME("ActionPaste"), SNAME("EditorIcons")), TTR("Paste Node(s) Here"), ADD_PASTE);
+ break;
+ }
+ }
+ for (Node *node : EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list()) {
+ if (Object::cast_to<CanvasItem>(node)) {
+ add_node_menu->add_icon_item(get_theme_icon(SNAME("ToolMove"), SNAME("EditorIcons")), TTR("Move Node(s) Here"), ADD_MOVE);
+ break;
+ }
+ }
+
add_node_menu->reset_size();
- add_node_menu->set_position(get_screen_transform().xform(get_local_mouse_position()));
+ add_node_menu->set_position(get_screen_transform().xform(b->get_position()));
add_node_menu->popup();
- node_create_position = transform.affine_inverse().xform((get_local_mouse_position()));
+ node_create_position = transform.affine_inverse().xform(b->get_position());
return true;
}
@@ -2462,7 +2507,7 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) {
_update_cursor();
// Grab focus
- if (!viewport->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) {
+ if (!viewport->has_focus() && (!get_viewport()->gui_get_focus_owner() || !get_viewport()->gui_get_focus_owner()->is_text_field())) {
viewport->call_deferred(SNAME("grab_focus"));
}
}
@@ -3904,7 +3949,7 @@ void CanvasItemEditor::_selection_changed() {
void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {
Array selection = editor_selection->get_selected_nodes();
- if (selection.size() != 1 || (Node *)selection[0] != p_canvas_item) {
+ if (selection.size() != 1 || Object::cast_to<Node>(selection[0]) != p_canvas_item) {
drag_type = DRAG_NONE;
// Clear the selection
@@ -5186,6 +5231,11 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
controls_vb = memnew(VBoxContainer);
controls_vb->set_begin(Point2(5, 5));
+ zoom_widget = memnew(EditorZoomWidget);
+ controls_vb->add_child(zoom_widget);
+ zoom_widget->set_anchors_and_offsets_preset(Control::PRESET_TOP_LEFT, Control::PRESET_MODE_MINSIZE, 2 * EDSCALE);
+ zoom_widget->connect("zoom_changed", callable_mp(this, &CanvasItemEditor::_update_zoom));
+
panner.instantiate();
panner->set_callbacks(callable_mp(this, &CanvasItemEditor::_scroll_callback), callable_mp(this, &CanvasItemEditor::_pan_callback), callable_mp(this, &CanvasItemEditor::_zoom_callback));
@@ -5211,11 +5261,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
viewport->add_child(controls_vb);
- zoom_widget = memnew(EditorZoomWidget);
- controls_vb->add_child(zoom_widget);
- zoom_widget->set_anchors_and_offsets_preset(Control::PRESET_TOP_LEFT, Control::PRESET_MODE_MINSIZE, 2 * EDSCALE);
- zoom_widget->connect("zoom_changed", callable_mp(this, &CanvasItemEditor::_update_zoom));
-
updating_scroll = false;
// Add some margin to the left for better aesthetics.
@@ -5548,8 +5593,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
add_node_menu = memnew(PopupMenu);
add_child(add_node_menu);
- add_node_menu->add_icon_item(SceneTreeDock::get_singleton()->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), TTR("Add Node Here"));
- add_node_menu->add_icon_item(SceneTreeDock::get_singleton()->get_theme_icon(SNAME("Instance"), SNAME("EditorIcons")), TTR("Instance Scene Here"));
add_node_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_add_node_pressed));
multiply_grid_step_shortcut = ED_SHORTCUT("canvas_item_editor/multiply_grid_step", TTR("Multiply grid step by 2"), Key::KP_MULTIPLY);
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 1e8fc0670d..9fa44bfb25 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -84,6 +84,8 @@ public:
enum AddNodeOption {
ADD_NODE,
ADD_INSTANCE,
+ ADD_PASTE,
+ ADD_MOVE,
};
private:
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 9165223948..0c0188e8d1 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -1203,7 +1203,7 @@ Transform3D Node3DEditorViewport::_compute_transform(TransformMode p_mode, const
}
void Node3DEditorViewport::_surface_mouse_enter() {
- if (!surface->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) {
+ if (!surface->has_focus() && (!get_viewport()->gui_get_focus_owner() || !get_viewport()->gui_get_focus_owner()->is_text_field())) {
surface->grab_focus();
}
}
@@ -6623,7 +6623,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
// For snapping to be performed, there must be solid geometry under at least one of the selected nodes.
// We need to check this before snapping to register the undo/redo action only if needed.
for (int i = 0; i < keys.size(); i++) {
- Node *node = keys[i];
+ Node *node = Object::cast_to<Node>(keys[i]);
Node3D *sp = Object::cast_to<Node3D>(node);
Dictionary d = snap_data[node];
Vector3 from = d["from"];
@@ -6645,7 +6645,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
// Perform snapping if at least one node can be snapped
for (int i = 0; i < keys.size(); i++) {
- Node *node = keys[i];
+ Node *node = Object::cast_to<Node>(keys[i]);
Node3D *sp = Object::cast_to<Node3D>(node);
Dictionary d = snap_data[node];
Vector3 from = d["from"];
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index c50673559c..702bc4a8ce 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -38,14 +38,13 @@
void Path2DEditor::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_READY: {
- //button_create->set_icon( get_icon("Edit","EditorIcons"));
- //button_edit->set_icon( get_icon("MovePoint","EditorIcons"));
- //set_pressed_button(button_edit);
- //button_edit->set_pressed(true);
-
- } break;
- case NOTIFICATION_PHYSICS_PROCESS: {
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ curve_edit->set_icon(get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons")));
+ curve_edit_curve->set_icon(get_theme_icon(SNAME("CurveCurve"), SNAME("EditorIcons")));
+ curve_create->set_icon(get_theme_icon(SNAME("CurveCreate"), SNAME("EditorIcons")));
+ curve_del->set_icon(get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons")));
+ curve_close->set_icon(get_theme_icon(SNAME("CurveClose"), SNAME("EditorIcons")));
} break;
}
}
@@ -532,41 +531,41 @@ Path2DEditor::Path2DEditor(EditorNode *p_editor) {
sep = memnew(VSeparator);
base_hb->add_child(sep);
+
curve_edit = memnew(Button);
curve_edit->set_flat(true);
- curve_edit->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons")));
curve_edit->set_toggle_mode(true);
curve_edit->set_focus_mode(Control::FOCUS_NONE);
curve_edit->set_tooltip(TTR("Select Points") + "\n" + TTR("Shift+Drag: Select Control Points") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Click: Add Point") + "\n" + TTR("Left Click: Split Segment (in curve)") + "\n" + TTR("Right Click: Delete Point"));
curve_edit->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected), varray(MODE_EDIT));
base_hb->add_child(curve_edit);
+
curve_edit_curve = memnew(Button);
curve_edit_curve->set_flat(true);
- curve_edit_curve->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveCurve"), SNAME("EditorIcons")));
curve_edit_curve->set_toggle_mode(true);
curve_edit_curve->set_focus_mode(Control::FOCUS_NONE);
curve_edit_curve->set_tooltip(TTR("Select Control Points (Shift+Drag)"));
curve_edit_curve->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected), varray(MODE_EDIT_CURVE));
base_hb->add_child(curve_edit_curve);
+
curve_create = memnew(Button);
curve_create->set_flat(true);
- curve_create->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveCreate"), SNAME("EditorIcons")));
curve_create->set_toggle_mode(true);
curve_create->set_focus_mode(Control::FOCUS_NONE);
curve_create->set_tooltip(TTR("Add Point (in empty space)"));
curve_create->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected), varray(MODE_CREATE));
base_hb->add_child(curve_create);
+
curve_del = memnew(Button);
curve_del->set_flat(true);
- curve_del->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons")));
curve_del->set_toggle_mode(true);
curve_del->set_focus_mode(Control::FOCUS_NONE);
curve_del->set_tooltip(TTR("Delete Point"));
curve_del->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected), varray(MODE_DELETE));
base_hb->add_child(curve_del);
+
curve_close = memnew(Button);
curve_close->set_flat(true);
- curve_close->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveClose"), SNAME("EditorIcons")));
curve_close->set_focus_mode(Control::FOCUS_NONE);
curve_close->set_tooltip(TTR("Close Curve"));
curve_close->connect("pressed", callable_mp(this, &Path2DEditor::_mode_selected), varray(ACTION_CLOSE));
diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp
index cb62dcdccc..7cc926f06c 100644
--- a/editor/plugins/path_3d_editor_plugin.cpp
+++ b/editor/plugins/path_3d_editor_plugin.cpp
@@ -539,12 +539,29 @@ void Path3DEditorPlugin::_handle_option_pressed(int p_option) {
}
}
+void Path3DEditorPlugin::_update_theme() {
+ // TODO: Split the EditorPlugin instance from the UI instance and connect this properly.
+ // See the 2D path editor for inspiration.
+ curve_edit->set_icon(Node3DEditor::get_singleton()->get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons")));
+ curve_create->set_icon(Node3DEditor::get_singleton()->get_theme_icon(SNAME("CurveCreate"), SNAME("EditorIcons")));
+ curve_del->set_icon(Node3DEditor::get_singleton()->get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons")));
+ curve_close->set_icon(Node3DEditor::get_singleton()->get_theme_icon(SNAME("CurveClose"), SNAME("EditorIcons")));
+}
+
void Path3DEditorPlugin::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- curve_create->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed), make_binds(0));
- curve_edit->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed), make_binds(1));
- curve_del->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed), make_binds(2));
- curve_close->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_close_curve));
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ curve_create->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed), make_binds(0));
+ curve_edit->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed), make_binds(1));
+ curve_del->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed), make_binds(2));
+ curve_close->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_close_curve));
+
+ _update_theme();
+ } break;
+
+ case NOTIFICATION_READY: {
+ Node3DEditor::get_singleton()->connect("theme_changed", callable_mp(this, &Path3DEditorPlugin::_update_theme));
+ } break;
}
}
@@ -567,33 +584,33 @@ Path3DEditorPlugin::Path3DEditorPlugin(EditorNode *p_node) {
sep = memnew(VSeparator);
sep->hide();
Node3DEditor::get_singleton()->add_control_to_menu_panel(sep);
+
curve_edit = memnew(Button);
curve_edit->set_flat(true);
- curve_edit->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons")));
curve_edit->set_toggle_mode(true);
curve_edit->hide();
curve_edit->set_focus_mode(Control::FOCUS_NONE);
curve_edit->set_tooltip(TTR("Select Points") + "\n" + TTR("Shift+Drag: Select Control Points") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Click: Add Point") + "\n" + TTR("Right Click: Delete Point"));
Node3DEditor::get_singleton()->add_control_to_menu_panel(curve_edit);
+
curve_create = memnew(Button);
curve_create->set_flat(true);
- curve_create->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveCreate"), SNAME("EditorIcons")));
curve_create->set_toggle_mode(true);
curve_create->hide();
curve_create->set_focus_mode(Control::FOCUS_NONE);
curve_create->set_tooltip(TTR("Add Point (in empty space)") + "\n" + TTR("Split Segment (in curve)"));
Node3DEditor::get_singleton()->add_control_to_menu_panel(curve_create);
+
curve_del = memnew(Button);
curve_del->set_flat(true);
- curve_del->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons")));
curve_del->set_toggle_mode(true);
curve_del->hide();
curve_del->set_focus_mode(Control::FOCUS_NONE);
curve_del->set_tooltip(TTR("Delete Point"));
Node3DEditor::get_singleton()->add_control_to_menu_panel(curve_del);
+
curve_close = memnew(Button);
curve_close->set_flat(true);
- curve_close->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveClose"), SNAME("EditorIcons")));
curve_close->hide();
curve_close->set_focus_mode(Control::FOCUS_NONE);
curve_close->set_tooltip(TTR("Close Curve"));
diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h
index adda648868..b877e2ae17 100644
--- a/editor/plugins/path_3d_editor_plugin.h
+++ b/editor/plugins/path_3d_editor_plugin.h
@@ -80,6 +80,8 @@ class Path3DEditorPlugin : public EditorPlugin {
Path3D *path;
+ void _update_theme();
+
void _mode_changed(int p_idx);
void _close_curve();
void _handle_option_pressed(int p_option);
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index 7a96e6eced..b116f8ff6d 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -473,7 +473,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
uv_move_current = uv_mode;
if (uv_move_current == UV_MODE_CREATE) {
if (!uv_create) {
- points_prev.resize(0);
+ points_prev.clear();
Vector2 tuv = mtx.affine_inverse().xform(snap_point(mb->get_position()));
points_prev.push_back(tuv);
uv_create_to = tuv;
@@ -682,7 +682,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
polygon_create.clear();
- } else if (polygon_create.find(closest) == -1) {
+ } else if (!polygon_create.has(closest)) {
//add temporarily if not exists
polygon_create.push_back(closest);
}
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 2fc4cda861..f1f67eeea0 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -1603,7 +1603,8 @@ void ScriptEditor::_notification(int p_what) {
members_overview->connect("item_selected", callable_mp(this, &ScriptEditor::_members_overview_selected));
help_overview->connect("item_selected", callable_mp(this, &ScriptEditor::_help_overview_selected));
- script_split->connect("dragged", callable_mp(this, &ScriptEditor::_script_split_dragged));
+ script_split->connect("dragged", callable_mp(this, &ScriptEditor::_split_dragged));
+ list_split->connect("dragged", callable_mp(this, &ScriptEditor::_split_dragged));
EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &ScriptEditor::_editor_settings_changed));
EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &ScriptEditor::_filesystem_changed));
@@ -1878,7 +1879,7 @@ void ScriptEditor::_update_members_overview() {
for (int i = 0; i < functions.size(); i++) {
String filter = filter_methods->get_text();
String name = functions[i].get_slice(":", 0);
- if (filter.is_empty() || filter.is_subsequence_ofi(name)) {
+ if (filter.is_empty() || filter.is_subsequence_ofn(name)) {
members_overview->add_item(name);
members_overview->set_item_metadata(members_overview->get_item_count() - 1, functions[i].get_slice(":", 1).to_int() - 1);
}
@@ -2128,7 +2129,7 @@ void ScriptEditor::_update_script_names() {
Vector<_ScriptEditorItemData> sedata_filtered;
for (int i = 0; i < sedata.size(); i++) {
String filter = filter_scripts->get_text();
- if (filter.is_empty() || filter.is_subsequence_ofi(sedata[i].name)) {
+ if (filter.is_empty() || filter.is_subsequence_ofn(sedata[i].name)) {
sedata_filtered.push_back(sedata[i]);
}
}
@@ -2809,7 +2810,7 @@ void ScriptEditor::_tree_changed() {
call_deferred(SNAME("_update_script_connections"));
}
-void ScriptEditor::_script_split_dragged(float) {
+void ScriptEditor::_split_dragged(float) {
_save_layout();
}
@@ -2859,7 +2860,7 @@ bool ScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data
}
if (String(d["type"]) == "script_list_element") {
- Node *node = d["script_list_element"];
+ Node *node = Object::cast_to<Node>(d["script_list_element"]);
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(node);
if (se) {
@@ -2932,7 +2933,7 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
}
if (String(d["type"]) == "script_list_element") {
- Node *node = d["script_list_element"];
+ Node *node = Object::cast_to<Node>(d["script_list_element"]);
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(node);
EditorHelp *eh = Object::cast_to<EditorHelp>(node);
@@ -3199,8 +3200,12 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
tab_container->get_child(i)->set_meta("__editor_pass", Variant());
}
- if (p_layout->has_section_key("ScriptEditor", "split_offset")) {
- script_split->set_split_offset(p_layout->get_value("ScriptEditor", "split_offset"));
+ if (p_layout->has_section_key("ScriptEditor", "script_split_offset")) {
+ script_split->set_split_offset(p_layout->get_value("ScriptEditor", "script_split_offset"));
+ }
+
+ if (p_layout->has_section_key("ScriptEditor", "list_split_offset")) {
+ list_split->set_split_offset(p_layout->get_value("ScriptEditor", "list_split_offset"));
}
// Remove any deleted editors that have been removed between launches.
@@ -3253,7 +3258,8 @@ void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) {
p_layout->set_value("ScriptEditor", "open_scripts", scripts);
p_layout->set_value("ScriptEditor", "open_help", helps);
- p_layout->set_value("ScriptEditor", "split_offset", script_split->get_split_offset());
+ p_layout->set_value("ScriptEditor", "script_split_offset", script_split->get_split_offset());
+ p_layout->set_value("ScriptEditor", "list_split_offset", list_split->get_split_offset());
// Save the cache.
script_editor_cache->save(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("script_editor_cache.cfg"));
@@ -3486,7 +3492,7 @@ void ScriptEditor::_open_script_request(const String &p_path) {
void ScriptEditor::register_syntax_highlighter(const Ref<EditorSyntaxHighlighter> &p_syntax_highlighter) {
ERR_FAIL_COND(p_syntax_highlighter.is_null());
- if (syntax_highlighters.find(p_syntax_highlighter) == -1) {
+ if (!syntax_highlighters.has(p_syntax_highlighter)) {
syntax_highlighters.push_back(p_syntax_highlighter);
}
}
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index 67a6a9da02..d754f1a378 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -418,7 +418,7 @@ class ScriptEditor : public PanelContainer {
void _tree_changed();
- void _script_split_dragged(float);
+ void _split_dragged(float);
Variant get_drag_data_fw(const Point2 &p_point, Control *p_from);
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index b765091d2b..09af73520b 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -413,12 +413,14 @@ void ScriptTextEditor::_validate_script() {
String text = te->get_text();
List<String> fnc;
- Set<int> safe_lines;
- List<ScriptLanguage::Warning> warnings;
- List<ScriptLanguage::ScriptError> errors;
+
+ warnings.clear();
+ errors.clear();
+ safe_lines.clear();
if (!script->get_language()->validate(text, script->get_path(), &fnc, &errors, &warnings, &safe_lines)) {
- String error_text = TTR("Error at ") + "(" + itos(errors[0].line) + "," + itos(errors[0].column) + "): " + errors[0].message;
+ // TRANSLATORS: Script error pointing to a line and column number.
+ String error_text = vformat(TTR("Error at (%d, %d):"), errors[0].line, errors[0].column) + " " + errors[0].message;
code_editor->set_error(error_text);
code_editor->set_error_pos(errors[0].line - 1, errors[0].column - 1);
script_is_valid = false;
@@ -437,7 +439,14 @@ void ScriptTextEditor::_validate_script() {
script_is_valid = true;
}
_update_connected_methods();
+ _update_warnings();
+ _update_errors();
+ emit_signal(SNAME("name_changed"));
+ emit_signal(SNAME("edited_script_changed"));
+}
+
+void ScriptTextEditor::_update_warnings() {
int warning_nb = warnings.size();
warnings_panel->clear();
@@ -465,7 +474,6 @@ void ScriptTextEditor::_validate_script() {
}
}
- code_editor->set_error_count(errors.size());
code_editor->set_warning_count(warning_nb);
if (has_connections_table) {
@@ -489,6 +497,10 @@ void ScriptTextEditor::_validate_script() {
warnings_panel->pop(); // Cell.
}
warnings_panel->pop(); // Table.
+}
+
+void ScriptTextEditor::_update_errors() {
+ code_editor->set_error_count(errors.size());
errors_panel->clear();
errors_panel->push_table(2);
@@ -507,6 +519,7 @@ void ScriptTextEditor::_validate_script() {
}
errors_panel->pop(); // Table
+ CodeEdit *te = code_editor->get_text_editor();
bool highlight_safe = EDITOR_DEF("text_editor/appearance/gutters/highlight_type_safe_lines", true);
bool last_is_safe = false;
for (int i = 0; i < te->get_line_count(); i++) {
@@ -536,9 +549,6 @@ void ScriptTextEditor::_validate_script() {
te->set_line_gutter_item_color(i, 1, default_line_number_color);
}
}
-
- emit_signal(SNAME("name_changed"));
- emit_signal(SNAME("edited_script_changed"));
}
void ScriptTextEditor::_update_bookmark_list() {
@@ -1323,6 +1333,11 @@ void ScriptTextEditor::_change_syntax_highlighter(int p_idx) {
void ScriptTextEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED:
+ if (is_visible_in_tree()) {
+ _update_warnings();
+ _update_errors();
+ }
+ [[fallthrough]];
case NOTIFICATION_ENTER_TREE: {
code_editor->get_text_editor()->set_gutter_width(connection_gutter, code_editor->get_text_editor()->get_line_height());
} break;
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index bc674ce964..1e2284b403 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -62,6 +62,9 @@ class ScriptTextEditor : public ScriptEditorBase {
bool editor_enabled = false;
Vector<String> functions;
+ List<ScriptLanguage::Warning> warnings;
+ List<ScriptLanguage::ScriptError> errors;
+ Set<int> safe_lines;
List<Connection> missing_connections;
@@ -154,6 +157,8 @@ protected:
void _breakpoint_toggled(int p_row);
void _validate_script(); // No longer virtual.
+ void _update_warnings();
+ void _update_errors();
void _update_bookmark_list();
void _bookmark_item_pressed(int p_idx);
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index afecada1db..4bbeb33406 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -50,6 +50,20 @@ static bool saved_treat_warning_as_errors = false;
static Map<ShaderWarning::Code, bool> saved_warnings;
static uint32_t saved_warning_flags = 0U;
+void ShaderTextEditor::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_THEME_CHANGED: {
+ if (is_visible_in_tree()) {
+ _load_theme_settings();
+ if (warnings.size() > 0 && last_compile_result == OK) {
+ warnings_panel->clear();
+ _update_warning_panel();
+ }
+ }
+ } break;
+ }
+}
+
Ref<Shader> ShaderTextEditor::get_edited_shader() const {
return shader;
}
@@ -243,9 +257,9 @@ void ShaderTextEditor::_validate_script() {
sl.enable_warning_checking(saved_warnings_enabled);
sl.set_warning_flags(saved_warning_flags);
- Error err = sl.compile(code, info);
+ last_compile_result = sl.compile(code, info);
- if (err != OK) {
+ if (last_compile_result != OK) {
String error_text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text();
set_error(error_text);
set_error_pos(sl.get_error_line() - 1, 0);
@@ -260,14 +274,14 @@ void ShaderTextEditor::_validate_script() {
set_error("");
}
- if (warnings.size() > 0 || err != OK) {
+ if (warnings.size() > 0 || last_compile_result != OK) {
warnings_panel->clear();
}
warnings.clear();
for (List<ShaderWarning>::Element *E = sl.get_warnings_ptr(); E; E = E->next()) {
warnings.push_back(E->get());
}
- if (warnings.size() > 0 && err == OK) {
+ if (warnings.size() > 0 && last_compile_result == OK) {
warnings.sort_custom<WarningsComparator>();
_update_warning_panel();
} else {
diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h
index db2d1438b3..9196ded921 100644
--- a/editor/plugins/shader_editor_plugin.h
+++ b/editor/plugins/shader_editor_plugin.h
@@ -55,11 +55,13 @@ class ShaderTextEditor : public CodeTextEditor {
RichTextLabel *warnings_panel = nullptr;
Ref<Shader> shader;
List<ShaderWarning> warnings;
+ Error last_compile_result = Error::OK;
void _check_shader_mode();
void _update_warning_panel();
protected:
+ void _notification(int p_what);
static void _bind_methods();
virtual void _load_theme_settings() override;
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index 169ce29438..5dd24983ff 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -383,7 +383,7 @@ void Skeleton3DEditor::create_physical_skeleton() {
if (!bones_infos[parent].physical_bone) {
bones_infos.write[parent].physical_bone = create_physical_bone(parent, bone_id, bones_infos);
- ur->create_action(TTR("Create physical bones"));
+ ur->create_action(TTR("Create physical bones"), UndoRedo::MERGE_ALL);
ur->add_do_method(skeleton, "add_child", bones_infos[parent].physical_bone);
ur->add_do_reference(bones_infos[parent].physical_bone);
ur->add_undo_method(skeleton, "remove_child", bones_infos[parent].physical_bone);
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index 9013eaf9d8..014fa0e7a5 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -821,7 +821,7 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) {
for (int i = 0; i < frames->get_frame_count(edited_anim); i++) {
String name;
- Ref<Texture> frame = frames->get_frame(edited_anim, i);
+ Ref<Texture2D> frame = frames->get_frame(edited_anim, i);
if (frame.is_null()) {
name = itos(i) + ": " + TTR("(empty)");
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index f95b2b40b5..aaa09237cf 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -2076,7 +2076,7 @@ void ThemeTypeDialog::_update_add_type_options(const String &p_filter) {
Vector<StringName> unique_names;
for (const StringName &E : names) {
// Filter out undesired values.
- if (!p_filter.is_subsequence_ofi(String(E))) {
+ if (!p_filter.is_subsequence_ofn(String(E))) {
continue;
}
@@ -2226,7 +2226,7 @@ void ThemeTypeEditor::_update_type_list() {
}
updating = true;
- Control *focused = get_focus_owner();
+ Control *focused = get_viewport()->gui_get_focus_owner();
if (focused) {
if (focusables.has(focused)) {
// If focus is currently on one of the internal property editors, don't update.
@@ -3469,7 +3469,7 @@ void ThemeEditor::_add_preview_tab(ThemeEditorPreview *p_preview_tab, const Stri
preview_tabs->add_tab(p_preview_name, p_icon);
preview_tabs_content->add_child(p_preview_tab);
- preview_tabs->set_tab_right_button(preview_tabs->get_tab_count() - 1, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("close"), SNAME("TabBar")));
+ preview_tabs->set_tab_button_icon(preview_tabs->get_tab_count() - 1, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("close"), SNAME("TabBar")));
p_preview_tab->connect("control_picked", callable_mp(this, &ThemeEditor::_preview_control_picked));
preview_tabs->set_current_tab(preview_tabs->get_tab_count() - 1);
@@ -3600,7 +3600,7 @@ ThemeEditor::ThemeEditor() {
preview_tabs->set_h_size_flags(SIZE_EXPAND_FILL);
preview_tabbar_hb->add_child(preview_tabs);
preview_tabs->connect("tab_changed", callable_mp(this, &ThemeEditor::_change_preview_tab));
- preview_tabs->connect("tab_rmb_clicked", callable_mp(this, &ThemeEditor::_remove_preview_tab));
+ preview_tabs->connect("tab_button_pressed", callable_mp(this, &ThemeEditor::_remove_preview_tab));
HBoxContainer *add_preview_button_hb = memnew(HBoxContainer);
preview_tabbar_hb->add_child(add_preview_button_hb);
diff --git a/editor/plugins/tiles/atlas_merging_dialog.cpp b/editor/plugins/tiles/atlas_merging_dialog.cpp
index fc4764f61e..677c9759c2 100644
--- a/editor/plugins/tiles/atlas_merging_dialog.cpp
+++ b/editor/plugins/tiles/atlas_merging_dialog.cpp
@@ -81,7 +81,7 @@ void AtlasMergingDialog::_generate_merged(Vector<Ref<TileSetAtlasSource>> p_atla
}
// Copy the properties.
- TileData *original_tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(tile_id, alternative_id));
+ TileData *original_tile_data = atlas_source->get_tile_data(tile_id, alternative_id);
List<PropertyInfo> properties;
original_tile_data->get_property_list(&properties);
for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp
index 3b9bde6b0d..35496795e0 100644
--- a/editor/plugins/tiles/tile_atlas_view.cpp
+++ b/editor/plugins/tiles/tile_atlas_view.cpp
@@ -83,7 +83,7 @@ Size2i TileAtlasView::_compute_alternative_tiles_control_size() {
Size2i texture_region_size = tile_set_atlas_source->get_tile_texture_region(tile_id).size;
for (int j = 1; j < alternatives_count; j++) {
int alternative_id = tile_set_atlas_source->get_alternative_tile_id(tile_id, j);
- bool transposed = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(tile_id, alternative_id))->get_transpose();
+ bool transposed = tile_set_atlas_source->get_tile_data(tile_id, alternative_id)->get_transpose();
line_size.x += transposed ? texture_region_size.y : texture_region_size.x;
line_size.y = MAX(line_size.y, transposed ? texture_region_size.x : texture_region_size.y);
}
@@ -345,7 +345,7 @@ void TileAtlasView::_draw_alternatives() {
int alternatives_count = tile_set_atlas_source->get_alternative_tiles_count(atlas_coords);
for (int j = 1; j < alternatives_count; j++) {
int alternative_id = tile_set_atlas_source->get_alternative_tile_id(atlas_coords, j);
- TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(atlas_coords, alternative_id));
+ TileData *tile_data = tile_set_atlas_source->get_tile_data(atlas_coords, alternative_id);
bool transposed = tile_data->get_transpose();
// Update the y to max value.
@@ -473,7 +473,7 @@ void TileAtlasView::_update_alternative_tiles_rect_cache() {
int line_height = 0;
for (int j = 1; j < alternatives_count; j++) {
int alternative_id = tile_set_atlas_source->get_alternative_tile_id(tile_id, j);
- TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(tile_id, alternative_id));
+ TileData *tile_data = tile_set_atlas_source->get_tile_data(tile_id, alternative_id);
bool transposed = tile_data->get_transpose();
current.size = transposed ? Vector2i(texture_region_size.y, texture_region_size.x) : texture_region_size;
diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp
index d5c2051f31..12003738e7 100644
--- a/editor/plugins/tiles/tile_data_editors.cpp
+++ b/editor/plugins/tiles/tile_data_editors.cpp
@@ -60,7 +60,7 @@ TileData *TileDataEditor::_get_tile_data(TileMapCell p_cell) {
if (atlas_source) {
ERR_FAIL_COND_V(!atlas_source->has_tile(p_cell.get_atlas_coords()), nullptr);
ERR_FAIL_COND_V(!atlas_source->has_alternative_tile(p_cell.get_atlas_coords(), p_cell.alternative_tile), nullptr);
- td = Object::cast_to<TileData>(atlas_source->get_tile_data(p_cell.get_atlas_coords(), p_cell.alternative_tile));
+ td = atlas_source->get_tile_data(p_cell.get_atlas_coords(), p_cell.alternative_tile);
}
return td;
@@ -713,20 +713,21 @@ void GenericTilePolygonEditor::set_multiple_polygon_mode(bool p_multiple_polygon
void GenericTilePolygonEditor::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_READY:
- button_create->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveCreate"), SNAME("EditorIcons")));
- button_edit->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons")));
- button_delete->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons")));
- button_center_view->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("CenterView"), SNAME("EditorIcons")));
- button_pixel_snap->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Snap"), SNAME("EditorIcons")));
- button_advanced_menu->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
+ case NOTIFICATION_ENTER_TREE:
+ case NOTIFICATION_THEME_CHANGED: {
+ button_create->set_icon(get_theme_icon(SNAME("CurveCreate"), SNAME("EditorIcons")));
+ button_edit->set_icon(get_theme_icon(SNAME("CurveEdit"), SNAME("EditorIcons")));
+ button_delete->set_icon(get_theme_icon(SNAME("CurveDelete"), SNAME("EditorIcons")));
+ button_center_view->set_icon(get_theme_icon(SNAME("CenterView"), SNAME("EditorIcons")));
+ button_pixel_snap->set_icon(get_theme_icon(SNAME("Snap"), SNAME("EditorIcons")));
+ button_advanced_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
PopupMenu *p = button_advanced_menu->get_popup();
p->set_item_icon(p->get_item_index(ROTATE_RIGHT), get_theme_icon(SNAME("RotateRight"), SNAME("EditorIcons")));
p->set_item_icon(p->get_item_index(ROTATE_LEFT), get_theme_icon(SNAME("RotateLeft"), SNAME("EditorIcons")));
p->set_item_icon(p->get_item_index(FLIP_HORIZONTALLY), get_theme_icon(SNAME("MirrorX"), SNAME("EditorIcons")));
p->set_item_icon(p->get_item_index(FLIP_VERTICALLY), get_theme_icon(SNAME("MirrorY"), SNAME("EditorIcons")));
- break;
+ } break;
}
}
@@ -837,7 +838,7 @@ Variant TileDataDefaultEditor::_get_painted_value() {
}
void TileDataDefaultEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile);
ERR_FAIL_COND(!tile_data);
Variant value = tile_data->get(property);
dummy_object->set(property, value);
@@ -847,13 +848,13 @@ void TileDataDefaultEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_at
}
void TileDataDefaultEditor::_set_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile, Variant p_value) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile);
ERR_FAIL_COND(!tile_data);
tile_data->set(property, p_value);
}
Variant TileDataDefaultEditor::_get_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile);
ERR_FAIL_COND_V(!tile_data, Variant());
return tile_data->get(property);
}
@@ -1269,7 +1270,7 @@ Variant TileDataOcclusionShapeEditor::_get_painted_value() {
}
void TileDataOcclusionShapeEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile);
ERR_FAIL_COND(!tile_data);
Ref<OccluderPolygon2D> occluder_polygon = tile_data->get_occluder(occlusion_layer);
@@ -1281,7 +1282,7 @@ void TileDataOcclusionShapeEditor::_set_painted_value(TileSetAtlasSource *p_tile
}
void TileDataOcclusionShapeEditor::_set_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile, Variant p_value) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile);
ERR_FAIL_COND(!tile_data);
Ref<OccluderPolygon2D> occluder_polygon = p_value;
tile_data->set_occluder(occlusion_layer, occluder_polygon);
@@ -1290,7 +1291,7 @@ void TileDataOcclusionShapeEditor::_set_value(TileSetAtlasSource *p_tile_set_atl
}
Variant TileDataOcclusionShapeEditor::_get_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile);
ERR_FAIL_COND_V(!tile_data, Variant());
return tile_data->get_occluder(occlusion_layer);
}
@@ -1412,7 +1413,7 @@ Variant TileDataCollisionEditor::_get_painted_value() {
}
void TileDataCollisionEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile);
ERR_FAIL_COND(!tile_data);
polygon_editor->clear_polygons();
@@ -1438,7 +1439,7 @@ void TileDataCollisionEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_
}
void TileDataCollisionEditor::_set_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile, Variant p_value) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile);
ERR_FAIL_COND(!tile_data);
Dictionary dict = p_value;
@@ -1457,7 +1458,7 @@ void TileDataCollisionEditor::_set_value(TileSetAtlasSource *p_tile_set_atlas_so
}
Variant TileDataCollisionEditor::_get_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile);
ERR_FAIL_COND_V(!tile_data, Variant());
Dictionary dict;
@@ -1659,7 +1660,7 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas
hovered_coords = p_tile_atlas_view->get_atlas_tile_coords_at_pos(mouse_pos);
hovered_coords = p_tile_set_atlas_source->get_tile_at_coords(hovered_coords);
if (hovered_coords != TileSetSource::INVALID_ATLAS_COORDS) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(hovered_coords, 0));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(hovered_coords, 0);
int terrain_set = tile_data->get_terrain_set();
Rect2i texture_region = p_tile_set_atlas_source->get_tile_texture_region(hovered_coords);
Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(hovered_coords, 0);
@@ -1698,7 +1699,7 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas
for (int i = 0; i < p_tile_set_atlas_source->get_tiles_count(); i++) {
Vector2i coords = p_tile_set_atlas_source->get_tile_id(i);
if (coords != hovered_coords) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0);
if (tile_data->get_terrain_set() != int(dummy_object->get("terrain_set"))) {
// Dimming
p_canvas_item->draw_set_transform_matrix(p_transform);
@@ -1772,7 +1773,7 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas
Vector2i coords = Vector2i(x, y);
coords = p_tile_set_atlas_source->get_tile_at_coords(coords);
if (coords != TileSetSource::INVALID_ATLAS_COORDS) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0);
if (tile_data->get_terrain_set() == terrain_set) {
TileMapCell cell;
cell.source_id = 0;
@@ -1833,7 +1834,7 @@ void TileDataTerrainsEditor::forward_draw_over_alternatives(TileAtlasView *p_til
hovered_coords = Vector2i(hovered.x, hovered.y);
hovered_alternative = hovered.z;
if (hovered_coords != TileSetSource::INVALID_ATLAS_COORDS) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(hovered_coords, hovered_alternative));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(hovered_coords, hovered_alternative);
int terrain_set = tile_data->get_terrain_set();
Rect2i texture_region = p_tile_atlas_view->get_alternative_tile_rect(hovered_coords, hovered_alternative);
Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(hovered_coords, hovered_alternative);
@@ -1874,7 +1875,7 @@ void TileDataTerrainsEditor::forward_draw_over_alternatives(TileAtlasView *p_til
for (int j = 1; j < p_tile_set_atlas_source->get_alternative_tiles_count(coords); j++) {
int alternative_tile = p_tile_set_atlas_source->get_alternative_tile_id(coords, j);
if (coords != hovered_coords || alternative_tile != hovered_alternative) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, alternative_tile);
if (tile_data->get_terrain_set() != int(dummy_object->get("terrain_set"))) {
// Dimming
p_canvas_item->draw_set_transform_matrix(p_transform);
@@ -1918,7 +1919,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
cell.alternative_tile = 0;
// Save the old terrain_set and terrains bits.
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0);
if (!drag_modified.has(cell)) {
Dictionary dict;
dict["terrain_set"] = tile_data->get_terrain_set();
@@ -1948,7 +1949,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
cell.set_atlas_coords(coords);
cell.alternative_tile = 0;
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0);
if (tile_data->get_terrain_set() == terrain_set) {
// Save the old terrain_set and terrains bits.
if (!drag_modified.has(cell)) {
@@ -1990,7 +1991,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
Vector2i coords = p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position());
coords = p_tile_set_atlas_source->get_tile_at_coords(coords);
if (coords != TileSetSource::INVALID_ATLAS_COORDS) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0);
int terrain_set = tile_data->get_terrain_set();
Rect2i texture_region = p_tile_set_atlas_source->get_tile_texture_region(coords);
Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, 0);
@@ -2014,7 +2015,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
coords = p_tile_set_atlas_source->get_tile_at_coords(coords);
TileData *tile_data = nullptr;
if (coords != TileSetAtlasSource::INVALID_ATLAS_COORDS) {
- tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0));
+ tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0);
}
int terrain_set = int(dummy_object->get("terrain_set"));
int terrain = int(dummy_object->get("terrain"));
@@ -2131,7 +2132,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
undo_redo->create_action(TTR("Painting Terrain Set"));
for (Set<TileMapCell>::Element *E = edited.front(); E; E = E->next()) {
Vector2i coords = E->get().get_atlas_coords();
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0);
undo_redo->add_undo_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E->get().alternative_tile), tile_data->get_terrain_set());
undo_redo->add_do_property(p_tile_set_atlas_source, vformat("%d:%d/%d/terrain_set", coords.x, coords.y, E->get().alternative_tile), drag_painted_value);
for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
@@ -2197,7 +2198,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
Vector2i coords = Vector2i(x, y);
coords = p_tile_set_atlas_source->get_tile_at_coords(coords);
if (coords != TileSetSource::INVALID_ATLAS_COORDS) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0);
if (tile_data->get_terrain_set() == terrain_set) {
TileMapCell cell;
cell.source_id = 0;
@@ -2218,7 +2219,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t
undo_redo->create_action(TTR("Painting Terrain"));
for (Set<TileMapCell>::Element *E = edited.front(); E; E = E->next()) {
Vector2i coords = E->get().get_atlas_coords();
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, 0));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, 0);
for (int i = 0; i < TileSet::CELL_NEIGHBOR_MAX; i++) {
TileSet::CellNeighbor bit = TileSet::CellNeighbor(i);
@@ -2259,7 +2260,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi
cell.source_id = 0;
cell.set_atlas_coords(coords);
cell.alternative_tile = alternative_tile;
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, alternative_tile);
if (!drag_modified.has(cell)) {
Dictionary dict;
dict["terrain_set"] = tile_data->get_terrain_set();
@@ -2291,7 +2292,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi
cell.alternative_tile = alternative_tile;
// Save the old terrain_set and terrains bits.
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, alternative_tile);
if (tile_data->get_terrain_set() == terrain_set) {
if (!drag_modified.has(cell)) {
Dictionary dict;
@@ -2333,7 +2334,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi
int alternative_tile = tile.z;
if (coords != TileSetSource::INVALID_ATLAS_COORDS) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, alternative_tile);
int terrain_set = tile_data->get_terrain_set();
Rect2i texture_region = p_tile_atlas_view->get_alternative_tile_rect(coords, alternative_tile);
Vector2i position = texture_region.get_center() + p_tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative_tile);
@@ -2360,7 +2361,7 @@ void TileDataTerrainsEditor::forward_painting_alternatives_gui_input(TileAtlasVi
Vector2i coords = Vector2i(tile.x, tile.y);
int alternative_tile = tile.z;
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(coords, alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(coords, alternative_tile);
if (terrain_set == -1 || !tile_data || tile_data->get_terrain_set() != terrain_set) {
drag_type = DRAG_TYPE_PAINT_TERRAIN_SET;
@@ -2539,7 +2540,7 @@ Variant TileDataNavigationEditor::_get_painted_value() {
}
void TileDataNavigationEditor::_set_painted_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile);
ERR_FAIL_COND(!tile_data);
Ref<NavigationPolygon> navigation_polygon = tile_data->get_navigation_polygon(navigation_layer);
@@ -2553,7 +2554,7 @@ void TileDataNavigationEditor::_set_painted_value(TileSetAtlasSource *p_tile_set
}
void TileDataNavigationEditor::_set_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile, Variant p_value) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile);
ERR_FAIL_COND(!tile_data);
Ref<NavigationPolygon> navigation_polygon = p_value;
tile_data->set_navigation_polygon(navigation_layer, navigation_polygon);
@@ -2562,7 +2563,7 @@ void TileDataNavigationEditor::_set_value(TileSetAtlasSource *p_tile_set_atlas_s
}
Variant TileDataNavigationEditor::_get_value(TileSetAtlasSource *p_tile_set_atlas_source, Vector2 p_coords, int p_alternative_tile) {
- TileData *tile_data = Object::cast_to<TileData>(p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile));
+ TileData *tile_data = p_tile_set_atlas_source->get_tile_data(p_coords, p_alternative_tile);
ERR_FAIL_COND_V(!tile_data, Variant());
return tile_data->get_navigation_polygon(navigation_layer);
}
diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp
index aa92920722..89027b174d 100644
--- a/editor/plugins/tiles/tile_map_editor.cpp
+++ b/editor/plugins/tiles/tile_map_editor.cpp
@@ -124,6 +124,10 @@ void TileMapEditorTilesPlugin::_tab_changed() {
void TileMapEditorTilesPlugin::_update_tile_set_sources_list() {
// Update the sources.
int old_current = sources_list->get_current();
+ int old_source = -1;
+ if (old_current > -1) {
+ old_source = sources_list->get_item_metadata(old_current);
+ }
sources_list->clear();
TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
@@ -136,9 +140,12 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() {
return;
}
- for (int i = 0; i < tile_set->get_source_count(); i++) {
- int source_id = tile_set->get_source_id(i);
+ if (!tile_set->has_source(old_source)) {
+ old_source = -1;
+ }
+ List<int> source_ids = TilesEditorPlugin::get_singleton()->get_sorted_sources(tile_set);
+ for (const int &source_id : source_ids) {
TileSetSource *source = *tile_set->get_source(source_id);
Ref<Texture2D> texture;
@@ -157,7 +164,7 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() {
if (texture.is_valid()) {
item_text = vformat("%s (ID: %d)", texture->get_path().get_file(), source_id);
} else {
- item_text = vformat("No Texture Atlas Source (ID: %d)", source_id);
+ item_text = vformat(TTR("No Texture Atlas Source (ID: %d)"), source_id);
}
}
}
@@ -180,20 +187,25 @@ void TileMapEditorTilesPlugin::_update_tile_set_sources_list() {
}
sources_list->add_item(item_text, texture);
- sources_list->set_item_metadata(i, source_id);
+ sources_list->set_item_metadata(sources_list->get_item_count() - 1, source_id);
}
if (sources_list->get_item_count() > 0) {
- if (old_current > 0) {
- // Keep the current selected item if needed.
- sources_list->set_current(CLAMP(old_current, 0, sources_list->get_item_count() - 1));
+ if (old_source >= 0) {
+ for (int i = 0; i < sources_list->get_item_count(); i++) {
+ if ((int)sources_list->get_item_metadata(i) == old_source) {
+ sources_list->set_current(i);
+ sources_list->ensure_current_is_visible();
+ break;
+ }
+ }
} else {
sources_list->set_current(0);
}
sources_list->emit_signal(SNAME("item_selected"), sources_list->get_current());
}
- // Synchronize
+ // Synchronize the lists.
TilesEditorPlugin::get_singleton()->set_sources_lists_current(sources_list->get_current());
}
@@ -439,6 +451,7 @@ void TileMapEditorTilesPlugin::_scenes_list_nothing_selected() {
}
void TileMapEditorTilesPlugin::_update_theme() {
+ source_sort_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Sort"), SNAME("EditorIcons")));
select_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("ToolSelect"), SNAME("EditorIcons")));
paint_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("Edit"), SNAME("EditorIcons")));
line_tool_button->set_icon(tiles_bottom_panel->get_theme_icon(SNAME("CurveLinear"), SNAME("EditorIcons")));
@@ -835,9 +848,9 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
// Fade out the border of the grid.
float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f);
- float right_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.x, (float)(drawn_grid_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f);
+ float right_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.x, (float)(drawn_grid_rect.size.x - fading), (float)(pos_in_rect.x + 1)), 0.0f, 1.0f);
float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f);
- float bottom_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.y, (float)(drawn_grid_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f);
+ float bottom_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.y, (float)(drawn_grid_rect.size.y - fading), (float)(pos_in_rect.y + 1)), 0.0f, 1.0f);
float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f);
Transform2D tile_xform;
@@ -864,7 +877,7 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
if (atlas_source) {
// Get tile data.
- TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(E.value.get_atlas_coords(), E.value.alternative_tile));
+ TileData *tile_data = atlas_source->get_tile_data(E.value.get_atlas_coords(), E.value.alternative_tile);
// Compute the offset
Rect2i source_rect = atlas_source->get_tile_texture_region(E.value.get_atlas_coords());
@@ -936,7 +949,7 @@ TileMapCell TileMapEditorTilesPlugin::_pick_random_tile(Ref<TileMapPattern> p_pa
TileSetSource *source = *tile_set->get_source(source_id);
TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
if (atlas_source) {
- TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(atlas_coords, alternative_tile));
+ TileData *tile_data = atlas_source->get_tile_data(atlas_coords, alternative_tile);
ERR_FAIL_COND_V(!tile_data, TileMapCell());
sum += tile_data->get_probability();
} else {
@@ -955,7 +968,7 @@ TileMapCell TileMapEditorTilesPlugin::_pick_random_tile(Ref<TileMapPattern> p_pa
TileSetSource *source = *tile_set->get_source(source_id);
TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
if (atlas_source) {
- current += Object::cast_to<TileData>(atlas_source->get_tile_data(atlas_coords, alternative_tile))->get_probability();
+ current += atlas_source->get_tile_data(atlas_coords, alternative_tile)->get_probability();
} else {
current += 1.0;
}
@@ -1950,6 +1963,14 @@ void TileMapEditorTilesPlugin::edit(ObjectID p_tile_map_id, int p_tile_map_layer
tile_map_layer = p_tile_map_layer;
}
+void TileMapEditorTilesPlugin::_set_source_sort(int p_sort) {
+ for (int i = 0; i != TilesEditorPlugin::SOURCE_SORT_MAX; i++) {
+ source_sort_button->get_popup()->set_item_checked(i, (i == (int)p_sort));
+ }
+ TilesEditorPlugin::get_singleton()->set_sorting_option(p_sort);
+ _update_tile_set_sources_list();
+}
+
void TileMapEditorTilesPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("_scene_thumbnail_done"), &TileMapEditorTilesPlugin::_scene_thumbnail_done);
ClassDB::bind_method(D_METHOD("_set_tile_map_selection", "selection"), &TileMapEditorTilesPlugin::_set_tile_map_selection);
@@ -2106,17 +2127,44 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
atlas_sources_split_container->set_v_size_flags(Control::SIZE_EXPAND_FILL);
tiles_bottom_panel->add_child(atlas_sources_split_container);
+ VBoxContainer *split_container_left_side = memnew(VBoxContainer);
+ split_container_left_side->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ split_container_left_side->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ split_container_left_side->set_stretch_ratio(0.25);
+ split_container_left_side->set_custom_minimum_size(Size2i(70, 0) * EDSCALE);
+ atlas_sources_split_container->add_child(split_container_left_side);
+
+ HBoxContainer *sources_bottom_actions = memnew(HBoxContainer);
+ sources_bottom_actions->set_alignment(HBoxContainer::ALIGNMENT_END);
+
+ source_sort_button = memnew(MenuButton);
+ source_sort_button->set_flat(true);
+ source_sort_button->set_tooltip(TTR("Sort sources"));
+
+ PopupMenu *p = source_sort_button->get_popup();
+ p->connect("id_pressed", callable_mp(this, &TileMapEditorTilesPlugin::_set_source_sort));
+ p->add_radio_check_item(TTR("Sort by ID (Ascending)"), TilesEditorPlugin::SOURCE_SORT_ID);
+ p->add_radio_check_item(TTR("Sort by ID (Descending)"), TilesEditorPlugin::SOURCE_SORT_ID_REVERSE);
+ p->add_radio_check_item(TTR("Sort by Name (Ascending)"), TilesEditorPlugin::SOURCE_SORT_NAME);
+ p->add_radio_check_item(TTR("Sort by Name (Descending)"), TilesEditorPlugin::SOURCE_SORT_NAME_REVERSE);
+ p->set_item_checked(TilesEditorPlugin::SOURCE_SORT_ID, true);
+ sources_bottom_actions->add_child(source_sort_button);
+
sources_list = memnew(ItemList);
sources_list->set_fixed_icon_size(Size2i(60, 60) * EDSCALE);
sources_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ sources_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
sources_list->set_stretch_ratio(0.25);
sources_list->set_custom_minimum_size(Size2i(70, 0) * EDSCALE);
sources_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST);
sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_fix_selected_and_hovered).unbind(1));
sources_list->connect("item_selected", callable_mp(this, &TileMapEditorTilesPlugin::_update_source_display).unbind(1));
sources_list->connect("item_selected", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::set_sources_lists_current));
- sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list), varray(sources_list));
- atlas_sources_split_container->add_child(sources_list);
+ sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list), varray(sources_list, source_sort_button));
+ sources_list->add_user_signal(MethodInfo("sort_request"));
+ sources_list->connect("sort_request", callable_mp(this, &TileMapEditorTilesPlugin::_update_tile_set_sources_list));
+ split_container_left_side->add_child(sources_list);
+ split_container_left_side->add_child(sources_bottom_actions);
// Tile atlas source.
tile_atlas_view = memnew(TileAtlasView);
@@ -2427,7 +2475,7 @@ Set<Vector2i> TileMapEditorTerrainsPlugin::_get_cells_for_bucket_fill(Vector2i p
Ref<TileSetSource> source = tile_set->get_source(source_cell.source_id);
Ref<TileSetAtlasSource> atlas_source = source;
if (atlas_source.is_valid()) {
- tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(source_cell.get_atlas_coords(), source_cell.alternative_tile));
+ tile_data = atlas_source->get_tile_data(source_cell.get_atlas_coords(), source_cell.alternative_tile);
}
if (!tile_data) {
return Set<Vector2i>();
@@ -2458,7 +2506,7 @@ Set<Vector2i> TileMapEditorTerrainsPlugin::_get_cells_for_bucket_fill(Vector2i p
Ref<TileSetSource> source = tile_set->get_source(tile_map->get_cell_source_id(tile_map_layer, coords));
Ref<TileSetAtlasSource> atlas_source = source;
if (atlas_source.is_valid()) {
- tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(tile_map->get_cell_atlas_coords(tile_map_layer, coords), tile_map->get_cell_alternative_tile(tile_map_layer, coords)));
+ tile_data = atlas_source->get_tile_data(tile_map->get_cell_atlas_coords(tile_map_layer, coords), tile_map->get_cell_alternative_tile(tile_map_layer, coords));
}
if (tile_data) {
candidate_pattern = tile_data->get_terrains_pattern();
@@ -2503,7 +2551,7 @@ Set<Vector2i> TileMapEditorTerrainsPlugin::_get_cells_for_bucket_fill(Vector2i p
Ref<TileSetSource> source = tile_set->get_source(tile_map->get_cell_source_id(tile_map_layer, coords));
Ref<TileSetAtlasSource> atlas_source = source;
if (atlas_source.is_valid()) {
- tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(tile_map->get_cell_atlas_coords(tile_map_layer, coords), tile_map->get_cell_alternative_tile(tile_map_layer, coords)));
+ tile_data = atlas_source->get_tile_data(tile_map->get_cell_atlas_coords(tile_map_layer, coords), tile_map->get_cell_alternative_tile(tile_map_layer, coords));
}
if (tile_data) {
candidate_pattern = tile_data->get_terrains_pattern();
@@ -2569,7 +2617,7 @@ void TileMapEditorTerrainsPlugin::_stop_dragging() {
Ref<TileSetSource> source = tile_set->get_source(cell.source_id);
Ref<TileSetAtlasSource> atlas_source = source;
if (atlas_source.is_valid()) {
- tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(cell.get_atlas_coords(), cell.alternative_tile));
+ tile_data = atlas_source->get_tile_data(cell.get_atlas_coords(), cell.alternative_tile);
}
if (tile_data) {
@@ -2948,9 +2996,9 @@ void TileMapEditorTerrainsPlugin::forward_canvas_draw_over_viewport(Control *p_o
// Fade out the border of the grid.
float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f);
- float right_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.x, (float)(drawn_grid_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f);
+ float right_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.x, (float)(drawn_grid_rect.size.x - fading), (float)(pos_in_rect.x + 1)), 0.0f, 1.0f);
float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f);
- float bottom_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.y, (float)(drawn_grid_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f);
+ float bottom_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.y, (float)(drawn_grid_rect.size.y - fading), (float)(pos_in_rect.y + 1)), 0.0f, 1.0f);
float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f);
Transform2D tile_xform;
@@ -3010,7 +3058,7 @@ void TileMapEditorTerrainsPlugin::_update_terrains_cache() {
for (int alternative_index = 0; alternative_index < source->get_alternative_tiles_count(tile_id); alternative_index++) {
int alternative_id = source->get_alternative_tile_id(tile_id, alternative_index);
- TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(tile_id, alternative_id));
+ TileData *tile_data = atlas_source->get_tile_data(tile_id, alternative_id);
int terrain_set = tile_data->get_terrain_set();
if (terrain_set >= 0) {
ERR_FAIL_INDEX(terrain_set, (int)per_terrain_terrains_patterns.size());
@@ -3138,7 +3186,7 @@ void TileMapEditorTerrainsPlugin::_update_tiles_list() {
Ref<TileSetAtlasSource> atlas_source = source;
if (atlas_source.is_valid()) {
- TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(cell.get_atlas_coords(), cell.alternative_tile));
+ TileData *tile_data = atlas_source->get_tile_data(cell.get_atlas_coords(), cell.alternative_tile);
if (tile_data->get_probability() > max_probability) {
icon = atlas_source->get_texture();
region = atlas_source->get_tile_texture_region(cell.get_atlas_coords());
@@ -3833,9 +3881,9 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
// Fade out the border of the grid.
float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f);
- float right_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.x, (float)(displayed_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f);
+ float right_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.x, (float)(displayed_rect.size.x - fading), (float)(pos_in_rect.x + 1)), 0.0f, 1.0f);
float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f);
- float bottom_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.y, (float)(displayed_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f);
+ float bottom_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.y, (float)(displayed_rect.size.y - fading), (float)(pos_in_rect.y + 1)), 0.0f, 1.0f);
float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f);
Transform2D tile_xform;
diff --git a/editor/plugins/tiles/tile_map_editor.h b/editor/plugins/tiles/tile_map_editor.h
index b1bee03211..6fa0d01612 100644
--- a/editor/plugins/tiles/tile_map_editor.h
+++ b/editor/plugins/tiles/tile_map_editor.h
@@ -145,6 +145,7 @@ private:
Label *invalid_source_label;
ItemList *sources_list;
+ MenuButton *source_sort_button;
Ref<Texture2D> missing_atlas_texture_icon;
void _update_tile_set_sources_list();
@@ -170,6 +171,7 @@ private:
void _tile_alternatives_control_gui_input(const Ref<InputEvent> &p_event);
void _update_atlas_view();
+ void _set_source_sort(int p_sort);
// Scenes collection sources.
ItemList *scene_tiles_list;
diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
index c4cc9745ee..e708b83440 100644
--- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
+++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp
@@ -274,7 +274,7 @@ bool TileSetAtlasSourceEditor::AtlasTileProxyObject::_set(const StringName &p_na
const int &alternative = E->get().alternative;
bool valid = false;
- TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(coords, alternative));
+ TileData *tile_data = tile_set_atlas_source->get_tile_data(coords, alternative);
ERR_FAIL_COND_V(!tile_data, false);
tile_data->set(p_name, p_value, &valid);
@@ -359,7 +359,7 @@ bool TileSetAtlasSourceEditor::AtlasTileProxyObject::_get(const StringName &p_na
const Vector2i &coords = E->get().tile;
const int &alternative = E->get().alternative;
- TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(coords, alternative));
+ TileData *tile_data = tile_set_atlas_source->get_tile_data(coords, alternative);
ERR_FAIL_COND_V(!tile_data, false);
bool valid = false;
@@ -432,7 +432,7 @@ void TileSetAtlasSourceEditor::AtlasTileProxyObject::_get_property_list(List<Pro
const Vector2i &coords = E->get().tile;
const int &alternative = E->get().alternative;
- TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(coords, alternative));
+ TileData *tile_data = tile_set_atlas_source->get_tile_data(coords, alternative);
ERR_FAIL_COND(!tile_data);
List<PropertyInfo> list;
@@ -486,7 +486,7 @@ void TileSetAtlasSourceEditor::AtlasTileProxyObject::edit(TileSetAtlasSource *p_
const int &alternative = E->get().alternative;
if (tile_set_atlas_source && tile_set_atlas_source->has_tile(coords) && tile_set_atlas_source->has_alternative_tile(coords, alternative)) {
- TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(coords, alternative));
+ TileData *tile_data = tile_set_atlas_source->get_tile_data(coords, alternative);
if (tile_data->is_connected(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed))) {
tile_data->disconnect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed));
}
@@ -502,7 +502,7 @@ void TileSetAtlasSourceEditor::AtlasTileProxyObject::edit(TileSetAtlasSource *p_
const int &alternative = E->get().alternative;
if (tile_set_atlas_source->has_tile(coords) && tile_set_atlas_source->has_alternative_tile(coords, alternative)) {
- TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(coords, alternative));
+ TileData *tile_data = tile_set_atlas_source->get_tile_data(coords, alternative);
if (!tile_data->is_connected(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed))) {
tile_data->connect(CoreStringNames::get_singleton()->property_list_changed, callable_mp((Object *)this, &Object::notify_property_list_changed));
}
@@ -2609,7 +2609,7 @@ void EditorPropertyTilePolygon::update_property() {
// Set the background
Vector2i coords = atlas_tile_proxy_object->get_edited_tiles().front()->get().tile;
int alternative = atlas_tile_proxy_object->get_edited_tiles().front()->get().alternative;
- TileData *tile_data = Object::cast_to<TileData>(tile_set_atlas_source->get_tile_data(coords, alternative));
+ TileData *tile_data = tile_set_atlas_source->get_tile_data(coords, alternative);
generic_tile_polygon_editor->set_background(tile_set_atlas_source->get_texture(), tile_set_atlas_source->get_tile_texture_region(coords), tile_set_atlas_source->get_tile_effective_texture_offset(coords, alternative), tile_data->get_flip_h(), tile_data->get_flip_v(), tile_data->get_transpose(), tile_data->get_modulate());
// Reset the polygons.
diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp
index ef8d423724..be261927ee 100644
--- a/editor/plugins/tiles/tile_set_editor.cpp
+++ b/editor/plugins/tiles/tile_set_editor.cpp
@@ -137,9 +137,8 @@ void TileSetEditor::_update_sources_list(int force_selected_id) {
sources_list->clear();
// Update the atlas sources.
- for (int i = 0; i < tile_set->get_source_count(); i++) {
- int source_id = tile_set->get_source_id(i);
-
+ List<int> source_ids = TilesEditorPlugin::get_singleton()->get_sorted_sources(tile_set);
+ for (const int &source_id : source_ids) {
TileSetSource *source = *tile_set->get_source(source_id);
Ref<Texture2D> texture;
@@ -156,9 +155,9 @@ void TileSetEditor::_update_sources_list(int force_selected_id) {
texture = atlas_source->get_texture();
if (item_text.is_empty()) {
if (texture.is_valid()) {
- item_text = vformat("%s (ID:%d)", texture->get_path().get_file(), source_id);
+ item_text = vformat("%s (ID: %d)", texture->get_path().get_file(), source_id);
} else {
- item_text = vformat(TTR("No Texture Atlas Source (ID:%d)"), source_id);
+ item_text = vformat(TTR("No Texture Atlas Source (ID: %d)"), source_id);
}
}
}
@@ -168,20 +167,20 @@ void TileSetEditor::_update_sources_list(int force_selected_id) {
if (scene_collection_source) {
texture = get_theme_icon(SNAME("PackedScene"), SNAME("EditorIcons"));
if (item_text.is_empty()) {
- item_text = vformat(TTR("Scene Collection Source (ID:%d)"), source_id);
+ item_text = vformat(TTR("Scene Collection Source (ID: %d)"), source_id);
}
}
// Use default if not valid.
if (item_text.is_empty()) {
- item_text = vformat(TTR("Unknown Type Source (ID:%d)"), source_id);
+ item_text = vformat(TTR("Unknown Type Source (ID: %d)"), source_id);
}
if (!texture.is_valid()) {
texture = missing_texture_texture;
}
sources_list->add_item(item_text, texture);
- sources_list->set_item_metadata(i, source_id);
+ sources_list->set_item_metadata(sources_list->get_item_count() - 1, source_id);
}
// Set again the current selected item if needed.
@@ -189,6 +188,7 @@ void TileSetEditor::_update_sources_list(int force_selected_id) {
for (int i = 0; i < sources_list->get_item_count(); i++) {
if ((int)sources_list->get_item_metadata(i) == to_select) {
sources_list->set_current(i);
+ sources_list->ensure_current_is_visible();
if (old_selected != to_select) {
sources_list->emit_signal(SNAME("item_selected"), sources_list->get_current());
}
@@ -312,12 +312,29 @@ void TileSetEditor::_sources_advanced_menu_id_pressed(int p_id_pressed) {
}
}
+void TileSetEditor::_set_source_sort(int p_sort) {
+ TilesEditorPlugin::get_singleton()->set_sorting_option(p_sort);
+ for (int i = 0; i != TilesEditorPlugin::SOURCE_SORT_MAX; i++) {
+ source_sort_button->get_popup()->set_item_checked(i, (i == (int)p_sort));
+ }
+
+ int old_selected = TileSet::INVALID_SOURCE;
+ if (sources_list->get_current() >= 0) {
+ int source_id = sources_list->get_item_metadata(sources_list->get_current());
+ if (tile_set->has_source(source_id)) {
+ old_selected = source_id;
+ }
+ }
+ _update_sources_list(old_selected);
+}
+
void TileSetEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED:
sources_delete_button->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
sources_add_button->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ source_sort_button->set_icon(get_theme_icon(SNAME("Sort"), SNAME("EditorIcons")));
sources_advanced_menu_button->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons")));
missing_texture_texture = get_theme_icon(SNAME("TileSet"), SNAME("EditorIcons"));
break;
@@ -465,7 +482,7 @@ void TileSetEditor::_move_tile_set_array_element(Object *p_undo_redo, Object *p_
Vector2i tile_id = tas->get_tile_id(j);
for (int k = 0; k < tas->get_alternative_tiles_count(tile_id); k++) {
int alternative_id = tas->get_alternative_tile_id(tile_id, k);
- TileData *tile_data = Object::cast_to<TileData>(tas->get_tile_data(tile_id, alternative_id));
+ TileData *tile_data = tas->get_tile_data(tile_id, alternative_id);
ERR_FAIL_COND(!tile_data);
// Actually saving stuff.
@@ -584,7 +601,7 @@ void TileSetEditor::_undo_redo_inspector_callback(Object *p_undo_redo, Object *p
Vector2i tile_id = tas->get_tile_id(j);
for (int k = 0; k < tas->get_alternative_tiles_count(tile_id); k++) {
int alternative_id = tas->get_alternative_tile_id(tile_id, k);
- TileData *tile_data = Object::cast_to<TileData>(tas->get_tile_data(tile_id, alternative_id));
+ TileData *tile_data = tas->get_tile_data(tile_id, alternative_id);
ERR_FAIL_COND(!tile_data);
if (components.size() == 2 && components[0].begins_with("terrain_set_") && components[0].trim_prefix("terrain_set_").is_valid_int() && components[1] == "mode") {
@@ -670,13 +687,27 @@ TileSetEditor::TileSetEditor() {
split_container_left_side->set_custom_minimum_size(Size2i(70, 0) * EDSCALE);
split_container->add_child(split_container_left_side);
+ source_sort_button = memnew(MenuButton);
+ source_sort_button->set_flat(true);
+ source_sort_button->set_tooltip(TTR("Sort sources"));
+
+ PopupMenu *p = source_sort_button->get_popup();
+ p->connect("id_pressed", callable_mp(this, &TileSetEditor::_set_source_sort));
+ p->add_radio_check_item(TTR("Sort by ID (Ascending)"), TilesEditorPlugin::SOURCE_SORT_ID);
+ p->add_radio_check_item(TTR("Sort by ID (Descending)"), TilesEditorPlugin::SOURCE_SORT_ID_REVERSE);
+ p->add_radio_check_item(TTR("Sort by Name (Ascending)"), TilesEditorPlugin::SOURCE_SORT_NAME);
+ p->add_radio_check_item(TTR("Sort by Name (Descending)"), TilesEditorPlugin::SOURCE_SORT_NAME_REVERSE);
+ p->set_item_checked(TilesEditorPlugin::SOURCE_SORT_ID, true);
+
sources_list = memnew(ItemList);
sources_list->set_fixed_icon_size(Size2i(60, 60) * EDSCALE);
sources_list->set_h_size_flags(SIZE_EXPAND_FILL);
sources_list->set_v_size_flags(SIZE_EXPAND_FILL);
sources_list->connect("item_selected", callable_mp(this, &TileSetEditor::_source_selected));
sources_list->connect("item_selected", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::set_sources_lists_current));
- sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list), varray(sources_list));
+ sources_list->connect("visibility_changed", callable_mp(TilesEditorPlugin::get_singleton(), &TilesEditorPlugin::synchronize_sources_list), varray(sources_list, source_sort_button));
+ sources_list->add_user_signal(MethodInfo("sort_request"));
+ sources_list->connect("sort_request", callable_mp(this, &TileSetEditor::_update_sources_list), varray(-1));
sources_list->set_texture_filter(CanvasItem::TEXTURE_FILTER_NEAREST);
sources_list->set_drag_forwarding(this);
split_container_left_side->add_child(sources_list);
@@ -704,6 +735,7 @@ TileSetEditor::TileSetEditor() {
sources_advanced_menu_button->get_popup()->add_item(TTR("Manage Tile Proxies"));
sources_advanced_menu_button->get_popup()->connect("id_pressed", callable_mp(this, &TileSetEditor::_sources_advanced_menu_id_pressed));
sources_bottom_actions->add_child(sources_advanced_menu_button);
+ sources_bottom_actions->add_child(source_sort_button);
atlas_merging_dialog = memnew(AtlasMergingDialog);
add_child(atlas_merging_dialog);
diff --git a/editor/plugins/tiles/tile_set_editor.h b/editor/plugins/tiles/tile_set_editor.h
index 98ebbae02f..a21c951c42 100644
--- a/editor/plugins/tiles/tile_set_editor.h
+++ b/editor/plugins/tiles/tile_set_editor.h
@@ -67,6 +67,7 @@ private:
// Sources management.
Button *sources_delete_button;
MenuButton *sources_add_button;
+ MenuButton *source_sort_button;
MenuButton *sources_advanced_menu_button;
ItemList *sources_list;
Ref<Texture2D> missing_texture_texture;
@@ -74,6 +75,7 @@ private:
void _source_delete_pressed();
void _source_add_id_pressed(int p_id_pressed);
void _sources_advanced_menu_id_pressed(int p_id_pressed);
+ void _set_source_sort(int p_sort);
AtlasMergingDialog *atlas_merging_dialog;
TileProxiesManagerDialog *tile_proxies_manager_dialog;
diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp
index cdde22f5bc..4c644f33d4 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.cpp
+++ b/editor/plugins/tiles/tiles_editor_plugin.cpp
@@ -166,8 +166,6 @@ void TilesEditorPlugin::_update_editors() {
editor_node->hide_bottom_panel();
}
}
- tileset_editor_button->set_visible(tile_set.is_valid());
- tilemap_editor_button->set_visible(tile_map);
}
void TilesEditorPlugin::_notification(int p_what) {
@@ -218,15 +216,29 @@ void TilesEditorPlugin::set_sources_lists_current(int p_current) {
atlas_sources_lists_current = p_current;
}
-void TilesEditorPlugin::synchronize_sources_list(Object *p_current) {
- ItemList *item_list = Object::cast_to<ItemList>(p_current);
+void TilesEditorPlugin::synchronize_sources_list(Object *p_current_list, Object *p_current_sort_button) {
+ ItemList *item_list = Object::cast_to<ItemList>(p_current_list);
+ MenuButton *sorting_button = Object::cast_to<MenuButton>(p_current_sort_button);
ERR_FAIL_COND(!item_list);
+ ERR_FAIL_COND(!sorting_button);
+
+ if (sorting_button->is_visible_in_tree()) {
+ for (int i = 0; i != SOURCE_SORT_MAX; i++) {
+ sorting_button->get_popup()->set_item_checked(i, (i == (int)source_sort));
+ }
+ }
if (item_list->is_visible_in_tree()) {
if (atlas_sources_lists_current < 0 || atlas_sources_lists_current >= item_list->get_item_count()) {
item_list->deselect_all();
} else {
+ // Make sure the selection is not overwritten after sorting.
+ int atlas_sources_lists_current_mem = atlas_sources_lists_current;
+ item_list->emit_signal(SNAME("sort_request"));
+ atlas_sources_lists_current = atlas_sources_lists_current_mem;
+
item_list->set_current(atlas_sources_lists_current);
+ item_list->ensure_current_is_visible();
item_list->emit_signal(SNAME("item_selected"), atlas_sources_lists_current);
}
}
@@ -246,6 +258,87 @@ void TilesEditorPlugin::synchronize_atlas_view(Object *p_current) {
}
}
+void TilesEditorPlugin::set_sorting_option(int p_option) {
+ source_sort = p_option;
+}
+
+List<int> TilesEditorPlugin::get_sorted_sources(const Ref<TileSet> tile_set) const {
+ SourceNameComparator::tile_set = tile_set;
+ List<int> source_ids;
+
+ for (int i = 0; i < tile_set->get_source_count(); i++) {
+ source_ids.push_back(tile_set->get_source_id(i));
+ }
+
+ switch (source_sort) {
+ case SOURCE_SORT_ID_REVERSE:
+ // Already sorted.
+ source_ids.reverse();
+ break;
+ case SOURCE_SORT_NAME:
+ source_ids.sort_custom<SourceNameComparator>();
+ break;
+ case SOURCE_SORT_NAME_REVERSE:
+ source_ids.sort_custom<SourceNameComparator>();
+ source_ids.reverse();
+ break;
+ default: // SOURCE_SORT_ID
+ break;
+ }
+
+ SourceNameComparator::tile_set.unref();
+ return source_ids;
+}
+
+Ref<TileSet> TilesEditorPlugin::SourceNameComparator::tile_set;
+
+bool TilesEditorPlugin::SourceNameComparator::operator()(const int &p_a, const int &p_b) const {
+ String name_a;
+ String name_b;
+
+ {
+ TileSetSource *source = *tile_set->get_source(p_a);
+
+ if (!source->get_name().is_empty()) {
+ name_a = source->get_name();
+ }
+
+ TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
+ if (atlas_source) {
+ Ref<Texture2D> texture = atlas_source->get_texture();
+ if (name_a.is_empty() && texture.is_valid()) {
+ name_a = texture->get_path().get_file();
+ }
+ }
+
+ if (name_a.is_empty()) {
+ name_a = itos(p_a);
+ }
+ }
+
+ {
+ TileSetSource *source = *tile_set->get_source(p_b);
+
+ if (!source->get_name().is_empty()) {
+ name_b = source->get_name();
+ }
+
+ TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
+ if (atlas_source) {
+ Ref<Texture2D> texture = atlas_source->get_texture();
+ if (name_b.is_empty() && texture.is_valid()) {
+ name_b = texture->get_path().get_file();
+ }
+ }
+
+ if (name_b.is_empty()) {
+ name_b = itos(p_b);
+ }
+ }
+
+ return NaturalNoCaseComparator()(name_a, name_b);
+}
+
void TilesEditorPlugin::edit(Object *p_object) {
// Disconnect to changes.
TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
diff --git a/editor/plugins/tiles/tiles_editor_plugin.h b/editor/plugins/tiles/tiles_editor_plugin.h
index 59eb79480e..487436b98a 100644
--- a/editor/plugins/tiles/tiles_editor_plugin.h
+++ b/editor/plugins/tiles/tiles_editor_plugin.h
@@ -43,6 +43,15 @@ class TilesEditorPlugin : public EditorPlugin {
static TilesEditorPlugin *singleton;
+public:
+ enum SourceSortOption {
+ SOURCE_SORT_ID = 0,
+ SOURCE_SORT_ID_REVERSE,
+ SOURCE_SORT_NAME,
+ SOURCE_SORT_NAME_REVERSE,
+ SOURCE_SORT_MAX
+ };
+
private:
EditorNode *editor_node;
@@ -65,6 +74,14 @@ private:
void _tile_map_changed();
+ // Source sorting.
+ int source_sort = SOURCE_SORT_ID;
+
+ struct SourceNameComparator {
+ static Ref<TileSet> tile_set;
+ bool operator()(const int &p_a, const int &p_b) const;
+ };
+
// Patterns preview generation.
struct QueueItem {
Ref<TileSet> tile_set;
@@ -97,11 +114,15 @@ public:
// To synchronize the atlas sources lists.
void set_sources_lists_current(int p_current);
- void synchronize_sources_list(Object *p_current);
+ void synchronize_sources_list(Object *p_current_list, Object *p_current_sort_button);
void set_atlas_view_transform(float p_zoom, Vector2 p_scroll);
void synchronize_atlas_view(Object *p_current);
+ // Sorting.
+ void set_sorting_option(int p_option);
+ List<int> get_sorted_sources(const Ref<TileSet> tile_set) const;
+
virtual void edit(Object *p_object) override;
virtual bool handles(Object *p_object) const override;
virtual void make_visible(bool p_visible) override;
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 2d0ca11b6a..9ab53bf5c3 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -202,6 +202,10 @@ void VisualShaderGraphPlugin::set_input_port_default_value(VisualShader::Type p_
case Variant::FLOAT: {
button->set_text(String::num(p_value, 4));
} break;
+ case Variant::VECTOR2: {
+ Vector2 v = p_value;
+ button->set_text(String::num(v.x, 3) + "," + String::num(v.y, 3));
+ } break;
case Variant::VECTOR3: {
Vector3 v = p_value;
button->set_text(String::num(v.x, 3) + "," + String::num(v.y, 3) + "," + String::num(v.z, 3));
@@ -358,10 +362,11 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
static Ref<StyleBoxEmpty> label_style = make_empty_stylebox(2, 1, 2, 1);
- static const Color type_color[6] = {
+ static const Color type_color[7] = {
Color(0.38, 0.85, 0.96), // scalar (float)
Color(0.49, 0.78, 0.94), // scalar (int)
- Color(0.84, 0.49, 0.93), // vector
+ Color(0.74, 0.57, 0.95), // vector2
+ Color(0.84, 0.49, 0.93), // vector3
Color(0.55, 0.65, 0.94), // boolean
Color(0.96, 0.66, 0.43), // transform
Color(1.0, 1.0, 0.0), // sampler
@@ -597,8 +602,15 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
int output_port_count = 0;
for (int i = 0; i < vsnode->get_output_port_count(); i++) {
if (vsnode->_is_output_port_expanded(i)) {
- if (vsnode->get_output_port_type(i) == VisualShaderNode::PORT_TYPE_VECTOR) {
- output_port_count += 3;
+ switch (vsnode->get_output_port_type(i)) {
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ output_port_count += 2;
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR: {
+ output_port_count += 3;
+ } break;
+ default:
+ break;
}
}
output_port_count++;
@@ -608,10 +620,23 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
int expanded_port_counter = 0;
for (int i = 0, j = 0; i < max_ports; i++, j++) {
- if (expanded_type == VisualShaderNode::PORT_TYPE_VECTOR && expanded_port_counter >= 3) {
- expanded_type = VisualShaderNode::PORT_TYPE_SCALAR;
- expanded_port_counter = 0;
- i -= 3;
+ switch (expanded_type) {
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ if (expanded_port_counter >= 2) {
+ expanded_type = VisualShaderNode::PORT_TYPE_SCALAR;
+ expanded_port_counter = 0;
+ i -= 2;
+ }
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR: {
+ if (expanded_port_counter >= 3) {
+ expanded_type = VisualShaderNode::PORT_TYPE_SCALAR;
+ expanded_port_counter = 0;
+ i -= 3;
+ }
+ } break;
+ default:
+ break;
}
if (vsnode->is_port_separator(i)) {
@@ -682,7 +707,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
hb->add_child(type_box);
type_box->add_item(TTR("Float"));
type_box->add_item(TTR("Int"));
- type_box->add_item(TTR("Vector"));
+ type_box->add_item(TTR("Vector2"));
+ type_box->add_item(TTR("Vector3"));
type_box->add_item(TTR("Boolean"));
type_box->add_item(TTR("Transform"));
type_box->add_item(TTR("Sampler"));
@@ -743,7 +769,8 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
hb->add_child(type_box);
type_box->add_item(TTR("Float"));
type_box->add_item(TTR("Int"));
- type_box->add_item(TTR("Vector"));
+ type_box->add_item(TTR("Vector2"));
+ type_box->add_item(TTR("Vector3"));
type_box->add_item(TTR("Boolean"));
type_box->add_item(TTR("Transform"));
type_box->select(group_node->get_output_port_type(i));
@@ -805,31 +832,55 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
node->set_slot(idx, valid_left, port_left, type_color[port_left], valid_right, port_right, type_color[port_right]);
if (vsnode->_is_output_port_expanded(i)) {
- if (vsnode->get_output_port_type(i) == VisualShaderNode::PORT_TYPE_VECTOR) {
- port_offset++;
- valid_left = (i + 1) < vsnode->get_input_port_count();
- port_left = VisualShaderNode::PORT_TYPE_SCALAR;
- if (valid_left) {
- port_left = vsnode->get_input_port_type(i + 1);
- }
- node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]);
- port_offset++;
+ switch (vsnode->get_output_port_type(i)) {
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ port_offset++;
+ valid_left = (i + 1) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 1);
+ }
+ node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]);
+ port_offset++;
- valid_left = (i + 2) < vsnode->get_input_port_count();
- port_left = VisualShaderNode::PORT_TYPE_SCALAR;
- if (valid_left) {
- port_left = vsnode->get_input_port_type(i + 2);
- }
- node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]);
- port_offset++;
+ valid_left = (i + 2) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 2);
+ }
+ node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]);
+
+ expanded_type = VisualShaderNode::PORT_TYPE_VECTOR_2D;
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR: {
+ port_offset++;
+ valid_left = (i + 1) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 1);
+ }
+ node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[0]);
+ port_offset++;
- valid_left = (i + 3) < vsnode->get_input_port_count();
- port_left = VisualShaderNode::PORT_TYPE_SCALAR;
- if (valid_left) {
- port_left = vsnode->get_input_port_type(i + 3);
- }
- node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[2]);
- expanded_type = VisualShaderNode::PORT_TYPE_VECTOR;
+ valid_left = (i + 2) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 2);
+ }
+ node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[1]);
+ port_offset++;
+
+ valid_left = (i + 3) < vsnode->get_input_port_count();
+ port_left = VisualShaderNode::PORT_TYPE_SCALAR;
+ if (valid_left) {
+ port_left = vsnode->get_input_port_type(i + 3);
+ }
+ node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], true, VisualShaderNode::PORT_TYPE_SCALAR, vector_expanded_color[2]);
+
+ expanded_type = VisualShaderNode::PORT_TYPE_VECTOR;
+ } break;
+ default:
+ break;
}
}
}
@@ -1030,7 +1081,7 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
}
void VisualShaderEditor::add_plugin(const Ref<VisualShaderNodePlugin> &p_plugin) {
- if (plugins.find(p_plugin) != -1) {
+ if (plugins.has(p_plugin)) {
return;
}
plugins.push_back(p_plugin);
@@ -1259,7 +1310,9 @@ void VisualShaderEditor::_update_options_menu() {
if (input.is_valid()) {
input->set_shader_mode(visual_shader->get_mode());
input->set_shader_type(visual_shader->get_shader_type());
- input->set_input_name(add_options[i].sub_func_str);
+ if (!add_options[i].ops.is_empty() && add_options[i].ops[0].get_type() == Variant::STRING) {
+ input->set_input_name((String)add_options[i].ops[0]);
+ }
}
Ref<VisualShaderNodeExpression> expression = Object::cast_to<VisualShaderNodeExpression>(vsn.ptr());
@@ -1376,6 +1429,9 @@ void VisualShaderEditor::_update_options_menu() {
case VisualShaderNode::PORT_TYPE_SCALAR_INT:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("int"), SNAME("EditorIcons")));
break;
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D:
+ item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")));
+ break;
case VisualShaderNode::PORT_TYPE_VECTOR:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")));
break;
@@ -1474,6 +1530,7 @@ void VisualShaderEditor::_update_uniforms(bool p_update_refs) {
if (uniform.is_valid()) {
Ref<VisualShaderNodeFloatUniform> float_uniform = vsnode;
Ref<VisualShaderNodeIntUniform> int_uniform = vsnode;
+ Ref<VisualShaderNodeVec2Uniform> vec2_uniform = vsnode;
Ref<VisualShaderNodeVec3Uniform> vec3_uniform = vsnode;
Ref<VisualShaderNodeColorUniform> color_uniform = vsnode;
Ref<VisualShaderNodeBooleanUniform> bool_uniform = vsnode;
@@ -1486,8 +1543,10 @@ void VisualShaderEditor::_update_uniforms(bool p_update_refs) {
uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_INT;
} else if (bool_uniform.is_valid()) {
uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_BOOLEAN;
+ } else if (vec2_uniform.is_valid()) {
+ uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_VECTOR2;
} else if (vec3_uniform.is_valid()) {
- uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_VECTOR;
+ uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_VECTOR3;
} else if (transform_uniform.is_valid()) {
uniform_type = VisualShaderNodeUniformRef::UniformType::UNIFORM_TYPE_TRANSFORM;
} else if (color_uniform.is_valid()) {
@@ -1726,8 +1785,15 @@ void VisualShaderEditor::_expand_output_port(int p_node, int p_port, bool p_expa
undo_redo->add_undo_method(node.ptr(), "_set_output_port_expanded", p_port, !p_expand);
int type_size = 0;
- if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_VECTOR) {
- type_size = 3;
+ switch (node->get_output_port_type(p_port)) {
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ type_size = 2;
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR: {
+ type_size = 3;
+ } break;
+ default:
+ break;
}
List<VisualShader::Connection> conns;
@@ -2175,13 +2241,36 @@ void VisualShaderEditor::_edit_port_default_input(Object *p_button, int p_node,
editing_port = p_port;
}
-void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
+void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, const Vector<Variant> &p_ops) {
+ // INPUT
+ {
+ VisualShaderNodeInput *input = Object::cast_to<VisualShaderNodeInput>(p_node);
+
+ if (input) {
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::STRING);
+ input->set_input_name((String)p_ops[0]);
+ return;
+ }
+ }
+
+ // FLOAT_CONST
+ {
+ VisualShaderNodeFloatConstant *float_const = Object::cast_to<VisualShaderNodeFloatConstant>(p_node);
+
+ if (float_const) {
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::FLOAT);
+ float_const->set_constant((float)p_ops[0]);
+ return;
+ }
+ }
+
// FLOAT_OP
{
VisualShaderNodeFloatOp *floatOp = Object::cast_to<VisualShaderNodeFloatOp>(p_node);
if (floatOp) {
- floatOp->set_operator((VisualShaderNodeFloatOp::Operator)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ floatOp->set_operator((VisualShaderNodeFloatOp::Operator)(int)p_ops[0]);
return;
}
}
@@ -2191,7 +2280,8 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeFloatFunc *floatFunc = Object::cast_to<VisualShaderNodeFloatFunc>(p_node);
if (floatFunc) {
- floatFunc->set_function((VisualShaderNodeFloatFunc::Function)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ floatFunc->set_function((VisualShaderNodeFloatFunc::Function)(int)p_ops[0]);
return;
}
}
@@ -2201,7 +2291,10 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeVectorOp *vecOp = Object::cast_to<VisualShaderNodeVectorOp>(p_node);
if (vecOp) {
- vecOp->set_operator((VisualShaderNodeVectorOp::Operator)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ ERR_FAIL_COND(p_ops[1].get_type() != Variant::INT);
+ vecOp->set_operator((VisualShaderNodeVectorOp::Operator)(int)p_ops[0]);
+ vecOp->set_op_type((VisualShaderNodeVectorOp::OpType)(int)p_ops[1]);
return;
}
}
@@ -2211,7 +2304,10 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeVectorFunc *vecFunc = Object::cast_to<VisualShaderNodeVectorFunc>(p_node);
if (vecFunc) {
- vecFunc->set_function((VisualShaderNodeVectorFunc::Function)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ ERR_FAIL_COND(p_ops[1].get_type() != Variant::INT);
+ vecFunc->set_function((VisualShaderNodeVectorFunc::Function)(int)p_ops[0]);
+ vecFunc->set_op_type((VisualShaderNodeVectorFunc::OpType)(int)p_ops[1]);
return;
}
}
@@ -2221,7 +2317,8 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeColorOp *colorOp = Object::cast_to<VisualShaderNodeColorOp>(p_node);
if (colorOp) {
- colorOp->set_operator((VisualShaderNodeColorOp::Operator)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ colorOp->set_operator((VisualShaderNodeColorOp::Operator)(int)p_ops[0]);
return;
}
}
@@ -2231,7 +2328,8 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeColorFunc *colorFunc = Object::cast_to<VisualShaderNodeColorFunc>(p_node);
if (colorFunc) {
- colorFunc->set_function((VisualShaderNodeColorFunc::Function)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ colorFunc->set_function((VisualShaderNodeColorFunc::Function)(int)p_ops[0]);
return;
}
}
@@ -2241,7 +2339,8 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeIntOp *intOp = Object::cast_to<VisualShaderNodeIntOp>(p_node);
if (intOp) {
- intOp->set_operator((VisualShaderNodeIntOp::Operator)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ intOp->set_operator((VisualShaderNodeIntOp::Operator)(int)p_ops[0]);
return;
}
}
@@ -2251,7 +2350,8 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeIntFunc *intFunc = Object::cast_to<VisualShaderNodeIntFunc>(p_node);
if (intFunc) {
- intFunc->set_function((VisualShaderNodeIntFunc::Function)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ intFunc->set_function((VisualShaderNodeIntFunc::Function)(int)p_ops[0]);
return;
}
}
@@ -2261,7 +2361,8 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeTransformOp *matOp = Object::cast_to<VisualShaderNodeTransformOp>(p_node);
if (matOp) {
- matOp->set_operator((VisualShaderNodeTransformOp::Operator)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ matOp->set_operator((VisualShaderNodeTransformOp::Operator)(int)p_ops[0]);
return;
}
}
@@ -2271,17 +2372,41 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeTransformFunc *matFunc = Object::cast_to<VisualShaderNodeTransformFunc>(p_node);
if (matFunc) {
- matFunc->set_function((VisualShaderNodeTransformFunc::Function)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ matFunc->set_function((VisualShaderNodeTransformFunc::Function)(int)p_ops[0]);
+ return;
+ }
+ }
+
+ // VECTOR_COMPOSE
+ {
+ VisualShaderNodeVectorCompose *vecCompose = Object::cast_to<VisualShaderNodeVectorCompose>(p_node);
+
+ if (vecCompose) {
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ vecCompose->set_op_type((VisualShaderNodeVectorCompose::OpType)(int)p_ops[0]);
+ return;
+ }
+ }
+
+ // VECTOR_DECOMPOSE
+ {
+ VisualShaderNodeVectorDecompose *vecDecompose = Object::cast_to<VisualShaderNodeVectorDecompose>(p_node);
+
+ if (vecDecompose) {
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ vecDecompose->set_op_type((VisualShaderNodeVectorDecompose::OpType)(int)p_ops[0]);
return;
}
}
- //UV_FUNC
+ // UV_FUNC
{
VisualShaderNodeUVFunc *uvFunc = Object::cast_to<VisualShaderNodeUVFunc>(p_node);
if (uvFunc) {
- uvFunc->set_function((VisualShaderNodeUVFunc::Function)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ uvFunc->set_function((VisualShaderNodeUVFunc::Function)(int)p_ops[0]);
return;
}
}
@@ -2291,7 +2416,8 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeIs *is = Object::cast_to<VisualShaderNodeIs>(p_node);
if (is) {
- is->set_function((VisualShaderNodeIs::Function)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ is->set_function((VisualShaderNodeIs::Function)(int)p_ops[0]);
return;
}
}
@@ -2301,24 +2427,32 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeCompare *cmp = Object::cast_to<VisualShaderNodeCompare>(p_node);
if (cmp) {
- cmp->set_function((VisualShaderNodeCompare::Function)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ cmp->set_function((VisualShaderNodeCompare::Function)(int)p_ops[0]);
return;
}
}
- // DERIVATIVE
+ // DISTANCE
{
- VisualShaderNodeScalarDerivativeFunc *sderFunc = Object::cast_to<VisualShaderNodeScalarDerivativeFunc>(p_node);
+ VisualShaderNodeVectorDistance *dist = Object::cast_to<VisualShaderNodeVectorDistance>(p_node);
- if (sderFunc) {
- sderFunc->set_function((VisualShaderNodeScalarDerivativeFunc::Function)p_op_idx);
+ if (dist) {
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ dist->set_op_type((VisualShaderNodeVectorDistance::OpType)(int)p_ops[0]);
return;
}
+ }
- VisualShaderNodeVectorDerivativeFunc *vderFunc = Object::cast_to<VisualShaderNodeVectorDerivativeFunc>(p_node);
+ // DERIVATIVE
+ {
+ VisualShaderNodeDerivativeFunc *derFunc = Object::cast_to<VisualShaderNodeDerivativeFunc>(p_node);
- if (vderFunc) {
- vderFunc->set_function((VisualShaderNodeVectorDerivativeFunc::Function)p_op_idx);
+ if (derFunc) {
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ ERR_FAIL_COND(p_ops[1].get_type() != Variant::INT);
+ derFunc->set_function((VisualShaderNodeDerivativeFunc::Function)(int)p_ops[0]);
+ derFunc->set_op_type((VisualShaderNodeDerivativeFunc::OpType)(int)p_ops[1]);
return;
}
}
@@ -2328,7 +2462,8 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeMix *mix = Object::cast_to<VisualShaderNodeMix>(p_node);
if (mix) {
- mix->set_op_type((VisualShaderNodeMix::OpType)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ mix->set_op_type((VisualShaderNodeMix::OpType)(int)p_ops[0]);
return;
}
}
@@ -2338,7 +2473,8 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeClamp *clampFunc = Object::cast_to<VisualShaderNodeClamp>(p_node);
if (clampFunc) {
- clampFunc->set_op_type((VisualShaderNodeClamp::OpType)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ clampFunc->set_op_type((VisualShaderNodeClamp::OpType)(int)p_ops[0]);
return;
}
}
@@ -2348,7 +2484,28 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeSwitch *switchFunc = Object::cast_to<VisualShaderNodeSwitch>(p_node);
if (switchFunc) {
- switchFunc->set_op_type((VisualShaderNodeSwitch::OpType)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ switchFunc->set_op_type((VisualShaderNodeSwitch::OpType)(int)p_ops[0]);
+ return;
+ }
+ }
+
+ // FACEFORWARD
+ {
+ VisualShaderNodeFaceForward *faceForward = Object::cast_to<VisualShaderNodeFaceForward>(p_node);
+ if (faceForward) {
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ faceForward->set_op_type((VisualShaderNodeFaceForward::OpType)(int)p_ops[0]);
+ return;
+ }
+ }
+
+ // LENGTH
+ {
+ VisualShaderNodeVectorLen *length = Object::cast_to<VisualShaderNodeVectorLen>(p_node);
+ if (length) {
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ length->set_op_type((VisualShaderNodeVectorLen::OpType)(int)p_ops[0]);
return;
}
}
@@ -2358,7 +2515,8 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeSmoothStep *smoothStepFunc = Object::cast_to<VisualShaderNodeSmoothStep>(p_node);
if (smoothStepFunc) {
- smoothStepFunc->set_op_type((VisualShaderNodeSmoothStep::OpType)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ smoothStepFunc->set_op_type((VisualShaderNodeSmoothStep::OpType)(int)p_ops[0]);
return;
}
}
@@ -2368,7 +2526,8 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeStep *stepFunc = Object::cast_to<VisualShaderNodeStep>(p_node);
if (stepFunc) {
- stepFunc->set_op_type((VisualShaderNodeStep::OpType)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ stepFunc->set_op_type((VisualShaderNodeStep::OpType)(int)p_ops[0]);
return;
}
}
@@ -2378,12 +2537,13 @@ void VisualShaderEditor::_setup_node(VisualShaderNode *p_node, int p_op_idx) {
VisualShaderNodeMultiplyAdd *fmaFunc = Object::cast_to<VisualShaderNodeMultiplyAdd>(p_node);
if (fmaFunc) {
- fmaFunc->set_op_type((VisualShaderNodeMultiplyAdd::OpType)p_op_idx);
+ ERR_FAIL_COND(p_ops[0].get_type() != Variant::INT);
+ fmaFunc->set_op_type((VisualShaderNodeMultiplyAdd::OpType)(int)p_ops[0]);
}
}
}
-void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_path, int p_node_idx) {
+void VisualShaderEditor::_add_node(int p_idx, const Vector<Variant> &p_ops, String p_resource_path, int p_node_idx) {
ERR_FAIL_INDEX(p_idx, add_options.size());
VisualShader::Type type = get_current_shader_type();
@@ -2395,25 +2555,9 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_pa
if (!is_custom && !add_options[p_idx].type.is_empty()) {
VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instantiate(add_options[p_idx].type));
ERR_FAIL_COND(!vsn);
-
- VisualShaderNodeFloatConstant *constant = Object::cast_to<VisualShaderNodeFloatConstant>(vsn);
-
- if (constant) {
- if ((int)add_options[p_idx].value != -1) {
- constant->set_constant(add_options[p_idx].value);
- }
- } else {
- if (p_op_idx != -1) {
- VisualShaderNodeInput *input = Object::cast_to<VisualShaderNodeInput>(vsn);
-
- if (input) {
- input->set_input_name(add_options[p_idx].sub_func_str);
- } else {
- _setup_node(vsn, p_op_idx);
- }
- }
+ if (!p_ops.is_empty()) {
+ _setup_node(vsn, p_ops);
}
-
VisualShaderNodeUniformRef *uniform_ref = Object::cast_to<VisualShaderNodeUniformRef>(vsn);
if (uniform_ref && to_node != -1 && to_slot != -1) {
@@ -2501,6 +2645,9 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx, String p_resource_pa
case VisualShaderNode::PORT_TYPE_SCALAR_INT:
initial_expression_code = "output0 = 1;";
break;
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D:
+ initial_expression_code = "output0 = vec2(1.0, 1.0);";
+ break;
case VisualShaderNode::PORT_TYPE_VECTOR:
initial_expression_code = "output0 = vec3(1.0, 1.0, 1.0);";
break;
@@ -2911,6 +3058,25 @@ void VisualShaderEditor::_convert_constants_to_uniforms(bool p_vice_versa) {
}
}
+ // vec2
+ if (!caught) {
+ if (!p_vice_versa) {
+ Ref<VisualShaderNodeVec2Constant> vec2_const = Object::cast_to<VisualShaderNodeVec2Constant>(node.ptr());
+ if (vec2_const.is_valid()) {
+ _replace_node(type_id, node_id, "VisualShaderNodeVec2Constant", "VisualShaderNodeVec2Uniform");
+ var = vec2_const->get_constant();
+ caught = true;
+ }
+ } else {
+ Ref<VisualShaderNodeVec2Uniform> vec2_uniform = Object::cast_to<VisualShaderNodeVec2Uniform>(node.ptr());
+ if (vec2_uniform.is_valid()) {
+ _replace_node(type_id, node_id, "VisualShaderNodeVec2Uniform", "VisualShaderNodeVec2Constant");
+ var = vec2_uniform->get_default_value();
+ caught = true;
+ }
+ }
+ }
+
// vec3
if (!caught) {
if (!p_vice_versa) {
@@ -3696,7 +3862,7 @@ void VisualShaderEditor::_member_create() {
TreeItem *item = members->get_selected();
if (item != nullptr && item->has_meta("id")) {
int idx = members->get_selected()->get_meta("id");
- _add_node(idx, add_options[idx].sub_func);
+ _add_node(idx, add_options[idx].ops);
members_dialog->hide();
}
}
@@ -3799,11 +3965,6 @@ Variant VisualShaderEditor::get_drag_data_fw(const Point2 &p_point, Control *p_f
Dictionary d;
d["id"] = id;
- if (op.sub_func == -1) {
- d["sub_func"] = op.sub_func_str;
- } else {
- d["sub_func"] = op.sub_func;
- }
Label *label = memnew(Label);
label->set_text(it->get_text(0));
@@ -3836,7 +3997,7 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
int idx = d["id"];
saved_node_pos = p_point;
saved_node_pos_dirty = true;
- _add_node(idx, add_options[idx].sub_func);
+ _add_node(idx, add_options[idx].ops);
} else if (d.has("files")) {
undo_redo->create_action(TTR("Add Node(s) to Visual Shader"));
@@ -3861,33 +4022,33 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
}
if (idx != -1) {
- _add_node(idx, -1, arr[i], i);
+ _add_node(idx, {}, arr[i], i);
}
}
} else if (type == "CurveTexture") {
saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
saved_node_pos_dirty = true;
- _add_node(curve_node_option_idx, -1, arr[i], i);
+ _add_node(curve_node_option_idx, {}, arr[i], i);
} else if (type == "CurveXYZTexture") {
saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
saved_node_pos_dirty = true;
- _add_node(curve_xyz_node_option_idx, -1, arr[i], i);
+ _add_node(curve_xyz_node_option_idx, {}, arr[i], i);
} else if (ClassDB::get_parent_class(type) == "Texture2D") {
saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
saved_node_pos_dirty = true;
- _add_node(texture2d_node_option_idx, -1, arr[i], i);
+ _add_node(texture2d_node_option_idx, {}, arr[i], i);
} else if (type == "Texture2DArray") {
saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
saved_node_pos_dirty = true;
- _add_node(texture2d_array_node_option_idx, -1, arr[i], i);
+ _add_node(texture2d_array_node_option_idx, {}, arr[i], i);
} else if (ClassDB::get_parent_class(type) == "Texture3D") {
saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
saved_node_pos_dirty = true;
- _add_node(texture3d_node_option_idx, -1, arr[i], i);
+ _add_node(texture3d_node_option_idx, {}, arr[i], i);
} else if (type == "Cubemap") {
saved_node_pos = p_point + Vector2(0, i * 250 * EDSCALE);
saved_node_pos_dirty = true;
- _add_node(cubemap_node_option_idx, -1, arr[i], i);
+ _add_node(cubemap_node_option_idx, {}, arr[i], i);
}
}
}
@@ -4020,6 +4181,7 @@ VisualShaderEditor::VisualShaderEditor() {
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR_INT);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_BOOLEAN);
+ graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_VECTOR_2D);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_VECTOR);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_TRANSFORM);
graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SAMPLER);
@@ -4039,18 +4201,27 @@ VisualShaderEditor::VisualShaderEditor() {
graph->connect("visibility_changed", callable_mp(this, &VisualShaderEditor::_visibility_changed));
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR_INT);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR_2D);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_BOOLEAN);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_SCALAR);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_VECTOR_2D);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_VECTOR);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_BOOLEAN);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_SCALAR);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_SCALAR_INT);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_VECTOR_2D);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_VECTOR);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR_2D, VisualShaderNode::PORT_TYPE_BOOLEAN);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_SCALAR);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_SCALAR_INT);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR_2D);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_BOOLEAN);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_SCALAR);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_SCALAR_INT);
+ graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_VECTOR_2D);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_VECTOR);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_BOOLEAN);
graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShaderNode::PORT_TYPE_TRANSFORM);
@@ -4275,94 +4446,99 @@ VisualShaderEditor::VisualShaderEditor() {
// COLOR
- add_options.push_back(AddOption("ColorFunc", "Color", "Common", "VisualShaderNodeColorFunc", TTR("Color function."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ColorOp", "Color", "Common", "VisualShaderNodeColorOp", TTR("Color operator."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ColorFunc", "Color", "Common", "VisualShaderNodeColorFunc", TTR("Color function."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ColorOp", "Color", "Common", "VisualShaderNodeColorOp", TTR("Color operator."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Grayscale", "Color", "Functions", "VisualShaderNodeColorFunc", TTR("Grayscale function."), VisualShaderNodeColorFunc::FUNC_GRAYSCALE, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("HSV2RGB", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts HSV vector to RGB equivalent."), VisualShaderNodeVectorFunc::FUNC_HSV2RGB, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("RGB2HSV", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts RGB vector to HSV equivalent."), VisualShaderNodeVectorFunc::FUNC_RGB2HSV, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Sepia", "Color", "Functions", "VisualShaderNodeColorFunc", TTR("Sepia function."), VisualShaderNodeColorFunc::FUNC_SEPIA, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Grayscale", "Color", "Functions", "VisualShaderNodeColorFunc", TTR("Grayscale function."), { VisualShaderNodeColorFunc::FUNC_GRAYSCALE }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("HSV2RGB", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts HSV vector to RGB equivalent."), { VisualShaderNodeVectorFunc::FUNC_HSV2RGB }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("RGB2HSV", "Color", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts RGB vector to HSV equivalent."), { VisualShaderNodeVectorFunc::FUNC_RGB2HSV }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Sepia", "Color", "Functions", "VisualShaderNodeColorFunc", TTR("Sepia function."), { VisualShaderNodeColorFunc::FUNC_SEPIA }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Burn", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Burn operator."), VisualShaderNodeColorOp::OP_BURN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Darken", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Darken operator."), VisualShaderNodeColorOp::OP_DARKEN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Difference", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Difference operator."), VisualShaderNodeColorOp::OP_DIFFERENCE, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Dodge", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Dodge operator."), VisualShaderNodeColorOp::OP_DODGE, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("HardLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("HardLight operator."), VisualShaderNodeColorOp::OP_HARD_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Lighten", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Lighten operator."), VisualShaderNodeColorOp::OP_LIGHTEN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Overlay", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Overlay operator."), VisualShaderNodeColorOp::OP_OVERLAY, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Screen", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Screen operator."), VisualShaderNodeColorOp::OP_SCREEN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("SoftLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("SoftLight operator."), VisualShaderNodeColorOp::OP_SOFT_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Burn", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Burn operator."), { VisualShaderNodeColorOp::OP_BURN }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Darken", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Darken operator."), { VisualShaderNodeColorOp::OP_DARKEN }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Difference", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Difference operator."), { VisualShaderNodeColorOp::OP_DIFFERENCE }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Dodge", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Dodge operator."), { VisualShaderNodeColorOp::OP_DODGE }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("HardLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("HardLight operator."), { VisualShaderNodeColorOp::OP_HARD_LIGHT }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Lighten", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Lighten operator."), { VisualShaderNodeColorOp::OP_LIGHTEN }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Overlay", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Overlay operator."), { VisualShaderNodeColorOp::OP_OVERLAY }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Screen", "Color", "Operators", "VisualShaderNodeColorOp", TTR("Screen operator."), { VisualShaderNodeColorOp::OP_SCREEN }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SoftLight", "Color", "Operators", "VisualShaderNodeColorOp", TTR("SoftLight operator."), { VisualShaderNodeColorOp::OP_SOFT_LIGHT }, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ColorConstant", "Color", "Variables", "VisualShaderNodeColorConstant", TTR("Color constant."), -1, -1));
- add_options.push_back(AddOption("ColorUniform", "Color", "Variables", "VisualShaderNodeColorUniform", TTR("Color uniform."), -1, -1));
+ add_options.push_back(AddOption("ColorConstant", "Color", "Variables", "VisualShaderNodeColorConstant", TTR("Color constant.")));
+ add_options.push_back(AddOption("ColorUniform", "Color", "Variables", "VisualShaderNodeColorUniform", TTR("Color uniform.")));
+
+ // COMMON
+
+ add_options.push_back(AddOption("DerivativeFunc", "Common", "", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) Derivative function."), {}, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
// CONDITIONAL
const String &compare_func_desc = TTR("Returns the boolean result of the %s comparison between two parameters.");
- add_options.push_back(AddOption("Equal", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Equal (==)")), VisualShaderNodeCompare::FUNC_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("GreaterThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than (>)")), VisualShaderNodeCompare::FUNC_GREATER_THAN, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("GreaterThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than or Equal (>=)")), VisualShaderNodeCompare::FUNC_GREATER_THAN_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("If", "Conditional", "Functions", "VisualShaderNodeIf", TTR("Returns an associated vector if the provided scalars are equal, greater or less."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("IsInf", "Conditional", "Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF and a scalar parameter."), VisualShaderNodeIs::FUNC_IS_INF, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("IsNaN", "Conditional", "Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between NaN and a scalar parameter."), VisualShaderNodeIs::FUNC_IS_NAN, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("LessThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than (<)")), VisualShaderNodeCompare::FUNC_LESS_THAN, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("LessThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than or Equal (<=)")), VisualShaderNodeCompare::FUNC_LESS_THAN_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("NotEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Not Equal (!=)")), VisualShaderNodeCompare::FUNC_NOT_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated vector if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("SwitchBool", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated boolean if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("SwitchFloat", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated floating-point scalar if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_FLOAT, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("SwitchInt", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated integer scalar if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("SwitchTransform", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated transform if the provided boolean value is true or false."), VisualShaderNodeSwitch::OP_TYPE_TRANSFORM, VisualShaderNode::PORT_TYPE_TRANSFORM));
-
- add_options.push_back(AddOption("Compare", "Conditional", "Common", "VisualShaderNodeCompare", TTR("Returns the boolean result of the comparison between two parameters."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("Is", "Conditional", "Common", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF (or NaN) and a scalar parameter."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
-
- add_options.push_back(AddOption("BooleanConstant", "Conditional", "Variables", "VisualShaderNodeBooleanConstant", TTR("Boolean constant."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
- add_options.push_back(AddOption("BooleanUniform", "Conditional", "Variables", "VisualShaderNodeBooleanUniform", TTR("Boolean uniform."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("Equal", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Equal (==)")), { VisualShaderNodeCompare::FUNC_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("GreaterThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than (>)")), { VisualShaderNodeCompare::FUNC_GREATER_THAN }, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("GreaterThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than or Equal (>=)")), { VisualShaderNodeCompare::FUNC_GREATER_THAN_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("If", "Conditional", "Functions", "VisualShaderNodeIf", TTR("Returns an associated vector if the provided scalars are equal, greater or less."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("IsInf", "Conditional", "Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF and a scalar parameter."), { VisualShaderNodeIs::FUNC_IS_INF }, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("IsNaN", "Conditional", "Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between NaN and a scalar parameter."), { VisualShaderNodeIs::FUNC_IS_NAN }, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("LessThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than (<)")), { VisualShaderNodeCompare::FUNC_LESS_THAN }, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("LessThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Less Than or Equal (<=)")), { VisualShaderNodeCompare::FUNC_LESS_THAN_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("NotEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Not Equal (!=)")), { VisualShaderNodeCompare::FUNC_NOT_EQUAL }, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("Switch", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated 3D vector if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Switch2D", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated 2D vector if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("SwitchBool", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated boolean if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_BOOLEAN }, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("SwitchFloat", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated floating-point scalar if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_FLOAT }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("SwitchInt", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated integer scalar if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_INT }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("SwitchTransform", "Conditional", "Functions", "VisualShaderNodeSwitch", TTR("Returns an associated transform if the provided boolean value is true or false."), { VisualShaderNodeSwitch::OP_TYPE_TRANSFORM }, VisualShaderNode::PORT_TYPE_TRANSFORM));
+
+ add_options.push_back(AddOption("Compare", "Conditional", "Common", "VisualShaderNodeCompare", TTR("Returns the boolean result of the comparison between two parameters."), {}, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("Is", "Conditional", "Common", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF (or NaN) and a scalar parameter."), {}, VisualShaderNode::PORT_TYPE_BOOLEAN));
+
+ add_options.push_back(AddOption("BooleanConstant", "Conditional", "Variables", "VisualShaderNodeBooleanConstant", TTR("Boolean constant."), {}, VisualShaderNode::PORT_TYPE_BOOLEAN));
+ add_options.push_back(AddOption("BooleanUniform", "Conditional", "Variables", "VisualShaderNodeBooleanUniform", TTR("Boolean uniform."), {}, VisualShaderNode::PORT_TYPE_BOOLEAN));
// INPUT
const String input_param_shader_modes = TTR("'%s' input parameter for all shader modes.");
- // SPATIAL-FOR-ALL
+ // NODE3D-FOR-ALL
- add_options.push_back(AddOption("Camera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "camera"), "camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("InvCamera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_camera"), "inv_camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("InvProjection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_projection"), "inv_projection", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Normal", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "normal"), "normal", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("OutputIsSRGB", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "output_is_srgb"), "output_is_srgb", VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Projection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "projection"), "projection", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("UV", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("UV2", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv2"), "uv2", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("ViewportSize", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "viewport_size"), "viewport_size", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("World", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Camera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "camera"), { "camera" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("InvCamera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_camera"), { "inv_camera" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("InvProjection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_projection"), { "inv_projection" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Normal", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "normal"), { "normal" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("OutputIsSRGB", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "output_is_srgb"), { "output_is_srgb" }, VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Projection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "projection"), { "projection" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), { "time" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("UV", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv"), { "uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, -1, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("UV2", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv2"), { "uv2" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, -1, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ViewportSize", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "viewport_size"), { "viewport_size" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, -1, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("World", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "world"), { "world" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL));
// CANVASITEM-FOR-ALL
- add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("TexturePixelSize", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "texture_pixel_size"), "texture_pixel_size", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("UV", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), { "alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("TexturePixelSize", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "texture_pixel_size"), { "texture_pixel_size" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, -1, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), { "time" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("UV", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv"), { "uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, -1, Shader::MODE_CANVAS_ITEM));
// PARTICLES-FOR-ALL
- add_options.push_back(AddOption("Active", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), "active", VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("AttractorForce", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "attractor_force"), "attractor_force", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Custom", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("CustomAlpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Delta", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("EmissionTransform", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Index", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("LifeTime", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Restart", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), "restart", VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Transform", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("Velocity", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Active", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "active"), { "active" }, VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), { "alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("AttractorForce", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "attractor_force"), { "attractor_force" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Custom", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom"), { "custom" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("CustomAlpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "custom_alpha"), { "custom_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Delta", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "delta"), { "delta" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("EmissionTransform", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "emission_transform"), { "emission_transform" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Index", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "index"), { "index" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("LifeTime", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "lifetime"), { "lifetime" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Restart", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "restart"), { "restart" }, VisualShaderNode::PORT_TYPE_BOOLEAN, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), { "time" }, VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Transform", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "transform"), { "transform" }, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("Velocity", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "velocity"), { "velocity" }, VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_PARTICLES));
/////////////////
@@ -4384,369 +4560,428 @@ VisualShaderEditor::VisualShaderEditor() {
// NODE3D INPUTS
- add_options.push_back(AddOption("Alpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Binormal", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("InstanceId", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_id"), "instance_id", VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("InstanceCustom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom"), "instance_custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("InstanceCustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom_alpha"), "instance_custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("ModelView", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "modelview"), "modelview", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), "point_size", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Tangent", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "tangent"), "tangent", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
-
- add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("DepthTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "depth_texture"), "depth_texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("FrontFacing", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "front_facing"), "front_facing", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), "screen_texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Tangent", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "tangent"), "tangent", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("View", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), "view", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
-
- add_options.push_back(AddOption("Albedo", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "albedo"), "albedo", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Attenuation", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "attenuation"), "attenuation", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Backlight", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "backlight"), "backlight", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Diffuse", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "diffuse"), "diffuse", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), "light", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), "light_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Metallic", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "metallic"), "metallic", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Roughness", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "roughness"), "roughness", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Specular", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "specular"), "specular", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("View", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), "view", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Alpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), { "alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Binormal", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), { "binormal" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("InstanceId", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_id"), { "instance_id" }, VisualShaderNode::PORT_TYPE_SCALAR_INT, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("InstanceCustom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom"), { "instance_custom" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("InstanceCustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom_alpha"), { "instance_custom_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ModelView", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "modelview"), { "modelview" }, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), { "point_size" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Tangent", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "tangent"), { "tangent" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+
+ add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), { "alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), { "binormal" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), { "color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("DepthTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "depth_texture"), { "depth_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("FrontFacing", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "front_facing"), { "front_facing" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "point_coord"), { "point_coord" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), { "screen_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_uv"), { "screen_uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Tangent", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "tangent"), { "tangent" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("View", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), { "view" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_SPATIAL));
+
+ add_options.push_back(AddOption("Albedo", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "albedo"), { "albedo" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Attenuation", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "attenuation"), { "attenuation" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Backlight", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "backlight"), { "backlight" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Diffuse", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "diffuse"), { "diffuse" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), { "light" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), { "light_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Metallic", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "metallic"), { "metallic" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Roughness", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "roughness"), { "roughness" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Specular", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "specular"), { "specular" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("View", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), { "view" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
// CANVASITEM INPUTS
- add_options.push_back(AddOption("AtLightPass", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "at_light_pass"), "at_light_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Canvas", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "canvas"), "canvas", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("InstanceCustom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom"), "instance_custom", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("InstanceCustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom_alpha"), "instance_custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), "point_size", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Screen", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "screen"), "screen", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("World", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
-
- add_options.push_back(AddOption("AtLightPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "at_light_pass"), "at_light_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("NormalTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "normal_texture"), "normal_texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("ScreenPixelSize", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_pixel_size"), "screen_pixel_size", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), "screen_texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("SpecularShininess", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess"), "specular_shininess", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("SpecularShininessAlpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess_alpha"), "specular_shininess_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("SpecularShininessTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "specular_shininess_texture"), "specular_shininess_texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Texture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), "texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
-
- add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), "light", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_alpha"), "light_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), "light_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightColorAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color_alpha"), "light_color_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightPosition", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_position"), "light_position", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightVertex", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "light_vertex"), "light_vertex", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Normal", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "normal"), "normal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("PointCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("ScreenUV", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Shadow", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow"), "shadow", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("ShadowAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_alpha"), "shadow_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("SpecularShininess", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess"), "specular_shininess", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("SpecularShininessAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess_alpha"), "specular_shininess_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("Texture", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), "texture", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("AtLightPass", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "at_light_pass"), { "at_light_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Canvas", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "canvas"), { "canvas" }, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("InstanceCustom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom"), { "instance_custom" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("InstanceCustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "instance_custom_alpha"), { "instance_custom_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), { "point_size" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Screen", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "screen"), { "screen" }, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("World", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "world"), { "world" }, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_CANVAS_ITEM));
+
+ add_options.push_back(AddOption("AtLightPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "at_light_pass"), { "at_light_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("NormalTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "normal_texture"), { "normal_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), { "point_coord" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ScreenPixelSize", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_pixel_size"), { "screen_pixel_size" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ScreenTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_texture"), { "screen_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), { "screen_uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("SpecularShininess", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess"), { "specular_shininess" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("SpecularShininessAlpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess_alpha"), { "specular_shininess_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("SpecularShininessTexture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "specular_shininess_texture"), { "specular_shininess_texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Texture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), { "texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "vertex"), { "vertex" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT, Shader::MODE_CANVAS_ITEM));
+
+ add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), { "fragcoord" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), { "light" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_alpha"), { "light_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), { "light_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightColorAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color_alpha"), { "light_color_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightPosition", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_position"), { "light_position" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightVertex", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "light_vertex"), { "light_vertex" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Normal", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "normal"), { "normal" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("PointCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), { "point_coord" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ScreenUV", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), { "screen_uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Shadow", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow"), { "shadow" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ShadowAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_alpha"), { "shadow_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("SpecularShininess", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess"), { "specular_shininess" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("SpecularShininessAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "specular_shininess_alpha"), { "specular_shininess_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("Texture", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), { "texture" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
// SKY INPUTS
- add_options.push_back(AddOption("AtCubeMapPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_cubemap_pass"), "at_cubemap_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("AtHalfResPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_half_res_pass"), "at_half_res_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("AtQuarterResPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_quarter_res_pass"), "at_quarter_res_pass", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("EyeDir", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "eyedir"), "eyedir", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("HalfResColor", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "half_res_color"), "half_res_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("HalfResAlpha", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "half_res_alpha"), "half_res_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light0Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_color"), "light0_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light0Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_direction"), "light0_direction", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light0Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_enabled"), "light0_enabled", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light0Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_energy"), "light0_energy", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light1Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_color"), "light1_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light1Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_direction"), "light1_direction", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light1Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_enabled"), "light1_enabled", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light1Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_energy"), "light1_energy", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light2Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_color"), "light2_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light2Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_direction"), "light2_direction", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light2Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_enabled"), "light2_enabled", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light2Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_energy"), "light2_energy", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light3Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_color"), "light3_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light3Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_direction"), "light3_direction", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light3Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_enabled"), "light3_enabled", VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Light3Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_energy"), "light3_energy", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Position", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "position"), "position", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("QuarterResColor", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "quarter_res_color"), "quarter_res_color", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("QuarterResAlpha", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "quarter_res_alpha"), "quarter_res_alpha", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Radiance", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "radiance"), "radiance", VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("ScreenUV", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("SkyCoords", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "sky_coords"), "sky_coords", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
- add_options.push_back(AddOption("Time", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("AtCubeMapPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_cubemap_pass"), { "at_cubemap_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("AtHalfResPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_half_res_pass"), { "at_half_res_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("AtQuarterResPass", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "at_quarter_res_pass"), { "at_quarter_res_pass" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("EyeDir", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "eyedir"), { "eyedir" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("HalfResColor", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "half_res_color"), { "half_res_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("HalfResAlpha", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "half_res_alpha"), { "half_res_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light0Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_color"), { "light0_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light0Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_direction"), { "light0_direction" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light0Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_enabled"), { "light0_enabled" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light0Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light0_energy"), { "light0_energy" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light1Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_color"), { "light1_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light1Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_direction"), { "light1_direction" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light1Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_enabled"), { "light1_enabled" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light1Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light1_energy"), { "light1_energy" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light2Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_color"), { "light2_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light2Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_direction"), { "light2_direction" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light2Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_enabled"), { "light2_enabled" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light2Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light2_energy"), { "light2_energy" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light3Color", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_color"), { "light3_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light3Direction", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_direction"), { "light3_direction" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light3Enabled", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_enabled"), { "light3_enabled" }, VisualShaderNode::PORT_TYPE_BOOLEAN, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Light3Energy", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "light3_energy"), { "light3_energy" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Position", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "position"), { "position" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("QuarterResColor", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "quarter_res_color"), { "quarter_res_color" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("QuarterResAlpha", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "quarter_res_alpha"), { "quarter_res_alpha" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Radiance", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "radiance"), { "radiance" }, VisualShaderNode::PORT_TYPE_SAMPLER, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("ScreenUV", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "screen_uv"), { "screen_uv" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("SkyCoords", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "sky_coords"), { "sky_coords" }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_SKY, Shader::MODE_SKY));
+ add_options.push_back(AddOption("Time", "Input", "Sky", "VisualShaderNodeInput", vformat(input_param_for_sky_shader_mode, "time"), { "time" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_SKY, Shader::MODE_SKY));
// FOG INPUTS
- add_options.push_back(AddOption("WorldPosition", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "world_position"), "world_position", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
- add_options.push_back(AddOption("ObjectPosition", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "object_position"), "object_position", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
- add_options.push_back(AddOption("UVW", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "uvw"), "uvw", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
- add_options.push_back(AddOption("Extents", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "extents"), "extents", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
- add_options.push_back(AddOption("SDF", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "sdf"), "sdf", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
- add_options.push_back(AddOption("Time", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
+ add_options.push_back(AddOption("WorldPosition", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "world_position"), { "world_position" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
+ add_options.push_back(AddOption("ObjectPosition", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "object_position"), { "object_position" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
+ add_options.push_back(AddOption("UVW", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "uvw"), { "uvw" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
+ add_options.push_back(AddOption("Extents", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "extents"), { "extents" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
+ add_options.push_back(AddOption("SDF", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "sdf"), { "sdf" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
+ add_options.push_back(AddOption("Time", "Input", "Fog", "VisualShaderNodeInput", vformat(input_param_for_fog_shader_mode, "time"), { "time" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FOG, Shader::MODE_FOG));
// PARTICLES INPUTS
- add_options.push_back(AddOption("CollisionDepth", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_depth"), "collision_depth", VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("CollisionNormal", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_normal"), "collision_normal", VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("CollisionDepth", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_depth"), { "collision_depth" }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("CollisionNormal", "Input", "Collide", "VisualShaderNodeInput", vformat(input_param_for_collide_shader_mode, "collision_normal"), { "collision_normal" }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
// PARTICLES
- add_options.push_back(AddOption("EmitParticle", "Particles", "", "VisualShaderNodeParticleEmit", "", -1, -1, TYPE_FLAGS_PROCESS | TYPE_FLAGS_PROCESS_CUSTOM | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("ParticleAccelerator", "Particles", "", "VisualShaderNodeParticleAccelerator", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("ParticleRandomness", "Particles", "", "VisualShaderNodeParticleRandomness", "", -1, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("MultiplyByAxisAngle", "Particles", "Transform", "VisualShaderNodeParticleMultiplyByAxisAngle", "A node for help to multiply a position input vector by rotation using specific axis. Intended to work with emitters.", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("EmitParticle", "Particles", "", "VisualShaderNodeParticleEmit", "", {}, -1, TYPE_FLAGS_PROCESS | TYPE_FLAGS_PROCESS_CUSTOM | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("ParticleAccelerator", "Particles", "", "VisualShaderNodeParticleAccelerator", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_PROCESS, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("ParticleRandomness", "Particles", "", "VisualShaderNodeParticleRandomness", "", {}, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("MultiplyByAxisAngle", "Particles", "Transform", "VisualShaderNodeParticleMultiplyByAxisAngle", TTR("A node for help to multiply a position input vector by rotation using specific axis. Intended to work with emitters."), {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT | TYPE_FLAGS_PROCESS | TYPE_FLAGS_COLLIDE, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("BoxEmitter", "Particles", "Emitters", "VisualShaderNodeParticleBoxEmitter", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("MeshEmitter", "Particles", "Emitters", "VisualShaderNodeParticleMeshEmitter", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("RingEmitter", "Particles", "Emitters", "VisualShaderNodeParticleRingEmitter", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("SphereEmitter", "Particles", "Emitters", "VisualShaderNodeParticleSphereEmitter", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("BoxEmitter", "Particles", "Emitters", "VisualShaderNodeParticleBoxEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("MeshEmitter", "Particles", "Emitters", "VisualShaderNodeParticleMeshEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("RingEmitter", "Particles", "Emitters", "VisualShaderNodeParticleRingEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("SphereEmitter", "Particles", "Emitters", "VisualShaderNodeParticleSphereEmitter", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
- add_options.push_back(AddOption("ConeVelocity", "Particles", "Velocity", "VisualShaderNodeParticleConeVelocity", "", -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
+ add_options.push_back(AddOption("ConeVelocity", "Particles", "Velocity", "VisualShaderNodeParticleConeVelocity", "", {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_EMIT, Shader::MODE_PARTICLES));
// SCALAR
- add_options.push_back(AddOption("FloatFunc", "Scalar", "Common", "VisualShaderNodeFloatFunc", TTR("Float function."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("IntFunc", "Scalar", "Common", "VisualShaderNodeIntFunc", TTR("Integer function."), -1, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("FloatOp", "Scalar", "Common", "VisualShaderNodeFloatOp", TTR("Float operator."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("IntOp", "Scalar", "Common", "VisualShaderNodeIntOp", TTR("Integer operator."), -1, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("FloatFunc", "Scalar", "Common", "VisualShaderNodeFloatFunc", TTR("Float function."), {}, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("FloatOp", "Scalar", "Common", "VisualShaderNodeFloatOp", TTR("Float operator."), {}, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("IntFunc", "Scalar", "Common", "VisualShaderNodeIntFunc", TTR("Integer function."), {}, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("IntOp", "Scalar", "Common", "VisualShaderNodeIntOp", TTR("Integer operator."), {}, VisualShaderNode::PORT_TYPE_SCALAR_INT));
// CONSTANTS
for (int i = 0; i < MAX_FLOAT_CONST_DEFS; i++) {
- add_options.push_back(AddOption(float_constant_defs[i].name, "Scalar", "Constants", "VisualShaderNodeFloatConstant", float_constant_defs[i].desc, -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, float_constant_defs[i].value));
+ add_options.push_back(AddOption(float_constant_defs[i].name, "Scalar", "Constants", "VisualShaderNodeFloatConstant", float_constant_defs[i].desc, { float_constant_defs[i].value }, VisualShaderNode::PORT_TYPE_SCALAR));
}
// FUNCTIONS
- add_options.push_back(AddOption("Abs", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the absolute value of the parameter."), VisualShaderNodeFloatFunc::FUNC_ABS, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Abs", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the absolute value of the parameter."), VisualShaderNodeIntFunc::FUNC_ABS, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("ACos", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the arc-cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_ACOS, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("ACosH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_ACOSH, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("ASin", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the arc-sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_ASIN, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("ASinH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_ASINH, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("ATan", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the arc-tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_ATAN, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("ATan2", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeFloatOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("BitwiseNOT", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the result of bitwise NOT (~a) operation on the integer."), VisualShaderNodeIntFunc::FUNC_BITWISE_NOT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("Ceil", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeFloatFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_FLOAT, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("Cos", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("CosH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Degrees", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Converts a quantity in radians to degrees."), VisualShaderNodeFloatFunc::FUNC_DEGREES, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Exp", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-e Exponential."), VisualShaderNodeFloatFunc::FUNC_EXP, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Exp2", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-2 Exponential."), VisualShaderNodeFloatFunc::FUNC_EXP2, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Floor", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer less than or equal to the parameter."), VisualShaderNodeFloatFunc::FUNC_FLOOR, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Fract", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Computes the fractional part of the argument."), VisualShaderNodeFloatFunc::FUNC_FRAC, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("InverseSqrt", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse of the square root of the parameter."), VisualShaderNodeFloatFunc::FUNC_INVERSE_SQRT, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Log", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Natural logarithm."), VisualShaderNodeFloatFunc::FUNC_LOG, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Log2", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-2 logarithm."), VisualShaderNodeFloatFunc::FUNC_LOG2, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Max", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the greater of two values."), VisualShaderNodeFloatOp::OP_MAX, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Min", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the lesser of two values."), VisualShaderNodeFloatOp::OP_MIN, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Mix", "Scalar", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two scalars."), VisualShaderNodeMix::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("MultiplyAdd", "Scalar", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on scalars."), VisualShaderNodeMultiplyAdd::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeFloatFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeIntFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("OneMinus", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("1.0 - scalar"), VisualShaderNodeFloatFunc::FUNC_ONEMINUS, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Pow", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the value of the first parameter raised to the power of the second."), VisualShaderNodeFloatOp::OP_POW, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Radians", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Converts a quantity in degrees to radians."), VisualShaderNodeFloatFunc::FUNC_RADIANS, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Reciprocal", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("1.0 / scalar"), VisualShaderNodeFloatFunc::FUNC_RECIPROCAL, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Round", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer to the parameter."), VisualShaderNodeFloatFunc::FUNC_ROUND, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("RoundEven", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest even integer to the parameter."), VisualShaderNodeFloatFunc::FUNC_ROUNDEVEN, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Saturate", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Clamps the value between 0.0 and 1.0."), VisualShaderNodeFloatFunc::FUNC_SATURATE, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Sign", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Extracts the sign of the parameter."), VisualShaderNodeFloatFunc::FUNC_SIGN, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Sign", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Extracts the sign of the parameter."), VisualShaderNodeIntFunc::FUNC_SIGN, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("Sin", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Sqrt", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeFloatFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Tan", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeFloatFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR));
-
- add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Sums two floating-point scalars."), VisualShaderNodeFloatOp::OP_ADD, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Sums two integer scalars."), VisualShaderNodeIntOp::OP_ADD, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("BitwiseAND", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise AND (a & b) operation for two integers."), VisualShaderNodeIntOp::OP_BITWISE_AND, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("BitwiseLeftShift", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise left shift (a << b) operation on the integer."), VisualShaderNodeIntOp::OP_BITWISE_LEFT_SHIFT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("BitwiseOR", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise OR (a | b) operation for two integers."), VisualShaderNodeIntOp::OP_BITWISE_OR, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("BitwiseRightShift", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise right shift (a >> b) operation on the integer."), VisualShaderNodeIntOp::OP_BITWISE_RIGHT_SHIFT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("BitwiseXOR", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise XOR (a ^ b) operation on the integer."), VisualShaderNodeIntOp::OP_BITWISE_XOR, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Divides two floating-point scalars."), VisualShaderNodeFloatOp::OP_DIV, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Divides two integer scalars."), VisualShaderNodeIntOp::OP_DIV, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("Multiply", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Multiplies two floating-point scalars."), VisualShaderNodeFloatOp::OP_MUL, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Multiply", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Multiplies two integer scalars."), VisualShaderNodeIntOp::OP_MUL, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("Remainder", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Returns the remainder of the two floating-point scalars."), VisualShaderNodeFloatOp::OP_MOD, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Remainder", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the remainder of the two integer scalars."), VisualShaderNodeIntOp::OP_MOD, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("Subtract", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Subtracts two floating-point scalars."), VisualShaderNodeFloatOp::OP_SUB, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Subtract", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Subtracts two integer scalars."), VisualShaderNodeIntOp::OP_SUB, VisualShaderNode::PORT_TYPE_SCALAR_INT));
-
- add_options.push_back(AddOption("FloatConstant", "Scalar", "Variables", "VisualShaderNodeFloatConstant", TTR("Scalar floating-point constant."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("IntConstant", "Scalar", "Variables", "VisualShaderNodeIntConstant", TTR("Scalar integer constant."), -1, VisualShaderNode::PORT_TYPE_SCALAR_INT));
- add_options.push_back(AddOption("FloatUniform", "Scalar", "Variables", "VisualShaderNodeFloatUniform", TTR("Scalar floating-point uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("IntUniform", "Scalar", "Variables", "VisualShaderNodeIntUniform", TTR("Scalar integer uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("Abs", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the absolute value of the parameter."), { VisualShaderNodeFloatFunc::FUNC_ABS }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Abs", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the absolute value of the parameter."), { VisualShaderNodeIntFunc::FUNC_ABS }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("ACos", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the arc-cosine of the parameter."), { VisualShaderNodeFloatFunc::FUNC_ACOS }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("ACosH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), { VisualShaderNodeFloatFunc::FUNC_ACOSH }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("ASin", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the arc-sine of the parameter."), { VisualShaderNodeFloatFunc::FUNC_ASIN }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("ASinH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), { VisualShaderNodeFloatFunc::FUNC_ASINH }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("ATan", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the arc-tangent of the parameter."), { VisualShaderNodeFloatFunc::FUNC_ATAN }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("ATan2", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the arc-tangent of the parameters."), { VisualShaderNodeFloatOp::OP_ATAN2 }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), { VisualShaderNodeFloatFunc::FUNC_ATANH }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("BitwiseNOT", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the result of bitwise NOT (~a) operation on the integer."), { VisualShaderNodeIntFunc::FUNC_BITWISE_NOT }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("Ceil", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), { VisualShaderNodeFloatFunc::FUNC_CEIL }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), { VisualShaderNodeClamp::OP_TYPE_FLOAT }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), { VisualShaderNodeClamp::OP_TYPE_INT }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("Cos", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the cosine of the parameter."), { VisualShaderNodeFloatFunc::FUNC_COS }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("CosH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic cosine of the parameter."), { VisualShaderNodeFloatFunc::FUNC_COSH }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Degrees", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Converts a quantity in radians to degrees."), { VisualShaderNodeFloatFunc::FUNC_DEGREES }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("DFdX", "Scalar", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Scalar) Derivative in 'x' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_X, VisualShaderNodeDerivativeFunc::OP_TYPE_SCALAR }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
+ add_options.push_back(AddOption("DFdY", "Scalar", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Scalar) Derivative in 'y' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_Y, VisualShaderNodeDerivativeFunc::OP_TYPE_SCALAR }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
+ add_options.push_back(AddOption("Exp", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-e Exponential."), { VisualShaderNodeFloatFunc::FUNC_EXP }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Exp2", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-2 Exponential."), { VisualShaderNodeFloatFunc::FUNC_EXP2 }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Floor", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer less than or equal to the parameter."), { VisualShaderNodeFloatFunc::FUNC_FLOOR }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Fract", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeFloatFunc::FUNC_FRAC }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("InverseSqrt", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeFloatFunc::FUNC_INVERSE_SQRT }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Log", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Natural logarithm."), { VisualShaderNodeFloatFunc::FUNC_LOG }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Log2", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-2 logarithm."), { VisualShaderNodeFloatFunc::FUNC_LOG2 }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Max", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the greater of two values."), { VisualShaderNodeFloatOp::OP_MAX }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Min", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the lesser of two values."), { VisualShaderNodeFloatOp::OP_MIN }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Mix", "Scalar", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two scalars."), { VisualShaderNodeMix::OP_TYPE_SCALAR }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("MultiplyAdd", "Scalar", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on scalars."), { VisualShaderNodeMultiplyAdd::OP_TYPE_SCALAR }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeFloatFunc::FUNC_NEGATE }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeIntFunc::FUNC_NEGATE }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("OneMinus", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("1.0 - scalar"), { VisualShaderNodeFloatFunc::FUNC_ONEMINUS }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Pow", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeFloatOp::OP_POW }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Radians", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Converts a quantity in degrees to radians."), { VisualShaderNodeFloatFunc::FUNC_RADIANS }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Reciprocal", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("1.0 / scalar"), { VisualShaderNodeFloatFunc::FUNC_RECIPROCAL }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Round", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer to the parameter."), { VisualShaderNodeFloatFunc::FUNC_ROUND }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("RoundEven", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest even integer to the parameter."), { VisualShaderNodeFloatFunc::FUNC_ROUNDEVEN }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Saturate", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Clamps the value between 0.0 and 1.0."), { VisualShaderNodeFloatFunc::FUNC_SATURATE }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Sign", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Extracts the sign of the parameter."), { VisualShaderNodeFloatFunc::FUNC_SIGN }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Sign", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Extracts the sign of the parameter."), { VisualShaderNodeIntFunc::FUNC_SIGN }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("Sin", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the sine of the parameter."), { VisualShaderNodeFloatFunc::FUNC_SIN }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic sine of the parameter."), { VisualShaderNodeFloatFunc::FUNC_SINH }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Sqrt", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the square root of the parameter."), { VisualShaderNodeFloatFunc::FUNC_SQRT }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_SCALAR }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_SCALAR }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Sum", "Scalar", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_SCALAR }, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
+ add_options.push_back(AddOption("Tan", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the tangent of the parameter."), { VisualShaderNodeFloatFunc::FUNC_TAN }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic tangent of the parameter."), { VisualShaderNodeFloatFunc::FUNC_TANH }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the truncated value of the parameter."), { VisualShaderNodeFloatFunc::FUNC_TRUNC }, VisualShaderNode::PORT_TYPE_SCALAR));
+
+ add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Sums two floating-point scalars."), { VisualShaderNodeFloatOp::OP_ADD }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Sums two integer scalars."), { VisualShaderNodeIntOp::OP_ADD }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseAND", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise AND (a & b) operation for two integers."), { VisualShaderNodeIntOp::OP_BITWISE_AND }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseLeftShift", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise left shift (a << b) operation on the integer."), { VisualShaderNodeIntOp::OP_BITWISE_LEFT_SHIFT }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseOR", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise OR (a | b) operation for two integers."), { VisualShaderNodeIntOp::OP_BITWISE_OR }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseRightShift", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise right shift (a >> b) operation on the integer."), { VisualShaderNodeIntOp::OP_BITWISE_RIGHT_SHIFT }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseXOR", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise XOR (a ^ b) operation on the integer."), { VisualShaderNodeIntOp::OP_BITWISE_XOR }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Divides two floating-point scalars."), { VisualShaderNodeFloatOp::OP_DIV }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Divides two integer scalars."), { VisualShaderNodeIntOp::OP_DIV }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("Multiply", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Multiplies two floating-point scalars."), { VisualShaderNodeFloatOp::OP_MUL }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Multiply", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Multiplies two integer scalars."), { VisualShaderNodeIntOp::OP_MUL }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("Remainder", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Returns the remainder of the two floating-point scalars."), { VisualShaderNodeFloatOp::OP_MOD }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Remainder", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the remainder of the two integer scalars."), { VisualShaderNodeIntOp::OP_MOD }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("Subtract", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Subtracts two floating-point scalars."), { VisualShaderNodeFloatOp::OP_SUB }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Subtract", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Subtracts two integer scalars."), { VisualShaderNodeIntOp::OP_SUB }, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+
+ add_options.push_back(AddOption("FloatConstant", "Scalar", "Variables", "VisualShaderNodeFloatConstant", TTR("Scalar floating-point constant."), {}, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("IntConstant", "Scalar", "Variables", "VisualShaderNodeIntConstant", TTR("Scalar integer constant."), {}, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("FloatUniform", "Scalar", "Variables", "VisualShaderNodeFloatUniform", TTR("Scalar floating-point uniform."), {}, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("IntUniform", "Scalar", "Variables", "VisualShaderNodeIntUniform", TTR("Scalar integer uniform."), {}, VisualShaderNode::PORT_TYPE_SCALAR_INT));
// SDF
{
- add_options.push_back(AddOption("ScreenUVToSDF", "SDF", "", "VisualShaderNodeScreenUVToSDF", TTR("Converts screen UV to a SDF."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("SDFRaymarch", "SDF", "", "VisualShaderNodeSDFRaymarch", TTR("Casts a ray against the screen SDF and returns the distance travelled."), -1, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("SDFToScreenUV", "SDF", "", "VisualShaderNodeSDFToScreenUV", TTR("Converts a SDF to screen UV."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("TextureSDF", "SDF", "", "VisualShaderNodeTextureSDF", TTR("Performs a SDF texture lookup."), -1, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("TextureSDFNormal", "SDF", "", "VisualShaderNodeTextureSDFNormal", TTR("Performs a SDF normal texture lookup."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ScreenUVToSDF", "SDF", "", "VisualShaderNodeScreenUVToSDF", TTR("Converts screen UV to a SDF."), {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("SDFRaymarch", "SDF", "", "VisualShaderNodeSDFRaymarch", TTR("Casts a ray against the screen SDF and returns the distance travelled."), {}, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("SDFToScreenUV", "SDF", "", "VisualShaderNodeSDFToScreenUV", TTR("Converts a SDF to screen UV."), {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("TextureSDF", "SDF", "", "VisualShaderNodeTextureSDF", TTR("Performs a SDF texture lookup."), {}, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("TextureSDFNormal", "SDF", "", "VisualShaderNodeTextureSDFNormal", TTR("Performs a SDF normal texture lookup."), {}, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
}
// TEXTURES
- add_options.push_back(AddOption("UVFunc", "Textures", "Common", "VisualShaderNodeUVFunc", TTR("Function to be applied on texture coordinates."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("UVFunc", "Textures", "Common", "VisualShaderNodeUVFunc", TTR("Function to be applied on texture coordinates."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D));
cubemap_node_option_idx = add_options.size();
- add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup."), -1, -1));
+ add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup.")));
curve_node_option_idx = add_options.size();
- add_options.push_back(AddOption("CurveTexture", "Textures", "Functions", "VisualShaderNodeCurveTexture", TTR("Perform the curve texture lookup."), -1, -1));
+ add_options.push_back(AddOption("CurveTexture", "Textures", "Functions", "VisualShaderNodeCurveTexture", TTR("Perform the curve texture lookup.")));
curve_xyz_node_option_idx = add_options.size();
- add_options.push_back(AddOption("CurveXYZTexture", "Textures", "Functions", "VisualShaderNodeCurveXYZTexture", TTR("Perform the three components curve texture lookup."), -1, -1));
+ add_options.push_back(AddOption("CurveXYZTexture", "Textures", "Functions", "VisualShaderNodeCurveXYZTexture", TTR("Perform the three components curve texture lookup.")));
texture2d_node_option_idx = add_options.size();
- add_options.push_back(AddOption("Texture2D", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the 2D texture lookup."), -1, -1));
+ add_options.push_back(AddOption("Texture2D", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the 2D texture lookup.")));
texture2d_array_node_option_idx = add_options.size();
- add_options.push_back(AddOption("Texture2DArray", "Textures", "Functions", "VisualShaderNodeTexture2DArray", TTR("Perform the 2D-array texture lookup."), -1, -1, -1, -1, -1));
+ add_options.push_back(AddOption("Texture2DArray", "Textures", "Functions", "VisualShaderNodeTexture2DArray", TTR("Perform the 2D-array texture lookup.")));
texture3d_node_option_idx = add_options.size();
- add_options.push_back(AddOption("Texture3D", "Textures", "Functions", "VisualShaderNodeTexture3D", TTR("Perform the 3D texture lookup."), -1, -1));
- add_options.push_back(AddOption("UVPanning", "Textures", "Functions", "VisualShaderNodeUVFunc", TTR("Apply panning function on texture coordinates."), VisualShaderNodeUVFunc::FUNC_PANNING, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("UVScaling", "Textures", "Functions", "VisualShaderNodeUVFunc", TTR("Apply scaling function on texture coordinates."), VisualShaderNodeUVFunc::FUNC_SCALING, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Texture3D", "Textures", "Functions", "VisualShaderNodeTexture3D", TTR("Perform the 3D texture lookup.")));
+ add_options.push_back(AddOption("UVPanning", "Textures", "Functions", "VisualShaderNodeUVFunc", TTR("Apply panning function on texture coordinates."), { VisualShaderNodeUVFunc::FUNC_PANNING }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("UVScaling", "Textures", "Functions", "VisualShaderNodeUVFunc", TTR("Apply scaling function on texture coordinates."), { VisualShaderNodeUVFunc::FUNC_SCALING }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
- add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubemapUniform", TTR("Cubic texture uniform lookup."), -1, -1));
- add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), -1, -1));
- add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), -1, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Texture2DArrayUniform", "Textures", "Variables", "VisualShaderNodeTexture2DArrayUniform", TTR("2D array of textures uniform lookup."), -1, -1, -1, -1, -1));
- add_options.push_back(AddOption("Texture3DUniform", "Textures", "Variables", "VisualShaderNodeTexture3DUniform", TTR("3D texture uniform lookup."), -1, -1, -1, -1, -1));
+ add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubemapUniform", TTR("Cubic texture uniform lookup.")));
+ add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup.")));
+ add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), {}, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Texture2DArrayUniform", "Textures", "Variables", "VisualShaderNodeTexture2DArrayUniform", TTR("2D array of textures uniform lookup.")));
+ add_options.push_back(AddOption("Texture3DUniform", "Textures", "Variables", "VisualShaderNodeTexture3DUniform", TTR("3D texture uniform lookup.")));
// TRANSFORM
- add_options.push_back(AddOption("TransformFunc", "Transform", "Common", "VisualShaderNodeTransformFunc", TTR("Transform function."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM));
- add_options.push_back(AddOption("TransformOp", "Transform", "Common", "VisualShaderNodeTransformOp", TTR("Transform operator."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM));
+ add_options.push_back(AddOption("TransformFunc", "Transform", "Common", "VisualShaderNodeTransformFunc", TTR("Transform function."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM));
+ add_options.push_back(AddOption("TransformOp", "Transform", "Common", "VisualShaderNodeTransformOp", TTR("Transform operator."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM));
- add_options.push_back(AddOption("OuterProduct", "Transform", "Composition", "VisualShaderNodeOuterProduct", TTR("Calculate the outer product of a pair of vectors.\n\nOuterProduct treats the first parameter 'c' as a column vector (matrix with one column) and the second parameter 'r' as a row vector (matrix with one row) and does a linear algebraic matrix multiply 'c * r', yielding a matrix whose number of rows is the number of components in 'c' and whose number of columns is the number of components in 'r'."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM));
- add_options.push_back(AddOption("TransformCompose", "Transform", "Composition", "VisualShaderNodeTransformCompose", TTR("Composes transform from four vectors."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM));
+ add_options.push_back(AddOption("OuterProduct", "Transform", "Composition", "VisualShaderNodeOuterProduct", TTR("Calculate the outer product of a pair of vectors.\n\nOuterProduct treats the first parameter 'c' as a column vector (matrix with one column) and the second parameter 'r' as a row vector (matrix with one row) and does a linear algebraic matrix multiply 'c * r', yielding a matrix whose number of rows is the number of components in 'c' and whose number of columns is the number of components in 'r'."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM));
+ add_options.push_back(AddOption("TransformCompose", "Transform", "Composition", "VisualShaderNodeTransformCompose", TTR("Composes transform from four vectors."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM));
add_options.push_back(AddOption("TransformDecompose", "Transform", "Composition", "VisualShaderNodeTransformDecompose", TTR("Decomposes transform to four vectors.")));
- add_options.push_back(AddOption("Determinant", "Transform", "Functions", "VisualShaderNodeDeterminant", TTR("Calculates the determinant of a transform."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("GetBillboardMatrix", "Transform", "Functions", "VisualShaderNodeBillboard", TTR("Calculates how the object should face the camera to be applied on Model View Matrix output port for 3D objects."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
- add_options.push_back(AddOption("Inverse", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the inverse of a transform."), VisualShaderNodeTransformFunc::FUNC_INVERSE, VisualShaderNode::PORT_TYPE_TRANSFORM));
- add_options.push_back(AddOption("Transpose", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the transpose of a transform."), VisualShaderNodeTransformFunc::FUNC_TRANSPOSE, VisualShaderNode::PORT_TYPE_TRANSFORM));
+ add_options.push_back(AddOption("Determinant", "Transform", "Functions", "VisualShaderNodeDeterminant", TTR("Calculates the determinant of a transform."), {}, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("GetBillboardMatrix", "Transform", "Functions", "VisualShaderNodeBillboard", TTR("Calculates how the object should face the camera to be applied on Model View Matrix output port for 3D objects."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM, TYPE_FLAGS_VERTEX, Shader::MODE_SPATIAL));
+ add_options.push_back(AddOption("Inverse", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the inverse of a transform."), { VisualShaderNodeTransformFunc::FUNC_INVERSE }, VisualShaderNode::PORT_TYPE_TRANSFORM));
+ add_options.push_back(AddOption("Transpose", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the transpose of a transform."), { VisualShaderNodeTransformFunc::FUNC_TRANSPOSE }, VisualShaderNode::PORT_TYPE_TRANSFORM));
- add_options.push_back(AddOption("Add", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Sums two transforms."), VisualShaderNodeTransformOp::OP_ADD, VisualShaderNode::PORT_TYPE_TRANSFORM));
- add_options.push_back(AddOption("Divide", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Divides two transforms."), VisualShaderNodeTransformOp::OP_A_DIV_B, VisualShaderNode::PORT_TYPE_TRANSFORM));
- add_options.push_back(AddOption("Multiply", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Multiplies two transforms."), VisualShaderNodeTransformOp::OP_AxB, VisualShaderNode::PORT_TYPE_TRANSFORM));
- add_options.push_back(AddOption("MultiplyComp", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Performs per-component multiplication of two transforms."), VisualShaderNodeTransformOp::OP_AxB_COMP, VisualShaderNode::PORT_TYPE_TRANSFORM));
- add_options.push_back(AddOption("Subtract", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Subtracts two transforms."), VisualShaderNodeTransformOp::OP_A_MINUS_B, VisualShaderNode::PORT_TYPE_TRANSFORM));
- add_options.push_back(AddOption("TransformVectorMult", "Transform", "Operators", "VisualShaderNodeTransformVecMult", TTR("Multiplies vector by transform."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Add", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Sums two transforms."), { VisualShaderNodeTransformOp::OP_ADD }, VisualShaderNode::PORT_TYPE_TRANSFORM));
+ add_options.push_back(AddOption("Divide", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Divides two transforms."), { VisualShaderNodeTransformOp::OP_A_DIV_B }, VisualShaderNode::PORT_TYPE_TRANSFORM));
+ add_options.push_back(AddOption("Multiply", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Multiplies two transforms."), { VisualShaderNodeTransformOp::OP_AxB }, VisualShaderNode::PORT_TYPE_TRANSFORM));
+ add_options.push_back(AddOption("MultiplyComp", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Performs per-component multiplication of two transforms."), { VisualShaderNodeTransformOp::OP_AxB_COMP }, VisualShaderNode::PORT_TYPE_TRANSFORM));
+ add_options.push_back(AddOption("Subtract", "Transform", "Operators", "VisualShaderNodeTransformOp", TTR("Subtracts two transforms."), { VisualShaderNodeTransformOp::OP_A_MINUS_B }, VisualShaderNode::PORT_TYPE_TRANSFORM));
+ add_options.push_back(AddOption("TransformVectorMult", "Transform", "Operators", "VisualShaderNodeTransformVecMult", TTR("Multiplies vector by transform."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("TransformConstant", "Transform", "Variables", "VisualShaderNodeTransformConstant", TTR("Transform constant."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM));
- add_options.push_back(AddOption("TransformUniform", "Transform", "Variables", "VisualShaderNodeTransformUniform", TTR("Transform uniform."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM));
+ add_options.push_back(AddOption("TransformConstant", "Transform", "Variables", "VisualShaderNodeTransformConstant", TTR("Transform constant."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM));
+ add_options.push_back(AddOption("TransformUniform", "Transform", "Variables", "VisualShaderNodeTransformUniform", TTR("Transform uniform."), {}, VisualShaderNode::PORT_TYPE_TRANSFORM));
// VECTOR
- add_options.push_back(AddOption("VectorFunc", "Vector", "Common", "VisualShaderNodeVectorFunc", TTR("Vector function."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("VectorOp", "Vector", "Common", "VisualShaderNodeVectorOp", TTR("Vector operator."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
-
- add_options.push_back(AddOption("VectorCompose", "Vector", "Composition", "VisualShaderNodeVectorCompose", TTR("Composes vector from three scalars."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("VectorDecompose", "Vector", "Composition", "VisualShaderNodeVectorDecompose", TTR("Decomposes vector to three scalars.")));
-
- add_options.push_back(AddOption("Abs", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the absolute value of the parameter."), VisualShaderNodeVectorFunc::FUNC_ABS, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ACos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ACOS, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ACosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ACOSH, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ASin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ASIN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ASinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ASINH, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ATan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_ATAN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ATan2", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeVectorOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Ceil", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeVectorFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Cos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Cross", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Calculates the cross product of two vectors."), VisualShaderNodeVectorOp::OP_CROSS, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Degrees", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in radians to degrees."), VisualShaderNodeVectorFunc::FUNC_DEGREES, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Distance", "Vector", "Functions", "VisualShaderNodeVectorDistance", TTR("Returns the distance between two points."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Dot", "Vector", "Functions", "VisualShaderNodeDotProduct", TTR("Calculates the dot product of two vectors."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Exp", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-e Exponential."), VisualShaderNodeVectorFunc::FUNC_EXP, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Exp2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 Exponential."), VisualShaderNodeVectorFunc::FUNC_EXP2, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("FaceForward", "Vector", "Functions", "VisualShaderNodeFaceForward", TTR("Returns the vector that points in the same direction as a reference vector. The function has three vector parameters : N, the vector to orient, I, the incident vector, and Nref, the reference vector. If the dot product of I and Nref is smaller than zero the return value is N. Otherwise -N is returned."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Floor", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer less than or equal to the parameter."), VisualShaderNodeVectorFunc::FUNC_FLOOR, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), VisualShaderNodeVectorFunc::FUNC_FRAC, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Length", "Vector", "Functions", "VisualShaderNodeVectorLen", TTR("Calculates the length of a vector."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
- add_options.push_back(AddOption("Log", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Natural logarithm."), VisualShaderNodeVectorFunc::FUNC_LOG, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Log2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 logarithm."), VisualShaderNodeVectorFunc::FUNC_LOG2, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), VisualShaderNodeVectorOp::OP_MAX, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), VisualShaderNodeVectorOp::OP_MIN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors."), VisualShaderNodeMix::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), VisualShaderNodeMix::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("MultiplyAdd", "Vector", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("OneMinus", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Pow", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), VisualShaderNodeVectorOp::OP_POW, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Radians", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in degrees to radians."), VisualShaderNodeVectorFunc::FUNC_RADIANS, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Reciprocal", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 / vector"), VisualShaderNodeVectorFunc::FUNC_RECIPROCAL, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Reflect", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the vector that points in the direction of reflection ( a : incident vector, b : normal vector )."), VisualShaderNodeVectorOp::OP_REFLECT, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Refract", "Vector", "Functions", "VisualShaderNodeVectorRefract", TTR("Returns the vector that points in the direction of refraction."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer to the parameter."), VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("RoundEven", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest even integer to the parameter."), VisualShaderNodeVectorFunc::FUNC_ROUNDEVEN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Saturate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Clamps the value between 0.0 and 1.0."), VisualShaderNodeVectorFunc::FUNC_SATURATE, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Sign", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Extracts the sign of the parameter."), VisualShaderNodeVectorFunc::FUNC_SIGN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeStep::OP_TYPE_VECTOR_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_VECTOR));
-
- add_options.push_back(AddOption("Add", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Adds vector to vector."), VisualShaderNodeVectorOp::OP_ADD, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Divide", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Divides vector by vector."), VisualShaderNodeVectorOp::OP_DIV, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Multiply", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Multiplies vector by vector."), VisualShaderNodeVectorOp::OP_MUL, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Remainder", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Returns the remainder of the two vectors."), VisualShaderNodeVectorOp::OP_MOD, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("Subtract", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Subtracts vector from vector."), VisualShaderNodeVectorOp::OP_SUB, VisualShaderNode::PORT_TYPE_VECTOR));
-
- add_options.push_back(AddOption("VectorConstant", "Vector", "Variables", "VisualShaderNodeVec3Constant", TTR("Vector constant."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
- add_options.push_back(AddOption("VectorUniform", "Vector", "Variables", "VisualShaderNodeVec3Uniform", TTR("Vector uniform."), -1, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("VectorFunc", "Vector", "Common", "VisualShaderNodeVectorFunc", TTR("Vector function."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("VectorOp", "Vector", "Common", "VisualShaderNodeVectorOp", TTR("Vector operator."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("VectorCompose", "Vector", "Common", "VisualShaderNodeVectorCompose", TTR("Composes vector from three scalars.")));
+ add_options.push_back(AddOption("VectorDecompose", "Vector", "Common", "VisualShaderNodeVectorDecompose", TTR("Decomposes vector to three scalars.")));
+
+ add_options.push_back(AddOption("Vector2Compose", "Vector", "Composition", "VisualShaderNodeVectorCompose", TTR("Composes 2D vector from three scalars."), { VisualShaderNodeVectorCompose::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Vector2Decompose", "Vector", "Composition", "VisualShaderNodeVectorDecompose", TTR("Decomposes 2D vector to three scalars."), { VisualShaderNodeVectorCompose::OP_TYPE_VECTOR_2D }));
+ add_options.push_back(AddOption("Vector3Compose", "Vector", "Composition", "VisualShaderNodeVectorCompose", TTR("Composes 3D vector from three scalars."), { VisualShaderNodeVectorCompose::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Vector3Decompose", "Vector", "Composition", "VisualShaderNodeVectorDecompose", TTR("Decomposes 3D vector to three scalars."), { VisualShaderNodeVectorCompose::OP_TYPE_VECTOR_3D }));
+
+ add_options.push_back(AddOption("Abs", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the absolute value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ABS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Abs", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the absolute value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ABS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ACos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("ACos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ACosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("ACosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ACOSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ASin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("ASin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ASinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("ASinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ASINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ATan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("ATan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ATan2", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the arc-tangent of the parameters."), { VisualShaderNodeVectorOp::OP_ATAN2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("ATan2", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the arc-tangent of the parameters."), { VisualShaderNodeVectorOp::OP_ATAN2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("ATanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_ATANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Ceil", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_CEIL }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Ceil", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_CEIL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), { VisualShaderNodeClamp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Clamp", "Vector", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), { VisualShaderNodeClamp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Cos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Cos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("CosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic cosine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_COSH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Cross", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Calculates the cross product of two vectors."), { VisualShaderNodeVectorOp::OP_CROSS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Degrees", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in radians to degrees."), { VisualShaderNodeVectorFunc::FUNC_DEGREES, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Degrees", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in radians to degrees."), { VisualShaderNodeVectorFunc::FUNC_DEGREES, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("DFdX", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'x' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_X, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
+ add_options.push_back(AddOption("DFdX", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'x' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_X, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
+ add_options.push_back(AddOption("DFdY", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'y' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_Y, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
+ add_options.push_back(AddOption("DFdY", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'y' using local differencing."), { VisualShaderNodeDerivativeFunc::FUNC_Y, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
+ add_options.push_back(AddOption("Distance2D", "Vector", "Functions", "VisualShaderNodeVectorDistance", TTR("Returns the distance between two points."), { VisualShaderNodeVectorDistance::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Distance3D", "Vector", "Functions", "VisualShaderNodeVectorDistance", TTR("Returns the distance between two points."), { VisualShaderNodeVectorDistance::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Dot", "Vector", "Functions", "VisualShaderNodeDotProduct", TTR("Calculates the dot product of two vectors."), {}, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Exp", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-e Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Exp", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-e Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Exp2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Exp2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 Exponential."), { VisualShaderNodeVectorFunc::FUNC_EXP2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("FaceForward", "Vector", "Functions", "VisualShaderNodeFaceForward", TTR("Returns the vector that points in the same direction as a reference vector. The function has three vector parameters : N, the vector to orient, I, the incident vector, and Nref, the reference vector. If the dot product of I and Nref is smaller than zero the return value is N. Otherwise -N is returned."), { VisualShaderNodeFaceForward::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("FaceForward", "Vector", "Functions", "VisualShaderNodeFaceForward", TTR("Returns the vector that points in the same direction as a reference vector. The function has three vector parameters : N, the vector to orient, I, the incident vector, and Nref, the reference vector. If the dot product of I and Nref is smaller than zero the return value is N. Otherwise -N is returned."), { VisualShaderNodeFaceForward::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Floor", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer less than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_FLOOR, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Floor", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer less than or equal to the parameter."), { VisualShaderNodeVectorFunc::FUNC_FLOOR, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeVectorFunc::FUNC_FRAC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), { VisualShaderNodeVectorFunc::FUNC_FRAC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Fresnel", "Vector", "Functions", "VisualShaderNodeFresnel", TTR("Returns falloff based on the dot product of surface normal and view direction of camera (pass associated inputs to it)."), {}, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Length", "Vector", "Functions", "VisualShaderNodeVectorLen", TTR("Calculates the length of a vector."), { VisualShaderNodeVectorLen::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Length", "Vector", "Functions", "VisualShaderNodeVectorLen", TTR("Calculates the length of a vector."), { VisualShaderNodeVectorLen::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("Log", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Natural logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Log", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Natural logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Log2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Log2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG2, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), { VisualShaderNodeVectorOp::OP_MAX, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Max", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the greater of two values."), { VisualShaderNodeVectorOp::OP_MAX, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), { VisualShaderNodeVectorOp::OP_MIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Min", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the lesser of two values."), { VisualShaderNodeVectorOp::OP_MIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors."), { VisualShaderNodeMix::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Mix", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors."), { VisualShaderNodeMix::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), { VisualShaderNodeMix::OP_TYPE_VECTOR_2D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("MixS", "Vector", "Functions", "VisualShaderNodeMix", TTR("Linear interpolation between two vectors using scalar."), { VisualShaderNodeMix::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("MultiplyAdd", "Vector", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), { VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("MultiplyAdd", "Vector", "Functions", "VisualShaderNodeMultiplyAdd", TTR("Performs a fused multiply-add operation (a * b + c) on vectors."), { VisualShaderNodeMultiplyAdd::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Negate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the opposite value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_NEGATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), { VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Normalize", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Calculates the normalize product of vector."), { VisualShaderNodeVectorFunc::FUNC_NORMALIZE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("OneMinus", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), { VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("OneMinus", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 - vector"), { VisualShaderNodeVectorFunc::FUNC_ONEMINUS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Pow", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeVectorOp::OP_POW, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Pow", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), { VisualShaderNodeVectorOp::OP_POW, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Radians", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in degrees to radians."), { VisualShaderNodeVectorFunc::FUNC_RADIANS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Radians", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in degrees to radians."), { VisualShaderNodeVectorFunc::FUNC_RADIANS, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Reciprocal", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 / vector"), { VisualShaderNodeVectorFunc::FUNC_RECIPROCAL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Reciprocal", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 / vector"), { VisualShaderNodeVectorFunc::FUNC_RECIPROCAL, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Reflect", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the vector that points in the direction of reflection ( a : incident vector, b : normal vector )."), { VisualShaderNodeVectorOp::OP_REFLECT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Refract", "Vector", "Functions", "VisualShaderNodeVectorRefract", TTR("Returns the vector that points in the direction of refraction."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("RoundEven", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest even integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUNDEVEN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("RoundEven", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest even integer to the parameter."), { VisualShaderNodeVectorFunc::FUNC_ROUNDEVEN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Saturate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Clamps the value between 0.0 and 1.0."), { VisualShaderNodeVectorFunc::FUNC_SATURATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Saturate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Clamps the value between 0.0 and 1.0."), { VisualShaderNodeVectorFunc::FUNC_SATURATE, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Sign", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Extracts the sign of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIGN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Sign", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Extracts the sign of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIGN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Sin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SIN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("SinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic sine of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SINH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Sqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("SmoothStep", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_2D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("SmoothStepS", "Vector", "Functions", "VisualShaderNodeSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if 'x' is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), { VisualShaderNodeSmoothStep::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Step", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( vector(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_2D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("StepS", "Vector", "Functions", "VisualShaderNodeStep", TTR("Step function( scalar(edge), vector(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), { VisualShaderNodeStep::OP_TYPE_VECTOR_3D_SCALAR }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Sum", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
+ add_options.push_back(AddOption("Sum", "Vector", "Functions", "VisualShaderNodeDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), { VisualShaderNodeDerivativeFunc::FUNC_SUM, VisualShaderNodeDerivativeFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, true));
+ add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Tan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TAN, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("TanH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the hyperbolic tangent of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), { VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+
+ add_options.push_back(AddOption("Add", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Adds 2D vector to 2D vector."), { VisualShaderNodeVectorOp::OP_ADD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Add", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Adds 3D vector to 3D vector."), { VisualShaderNodeVectorOp::OP_ADD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Divide", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Divides 2D vector by 2D vector."), { VisualShaderNodeVectorOp::OP_DIV, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Divide", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Divides 3D vector by 3D vector."), { VisualShaderNodeVectorOp::OP_DIV, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Multiply", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Multiplies 2D vector by 2D vector."), { VisualShaderNodeVectorOp::OP_MUL, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Multiply", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Multiplies 3D vector by 3D vector."), { VisualShaderNodeVectorOp::OP_MUL, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Remainder", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Returns the remainder of the two 2D vectors."), { VisualShaderNodeVectorOp::OP_MOD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Remainder", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Returns the remainder of the two 3D vectors."), { VisualShaderNodeVectorOp::OP_MOD, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Subtract", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 2D vector from 2D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Subtract", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Subtracts 3D vector from 3D vector."), { VisualShaderNodeVectorOp::OP_SUB, VisualShaderNodeVectorOp::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR));
+
+ add_options.push_back(AddOption("Vector2Constant", "Vector", "Variables", "VisualShaderNodeVec2Constant", TTR("2D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Vector3Constant", "Vector", "Variables", "VisualShaderNodeVec3Constant", TTR("3D vector constant."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
+ add_options.push_back(AddOption("Vector2Uniform", "Vector", "Variables", "VisualShaderNodeVec2Uniform", TTR("2D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR_2D));
+ add_options.push_back(AddOption("Vector3Uniform", "Vector", "Variables", "VisualShaderNodeVec3Uniform", TTR("3D vector uniform."), {}, VisualShaderNode::PORT_TYPE_VECTOR));
// SPECIAL
add_options.push_back(AddOption("Comment", "Special", "", "VisualShaderNodeComment", TTR("A rectangular area with a description string for better graph organization.")));
add_options.push_back(AddOption("Expression", "Special", "", "VisualShaderNodeExpression", TTR("Custom Godot Shader Language expression, with custom amount of input and output ports. This is a direct injection of code into the vertex/fragment/light function, do not use it to write the function declarations inside.")));
- add_options.push_back(AddOption("Fresnel", "Special", "", "VisualShaderNodeFresnel", TTR("Returns falloff based on the dot product of surface normal and view direction of camera (pass associated inputs to it)."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("GlobalExpression", "Special", "", "VisualShaderNodeGlobalExpression", TTR("Custom Godot Shader Language expression, which is placed on top of the resulted shader. You can place various function definitions inside and call it later in the Expressions. You can also declare varyings, uniforms and constants.")));
add_options.push_back(AddOption("UniformRef", "Special", "", "VisualShaderNodeUniformRef", TTR("A reference to an existing uniform.")));
- add_options.push_back(AddOption("ScalarDerivativeFunc", "Special", "Common", "VisualShaderNodeScalarDerivativeFunc", TTR("(Fragment/Light mode only) Scalar derivative function."), -1, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, -1, true));
- add_options.push_back(AddOption("VectorDerivativeFunc", "Special", "Common", "VisualShaderNodeVectorDerivativeFunc", TTR("(Fragment/Light mode only) Vector derivative function."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, -1, true));
-
- add_options.push_back(AddOption("DdX", "Special", "Derivative", "VisualShaderNodeVectorDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'x' using local differencing."), VisualShaderNodeVectorDerivativeFunc::FUNC_X, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, -1, true));
- add_options.push_back(AddOption("DdXS", "Special", "Derivative", "VisualShaderNodeScalarDerivativeFunc", TTR("(Fragment/Light mode only) (Scalar) Derivative in 'x' using local differencing."), VisualShaderNodeScalarDerivativeFunc::FUNC_X, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, -1, true));
- add_options.push_back(AddOption("DdY", "Special", "Derivative", "VisualShaderNodeVectorDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'y' using local differencing."), VisualShaderNodeVectorDerivativeFunc::FUNC_Y, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, -1, true));
- add_options.push_back(AddOption("DdYS", "Special", "Derivative", "VisualShaderNodeScalarDerivativeFunc", TTR("(Fragment/Light mode only) (Scalar) Derivative in 'y' using local differencing."), VisualShaderNodeScalarDerivativeFunc::FUNC_Y, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, -1, true));
- add_options.push_back(AddOption("Sum", "Special", "Derivative", "VisualShaderNodeVectorDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), VisualShaderNodeVectorDerivativeFunc::FUNC_SUM, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, -1, true));
- add_options.push_back(AddOption("SumS", "Special", "Derivative", "VisualShaderNodeScalarDerivativeFunc", TTR("(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and 'y'."), VisualShaderNodeScalarDerivativeFunc::FUNC_SUM, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, -1, -1, true));
custom_node_option_idx = add_options.size();
/////////////////////////////////////////////////////////////////////
@@ -4831,9 +5066,10 @@ public:
void setup(const Ref<VisualShaderNodeInput> &p_input) {
input = p_input;
- Ref<Texture2D> type_icon[6] = {
+ Ref<Texture2D> type_icon[7] = {
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("int"), SNAME("EditorIcons")),
+ EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("bool"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")),
@@ -4879,10 +5115,11 @@ public:
void setup(const Ref<VisualShaderNodeUniformRef> &p_uniform_ref) {
uniform_ref = p_uniform_ref;
- Ref<Texture2D> type_icon[7] = {
+ Ref<Texture2D> type_icon[8] = {
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("int"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("bool"), SNAME("EditorIcons")),
+ EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Color"), SNAME("EditorIcons")),
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index 2b837ef4a0..c5037853cd 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -247,44 +247,25 @@ class VisualShaderEditor : public VBoxContainer {
String category;
String type;
String description;
- int sub_func = 0;
- String sub_func_str;
+ Vector<Variant> ops;
Ref<Script> script;
int mode = 0;
int return_type = 0;
int func = 0;
- float value = 0;
bool highend = false;
bool is_custom = false;
int temp_idx = 0;
- AddOption(const String &p_name = String(), const String &p_category = String(), const String &p_sub_category = String(), const String &p_type = String(), const String &p_description = String(), int p_sub_func = -1, int p_return_type = -1, int p_mode = -1, int p_func = -1, float p_value = -1, bool p_highend = false) {
+ AddOption(const String &p_name = String(), const String &p_category = String(), const String &p_sub_category = String(), const String &p_type = String(), const String &p_description = String(), const Vector<Variant> &p_ops = Vector<Variant>(), int p_return_type = -1, int p_mode = -1, int p_func = -1, bool p_highend = false) {
name = p_name;
type = p_type;
category = p_category + "/" + p_sub_category;
description = p_description;
- sub_func = p_sub_func;
+ ops = p_ops;
return_type = p_return_type;
mode = p_mode;
func = p_func;
- value = p_value;
highend = p_highend;
- is_custom = false;
- }
-
- AddOption(const String &p_name, const String &p_category, const String &p_sub_category, const String &p_type, const String &p_description, const String &p_sub_func, int p_return_type = -1, int p_mode = -1, int p_func = -1, float p_value = -1, bool p_highend = false) {
- name = p_name;
- type = p_type;
- category = p_category + "/" + p_sub_category;
- description = p_description;
- sub_func = 0;
- sub_func_str = p_sub_func;
- return_type = p_return_type;
- mode = p_mode;
- func = p_func;
- value = p_value;
- highend = p_highend;
- is_custom = false;
}
};
struct _OptionComparator {
@@ -307,8 +288,8 @@ class VisualShaderEditor : public VBoxContainer {
void _draw_color_over_button(Object *obj, Color p_color);
- void _setup_node(VisualShaderNode *p_node, int p_op_idx);
- void _add_node(int p_idx, int p_op_idx = -1, String p_resource_path = "", int p_node_idx = -1);
+ void _setup_node(VisualShaderNode *p_node, const Vector<Variant> &p_ops);
+ void _add_node(int p_idx, const Vector<Variant> &p_ops, String p_resource_path = "", int p_node_idx = -1);
void _update_options_menu();
void _set_mode(int p_which);
diff --git a/editor/plugins/voxel_gi_editor_plugin.cpp b/editor/plugins/voxel_gi_editor_plugin.cpp
index 1fd47b67c5..cef29032b2 100644
--- a/editor/plugins/voxel_gi_editor_plugin.cpp
+++ b/editor/plugins/voxel_gi_editor_plugin.cpp
@@ -115,7 +115,7 @@ EditorProgress *VoxelGIEditorPlugin::tmp_progress = nullptr;
void VoxelGIEditorPlugin::bake_func_begin(int p_steps) {
ERR_FAIL_COND(tmp_progress != nullptr);
- tmp_progress = memnew(EditorProgress("bake_gi", TTR("Bake GI Probe"), p_steps));
+ tmp_progress = memnew(EditorProgress("bake_gi", TTR("Bake VoxelGI"), p_steps));
}
void VoxelGIEditorPlugin::bake_func_step(int p_step, const String &p_description) {
@@ -149,7 +149,7 @@ VoxelGIEditorPlugin::VoxelGIEditorPlugin(EditorNode *p_node) {
bake = memnew(Button);
bake->set_flat(true);
bake->set_icon(editor->get_gui_base()->get_theme_icon(SNAME("Bake"), SNAME("EditorIcons")));
- bake->set_text(TTR("Bake GI Probe"));
+ bake->set_text(TTR("Bake VoxelGI"));
bake->connect("pressed", callable_mp(this, &VoxelGIEditorPlugin::_bake));
bake_hb->add_child(bake);
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index b246607786..08514da2c6 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "editor/editor_export.h"
+#include "editor/editor_log.h"
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
@@ -47,7 +48,8 @@ void ProjectSettingsEditor::popup_project_settings() {
}
_add_feature_overrides();
- inspector->update_category_list();
+ general_settings_inspector->update_category_list();
+ set_process_unhandled_input(true);
localization_editor->update_translations();
autoload_settings->update_autoload();
@@ -74,7 +76,7 @@ void ProjectSettingsEditor::_setting_edited(const String &p_name) {
void ProjectSettingsEditor::_advanced_toggled(bool p_button_pressed) {
EditorSettings::get_singleton()->set_project_metadata("project_settings", "advanced_mode", p_button_pressed);
- inspector->set_restrict_to_basic_settings(!p_button_pressed);
+ general_settings_inspector->set_restrict_to_basic_settings(!p_button_pressed);
}
void ProjectSettingsEditor::_setting_selected(const String &p_path) {
@@ -82,7 +84,7 @@ void ProjectSettingsEditor::_setting_selected(const String &p_path) {
return;
}
- property_box->set_text(inspector->get_current_section() + "/" + p_path);
+ property_box->set_text(general_settings_inspector->get_current_section() + "/" + p_path);
_update_property_box(); // set_text doesn't trigger text_changed
}
@@ -99,13 +101,13 @@ void ProjectSettingsEditor::_add_setting() {
undo_redo->add_do_property(ps, setting, value);
undo_redo->add_undo_property(ps, setting, ps->has_setting(setting) ? ps->get(setting) : Variant());
- undo_redo->add_do_method(inspector, "update_category_list");
- undo_redo->add_undo_method(inspector, "update_category_list");
+ undo_redo->add_do_method(general_settings_inspector, "update_category_list");
+ undo_redo->add_undo_method(general_settings_inspector, "update_category_list");
undo_redo->add_do_method(this, "queue_save");
undo_redo->add_undo_method(this, "queue_save");
undo_redo->commit_action();
- inspector->set_current_section(setting.get_slice("/", 1));
+ general_settings_inspector->set_current_section(setting.get_slice("/", 1));
add_button->release_focus();
}
@@ -120,8 +122,8 @@ void ProjectSettingsEditor::_delete_setting() {
undo_redo->add_undo_method(ps, "set", setting, value);
undo_redo->add_undo_method(ps, "set_order", setting, order);
- undo_redo->add_do_method(inspector, "update_category_list");
- undo_redo->add_undo_method(inspector, "update_category_list");
+ undo_redo->add_do_method(general_settings_inspector, "update_category_list");
+ undo_redo->add_undo_method(general_settings_inspector, "update_category_list");
undo_redo->add_do_method(this, "queue_save");
undo_redo->add_undo_method(this, "queue_save");
@@ -200,6 +202,44 @@ void ProjectSettingsEditor::_select_type(Variant::Type p_type) {
type_box->select(type_box->get_item_index(p_type));
}
+void ProjectSettingsEditor::unhandled_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
+ const Ref<InputEventKey> k = p_event;
+
+ if (k.is_valid() && k->is_pressed()) {
+ bool handled = false;
+
+ if (ED_IS_SHORTCUT("ui_undo", p_event)) {
+ String action = undo_redo->get_current_action_name();
+ if (!action.is_empty()) {
+ EditorNode::get_log()->add_message("Undo: " + action, EditorLog::MSG_TYPE_EDITOR);
+ }
+ undo_redo->undo();
+ handled = true;
+ }
+
+ if (ED_IS_SHORTCUT("ui_redo", p_event)) {
+ undo_redo->redo();
+ String action = undo_redo->get_current_action_name();
+ if (!action.is_empty()) {
+ EditorNode::get_log()->add_message("Redo: " + action, EditorLog::MSG_TYPE_EDITOR);
+ }
+ handled = true;
+ }
+
+ if (k->get_keycode_with_modifiers() == (KeyModifierMask::CMD | Key::F)) {
+ search_box->grab_focus();
+ search_box->select_all();
+ handled = true;
+ }
+
+ if (handled) {
+ set_input_as_handled();
+ }
+ }
+}
+
String ProjectSettingsEditor::_get_setting_name() const {
String name = property_box->get_text().strip_edges();
if (name.find("/") == -1) {
@@ -463,7 +503,7 @@ void ProjectSettingsEditor::_update_action_map_editor() {
actions.push_back(action_info);
}
- action_map->update_action_list(actions);
+ action_map_editor->update_action_list(actions);
}
void ProjectSettingsEditor::_update_theme() {
@@ -492,7 +532,7 @@ void ProjectSettingsEditor::_notification(int p_what) {
}
} break;
case NOTIFICATION_ENTER_TREE: {
- inspector->edit(ps);
+ general_settings_inspector->edit(ps);
_update_action_map_editor();
_update_theme();
} break;
@@ -571,14 +611,14 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
del_button->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_delete_setting));
header->add_child(del_button);
- inspector = memnew(SectionedInspector);
- inspector->get_inspector()->set_undo_redo(EditorNode::get_singleton()->get_undo_redo());
- inspector->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- inspector->register_search_box(search_box);
- inspector->get_inspector()->connect("property_selected", callable_mp(this, &ProjectSettingsEditor::_setting_selected));
- inspector->get_inspector()->connect("property_edited", callable_mp(this, &ProjectSettingsEditor::_setting_edited));
- inspector->get_inspector()->connect("restart_requested", callable_mp(this, &ProjectSettingsEditor::_editor_restart_request));
- general_editor->add_child(inspector);
+ general_settings_inspector = memnew(SectionedInspector);
+ general_settings_inspector->get_inspector()->set_undo_redo(EditorNode::get_singleton()->get_undo_redo());
+ general_settings_inspector->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ general_settings_inspector->register_search_box(search_box);
+ general_settings_inspector->get_inspector()->connect("property_selected", callable_mp(this, &ProjectSettingsEditor::_setting_selected));
+ general_settings_inspector->get_inspector()->connect("property_edited", callable_mp(this, &ProjectSettingsEditor::_setting_edited));
+ general_settings_inspector->get_inspector()->connect("restart_requested", callable_mp(this, &ProjectSettingsEditor::_editor_restart_request));
+ general_editor->add_child(general_settings_inspector);
restart_container = memnew(PanelContainer);
general_editor->add_child(restart_container);
@@ -606,14 +646,14 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
restart_close_button->connect("pressed", callable_mp(this, &ProjectSettingsEditor::_editor_restart_close));
restart_hb->add_child(restart_close_button);
- action_map = memnew(ActionMapEditor);
- action_map->set_name(TTR("Input Map"));
- action_map->connect("action_added", callable_mp(this, &ProjectSettingsEditor::_action_added));
- action_map->connect("action_edited", callable_mp(this, &ProjectSettingsEditor::_action_edited));
- action_map->connect("action_removed", callable_mp(this, &ProjectSettingsEditor::_action_removed));
- action_map->connect("action_renamed", callable_mp(this, &ProjectSettingsEditor::_action_renamed));
- action_map->connect("action_reordered", callable_mp(this, &ProjectSettingsEditor::_action_reordered));
- tab_container->add_child(action_map);
+ action_map_editor = memnew(ActionMapEditor);
+ action_map_editor->set_name(TTR("Input Map"));
+ action_map_editor->connect("action_added", callable_mp(this, &ProjectSettingsEditor::_action_added));
+ action_map_editor->connect("action_edited", callable_mp(this, &ProjectSettingsEditor::_action_edited));
+ action_map_editor->connect("action_removed", callable_mp(this, &ProjectSettingsEditor::_action_removed));
+ action_map_editor->connect("action_renamed", callable_mp(this, &ProjectSettingsEditor::_action_renamed));
+ action_map_editor->connect("action_reordered", callable_mp(this, &ProjectSettingsEditor::_action_reordered));
+ tab_container->add_child(action_map_editor);
localization_editor = memnew(LocalizationEditor);
localization_editor->set_name(TTR("Localization"));
@@ -649,7 +689,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
advanced->set_pressed(true);
}
- inspector->set_restrict_to_basic_settings(!use_advanced);
+ general_settings_inspector->set_restrict_to_basic_settings(!use_advanced);
import_defaults_editor = memnew(ImportDefaultsEditor);
import_defaults_editor->set_name(TTR("Import Defaults"));
diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h
index a8eed0093f..d48c2b76ca 100644
--- a/editor/project_settings_editor.h
+++ b/editor/project_settings_editor.h
@@ -50,8 +50,8 @@ class ProjectSettingsEditor : public AcceptDialog {
Timer *timer;
TabContainer *tab_container;
- SectionedInspector *inspector;
- ActionMapEditor *action_map;
+ SectionedInspector *general_settings_inspector;
+ ActionMapEditor *action_map_editor;
LocalizationEditor *localization_editor;
EditorAutoloadSettings *autoload_settings;
ShaderGlobalsEditor *shaders_global_variables_editor;
@@ -81,6 +81,8 @@ class ProjectSettingsEditor : public AcceptDialog {
void _feature_selected(int p_index);
void _select_type(Variant::Type p_type);
+ virtual void unhandled_input(const Ref<InputEvent> &p_event) override;
+
String _get_setting_name() const;
void _setting_edited(const String &p_name);
void _setting_selected(const String &p_path);
diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp
index 3b0cbfdde9..7c0683c37b 100644
--- a/editor/property_selector.cpp
+++ b/editor/property_selector.cpp
@@ -185,7 +185,7 @@ void PropertySelector::_update_search() {
continue;
}
- if (type_filter.size() && type_filter.find(E.type) == -1) {
+ if (type_filter.size() && !type_filter.has(E.type)) {
continue;
}
diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp
index 118c016c6d..2a8ca67fe6 100644
--- a/editor/quick_open.cpp
+++ b/editor/quick_open.cpp
@@ -84,7 +84,7 @@ void EditorQuickOpen::_update_search() {
// Filter possible candidates.
Vector<Entry> entries;
for (int i = 0; i < files.size(); i++) {
- if (empty_search || search_text.is_subsequence_ofi(files[i])) {
+ if (empty_search || search_text.is_subsequence_ofn(files[i])) {
Entry r;
r.path = files[i];
r.score = empty_search ? 0 : _score_path(search_text, files[i].to_lower());
diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp
index 72686e9eb3..c6a4c0d86a 100644
--- a/editor/rename_dialog.cpp
+++ b/editor/rename_dialog.cpp
@@ -337,7 +337,7 @@ void RenameDialog::_bind_methods() {
}
void RenameDialog::_update_substitute() {
- LineEdit *focus_owner_line_edit = Object::cast_to<LineEdit>(scene_tree_editor->get_focus_owner());
+ LineEdit *focus_owner_line_edit = Object::cast_to<LineEdit>(scene_tree_editor->get_viewport()->gui_get_focus_owner());
bool is_main_field = _is_main_field(focus_owner_line_edit);
but_insert_name->set_disabled(!is_main_field);
@@ -363,7 +363,7 @@ void RenameDialog::_post_popup() {
Array selected_node_list = editor_selection->get_selected_nodes();
ERR_FAIL_COND(selected_node_list.size() == 0);
- preview_node = selected_node_list[0];
+ preview_node = Object::cast_to<Node>(selected_node_list[0]);
_update_preview();
_update_substitute();
@@ -632,7 +632,7 @@ bool RenameDialog::_is_main_field(LineEdit *line_edit) {
}
void RenameDialog::_insert_text(String text) {
- LineEdit *focus_owner = Object::cast_to<LineEdit>(scene_tree_editor->get_focus_owner());
+ LineEdit *focus_owner = Object::cast_to<LineEdit>(scene_tree_editor->get_viewport()->gui_get_focus_owner());
if (_is_main_field(focus_owner)) {
focus_owner->selection_delete();
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 125fcc02dc..9b18d3a491 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -78,7 +78,7 @@ void SceneTreeDock::input(const Ref<InputEvent> &p_event) {
void SceneTreeDock::unhandled_key_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
- if (get_focus_owner() && get_focus_owner()->is_text_field()) {
+ if (get_viewport()->gui_get_focus_owner() && get_viewport()->gui_get_focus_owner()->is_text_field()) {
return;
}
@@ -1723,7 +1723,7 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
Node *validate = new_parent;
while (validate) {
- ERR_FAIL_COND_MSG(p_nodes.find(validate) != -1, "Selection changed at some point. Can't reparent.");
+ ERR_FAIL_COND_MSG(p_nodes.has(validate), "Selection changed at some point. Can't reparent.");
validate = validate->get_parent();
}
@@ -3060,6 +3060,10 @@ List<Node *> SceneTreeDock::paste_nodes() {
return pasted_nodes;
}
+List<Node *> SceneTreeDock::get_node_clipboard() const {
+ return node_clipboard;
+}
+
void SceneTreeDock::add_remote_tree_editor(Control *p_remote) {
ERR_FAIL_COND(remote_tree != nullptr);
add_child(p_remote);
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index d73038ef36..3639e66233 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -315,6 +315,7 @@ public:
void open_instance_child_dialog();
List<Node *> paste_nodes();
+ List<Node *> get_node_clipboard() const;
ScriptCreateDialog *get_script_create_dialog() { return script_create_dialog; }
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 4a36462d65..c755bca64f 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -411,7 +411,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll
item->set_as_cursor(0);
}
- bool keep = (filter.is_subsequence_ofi(String(p_node->get_name())));
+ bool keep = (filter.is_subsequence_ofn(String(p_node->get_name())));
for (int i = 0; i < p_node->get_child_count(); i++) {
bool child_keep = _add_nodes(p_node->get_child(i), item, p_scroll_to_selected);
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 2098fa2c85..360ba5780c 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -656,14 +656,18 @@ void ScriptCreateDialog::_update_dialog() {
if (is_new_script_created) {
class_name->set_editable(true);
class_name->set_placeholder(TTR("Allowed: a-z, A-Z, 0-9, _ and ."));
- class_name->set_placeholder_alpha(0.3);
+ Color placeholder_color = class_name->get_theme_color("font_placeholder_color");
+ placeholder_color.a = 0.3;
+ class_name->add_theme_color_override("font_placeholder_color", placeholder_color);
} else {
class_name->set_editable(false);
}
} else {
class_name->set_editable(false);
class_name->set_placeholder(TTR("N/A"));
- class_name->set_placeholder_alpha(1);
+ Color placeholder_color = class_name->get_theme_color("font_placeholder_color");
+ placeholder_color.a = 1;
+ class_name->add_theme_color_override("font_placeholder_color", placeholder_color);
class_name->set_text("");
}
diff --git a/gles3_builders.py b/gles3_builders.py
index 4f9247c938..15446d345f 100644
--- a/gles3_builders.py
+++ b/gles3_builders.py
@@ -502,7 +502,7 @@ def build_gles3_header(filename, include, class_suffix, output_attribs):
for i in range(len(header_data.specialization_names)):
defval = header_data.specialization_values[i].strip()
if defval.upper() == "TRUE" or defval == "1":
- defal = "true"
+ defval = "true"
else:
defval = "false"
diff --git a/main/main.cpp b/main/main.cpp
index 8b58641461..a632059849 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1310,12 +1310,14 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/viewport_width",
PropertyInfo(Variant::INT, "display/window/size/viewport_width",
PROPERTY_HINT_RANGE,
- "0,7680,or_greater")); // 8K resolution
+ "0,7680,1,or_greater")); // 8K resolution
+
GLOBAL_DEF_BASIC("display/window/size/viewport_height", 600);
ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/viewport_height",
PropertyInfo(Variant::INT, "display/window/size/viewport_height",
PROPERTY_HINT_RANGE,
- "0,4320,or_greater")); // 8K resolution
+ "0,4320,1,or_greater")); // 8K resolution
+
GLOBAL_DEF_BASIC("display/window/size/resizable", true);
GLOBAL_DEF_BASIC("display/window/size/borderless", false);
GLOBAL_DEF_BASIC("display/window/size/fullscreen", false);
@@ -1325,13 +1327,13 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
PropertyInfo(Variant::INT,
"display/window/size/window_width_override",
PROPERTY_HINT_RANGE,
- "0,7680,or_greater")); // 8K resolution
+ "0,7680,1,or_greater")); // 8K resolution
GLOBAL_DEF("display/window/size/window_height_override", 0);
ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/window_height_override",
PropertyInfo(Variant::INT,
"display/window/size/window_height_override",
PROPERTY_HINT_RANGE,
- "0,4320,or_greater")); // 8K resolution
+ "0,4320,1,or_greater")); // 8K resolution
if (use_custom_res) {
if (!force_res) {
diff --git a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj
index fd69725a21..5ba45c0c13 100644
--- a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj
+++ b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj
@@ -308,6 +308,7 @@
CODE_SIGN_ENTITLEMENTS = "$binary/$binary.entitlements";
CODE_SIGN_IDENTITY = "$code_sign_identity_debug";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "$code_sign_identity_debug";
+ CODE_SIGN_STYLE = "$code_sign_style_debug";
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
DEVELOPMENT_TEAM = $team_id;
INFOPLIST_FILE = "$binary/$binary-Info.plist";
@@ -338,6 +339,7 @@
CODE_SIGN_ENTITLEMENTS = "$binary/$binary.entitlements";
CODE_SIGN_IDENTITY = "$code_sign_identity_release";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "$code_sign_identity_release";
+ CODE_SIGN_STYLE = "$code_sign_style_release";
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
DEVELOPMENT_TEAM = $team_id;
INFOPLIST_FILE = "$binary/$binary-Info.plist";
diff --git a/misc/scripts/black_format.sh b/misc/scripts/black_format.sh
index 2ad9a23832..99343f1c5a 100755
--- a/misc/scripts/black_format.sh
+++ b/misc/scripts/black_format.sh
@@ -6,28 +6,20 @@ set -uo pipefail
# Apply black.
echo -e "Formatting Python files..."
-PY_FILES=$(find \( -path "./.git" \
- -o -path "./thirdparty" \
- \) -prune \
- -o \( -name "SConstruct" \
- -o -name "SCsub" \
- -o -name "*.py" \
- \) -print)
+PY_FILES=$(git ls-files -- '*SConstruct' '*SCsub' '*.py' ':!:.git/*' ':!:thirdparty/*')
black -l 120 $PY_FILES
-git diff --color > patch.patch
+diff=$(git diff --color)
# If no patch has been generated all is OK, clean up, and exit.
-if [ ! -s patch.patch ] ; then
+if [ -z "$diff" ] ; then
printf "Files in this commit comply with the black style rules.\n"
- rm -f patch.patch
exit 0
fi
# A patch has been created, notify the user, clean up, and exit.
printf "\n*** The following differences were found between the code "
printf "and the formatting rules:\n\n"
-cat patch.patch
+echo "$diff"
printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
-rm -f patch.patch
exit 1
diff --git a/misc/scripts/clang_format.sh b/misc/scripts/clang_format.sh
index 0006b82280..13b5ab79b6 100755
--- a/misc/scripts/clang_format.sh
+++ b/misc/scripts/clang_format.sh
@@ -4,53 +4,36 @@
# This is the primary script responsible for fixing style violations.
set -uo pipefail
-IFS=$'\n\t'
-CLANG_FORMAT_FILE_EXTS=(".c" ".h" ".cpp" ".hpp" ".cc" ".hh" ".cxx" ".m" ".mm" ".inc" ".java" ".glsl")
+# Loops through all code files tracked by Git.
+git ls-files -- '*.c' '*.h' '*.cpp' '*.hpp' '*.cc' '*.hh' '*.cxx' '*.m' '*.mm' '*.inc' '*.java' '*.glsl' \
+ ':!:.git/*' ':!:thirdparty/*' ':!:platform/android/java/lib/src/com/google/*' ':!:*-so_wrap.*' |
+while read -r f; do
+ # Run clang-format.
+ clang-format --Wno-error=unknown -i "$f"
-# Loops through all text files tracked by Git.
-git grep -zIl '' |
-while IFS= read -rd '' f; do
- # Exclude some files.
- if [[ "$f" == "thirdparty"* ]]; then
+ # Fix copyright headers, but not all files get them.
+ if [[ "$f" == *"inc" ]]; then
continue
- elif [[ "$f" == "platform/android/java/lib/src/com/google"* ]]; then
+ elif [[ "$f" == *"glsl" ]]; then
continue
- elif [[ "$f" == *"-so_wrap."* ]]; then
+ elif [[ "$f" == "platform/android/java/lib/src/org/godotengine/godot/input/InputManager"* ]]; then
continue
fi
- for extension in ${CLANG_FORMAT_FILE_EXTS[@]}; do
- if [[ "$f" == *"$extension" ]]; then
- # Run clang-format.
- clang-format --Wno-error=unknown -i "$f"
- # Fix copyright headers, but not all files get them.
- if [[ "$f" == *"inc" ]]; then
- continue 2
- elif [[ "$f" == *"glsl" ]]; then
- continue 2
- elif [[ "$f" == "platform/android/java/lib/src/org/godotengine/godot/input/InputManager"* ]]; then
- continue 2
- fi
- python misc/scripts/copyright_headers.py "$f"
- continue 2
- fi
- done
+ python misc/scripts/copyright_headers.py "$f"
done
-git diff --color > patch.patch
+diff=$(git diff --color)
# If no patch has been generated all is OK, clean up, and exit.
-if [ ! -s patch.patch ] ; then
- printf "Files in this commit comply with the clang-format style rules.\n"
- rm -f patch.patch
+if [ -z "$diff" ] ; then
+ printf "Files in this commit comply with the clang-tidy style rules.\n"
exit 0
fi
# A patch has been created, notify the user, clean up, and exit.
-printf "\n*** The following differences were found between the code "
-printf "and the formatting rules:\n\n"
-cat patch.patch
-printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
-rm -f patch.patch
+printf "\n*** The following changes have been made to comply with the formatting rules:\n\n"
+echo "$diff"
+printf "\n*** Please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
exit 1
diff --git a/misc/scripts/clang_tidy.sh b/misc/scripts/clang_tidy.sh
new file mode 100755
index 0000000000..e49f6ac9f4
--- /dev/null
+++ b/misc/scripts/clang_tidy.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+
+# This script runs clang-tidy on all relevant files in the repo.
+# This is more thorough than clang-format and thus slower; it should only be run manually.
+
+set -uo pipefail
+
+# Loops through all code files tracked by Git.
+git ls-files -- '*.c' '*.h' '*.cpp' '*.hpp' '*.cc' '*.hh' '*.cxx' '*.m' '*.mm' '*.inc' '*.java' '*.glsl' \
+ ':!:.git/*' ':!:thirdparty/*' ':!:platform/android/java/lib/src/com/google/*' ':!:*-so_wrap.*' |
+while read -r f; do
+ # Run clang-tidy.
+ clang-tidy --quiet --fix "$f" &> /dev/null
+
+ # Run clang-format. This also fixes the output of clang-tidy.
+ clang-format --Wno-error=unknown -i "$f"
+done
+
+diff=$(git diff --color)
+
+# If no patch has been generated all is OK, clean up, and exit.
+if [ -z "$diff" ] ; then
+ printf "Files in this commit comply with the clang-tidy style rules.\n"
+ exit 0
+fi
+
+# A patch has been created, notify the user, clean up, and exit.
+printf "\n*** The following changes have been made to comply with the formatting rules:\n\n"
+echo "$diff"
+printf "\n*** Please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
+exit 1
diff --git a/misc/scripts/file_format.sh b/misc/scripts/file_format.sh
index e66bc88bc0..0c7235817d 100755
--- a/misc/scripts/file_format.sh
+++ b/misc/scripts/file_format.sh
@@ -47,10 +47,10 @@ while IFS= read -rd '' f; do
perl -i -ple 's/\s*$//g' "$f"
done
-git diff --color > patch.patch
+diff=$(git diff --color)
# If no patch has been generated all is OK, clean up, and exit.
-if [ ! -s patch.patch ] ; then
+if [ -z "$diff" ] ; then
printf "Files in this commit comply with the formatting rules.\n"
rm -f patch.patch
exit 0
@@ -59,7 +59,6 @@ fi
# A patch has been created, notify the user, clean up, and exit.
printf "\n*** The following differences were found between the code "
printf "and the formatting rules:\n\n"
-cat patch.patch
+echo "$diff"
printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
-rm -f patch.patch
exit 1
diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h
index 6377f8915d..dffcadbcdc 100644
--- a/modules/bullet/shape_bullet.h
+++ b/modules/bullet/shape_bullet.h
@@ -105,7 +105,7 @@ private:
};
class SphereShapeBullet : public ShapeBullet {
- real_t radius;
+ real_t radius = 0.0;
public:
SphereShapeBullet();
@@ -137,8 +137,8 @@ private:
};
class CapsuleShapeBullet : public ShapeBullet {
- real_t height;
- real_t radius;
+ real_t height = 0.0;
+ real_t radius = 0.0;
public:
CapsuleShapeBullet();
@@ -155,8 +155,8 @@ private:
};
class CylinderShapeBullet : public ShapeBullet {
- real_t height;
- real_t radius;
+ real_t height = 0.0;
+ real_t radius = 0.0;
public:
CylinderShapeBullet();
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index 4b36bca02a..fbddedbe55 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -1451,8 +1451,8 @@ Ref<Material> CSGCylinder3D::get_material() const {
CSGCylinder3D::CSGCylinder3D() {
// defaults
- radius = 1.0;
- height = 1.0;
+ radius = 0.5;
+ height = 2.0;
sides = 8;
cone = false;
smooth_faces = true;
@@ -1671,8 +1671,8 @@ Ref<Material> CSGTorus3D::get_material() const {
CSGTorus3D::CSGTorus3D() {
// defaults
- inner_radius = 2.0;
- outer_radius = 3.0;
+ inner_radius = 0.5;
+ outer_radius = 1.0;
sides = 8;
ring_sides = 6;
smooth_faces = true;
diff --git a/modules/csg/csg_shape.h b/modules/csg/csg_shape.h
index eed995a40e..6da9893368 100644
--- a/modules/csg/csg_shape.h
+++ b/modules/csg/csg_shape.h
@@ -239,7 +239,7 @@ class CSGBox3D : public CSGPrimitive3D {
virtual CSGBrush *_build_brush() override;
Ref<Material> material;
- Vector3 size = Vector3(2, 2, 2);
+ Vector3 size = Vector3(1, 1, 1);
protected:
static void _bind_methods();
diff --git a/modules/csg/doc_classes/CSGBox3D.xml b/modules/csg/doc_classes/CSGBox3D.xml
index d64e58ae4d..4b479ed42e 100644
--- a/modules/csg/doc_classes/CSGBox3D.xml
+++ b/modules/csg/doc_classes/CSGBox3D.xml
@@ -12,7 +12,7 @@
<member name="material" type="Material" setter="set_material" getter="get_material">
The material used to render the box.
</member>
- <member name="size" type="Vector3" setter="set_size" getter="get_size" default="Vector3(2, 2, 2)">
+ <member name="size" type="Vector3" setter="set_size" getter="get_size" default="Vector3(1, 1, 1)">
The box's width, height and depth.
</member>
</members>
diff --git a/modules/csg/doc_classes/CSGCylinder3D.xml b/modules/csg/doc_classes/CSGCylinder3D.xml
index 40e989bfb3..1fe2025bab 100644
--- a/modules/csg/doc_classes/CSGCylinder3D.xml
+++ b/modules/csg/doc_classes/CSGCylinder3D.xml
@@ -12,13 +12,13 @@
<member name="cone" type="bool" setter="set_cone" getter="is_cone" default="false">
If [code]true[/code] a cone is created, the [member radius] will only apply to one side.
</member>
- <member name="height" type="float" setter="set_height" getter="get_height" default="1.0">
+ <member name="height" type="float" setter="set_height" getter="get_height" default="2.0">
The height of the cylinder.
</member>
<member name="material" type="Material" setter="set_material" getter="get_material">
The material used to render the cylinder.
</member>
- <member name="radius" type="float" setter="set_radius" getter="get_radius" default="1.0">
+ <member name="radius" type="float" setter="set_radius" getter="get_radius" default="0.5">
The radius of the cylinder.
</member>
<member name="sides" type="int" setter="set_sides" getter="get_sides" default="8">
diff --git a/modules/csg/doc_classes/CSGTorus3D.xml b/modules/csg/doc_classes/CSGTorus3D.xml
index 91ee63a4c9..2c0eef8f09 100644
--- a/modules/csg/doc_classes/CSGTorus3D.xml
+++ b/modules/csg/doc_classes/CSGTorus3D.xml
@@ -9,13 +9,13 @@
<tutorials>
</tutorials>
<members>
- <member name="inner_radius" type="float" setter="set_inner_radius" getter="get_inner_radius" default="2.0">
+ <member name="inner_radius" type="float" setter="set_inner_radius" getter="get_inner_radius" default="0.5">
The inner radius of the torus.
</member>
<member name="material" type="Material" setter="set_material" getter="get_material">
The material used to render the torus.
</member>
- <member name="outer_radius" type="float" setter="set_outer_radius" getter="get_outer_radius" default="3.0">
+ <member name="outer_radius" type="float" setter="set_outer_radius" getter="get_outer_radius" default="1.0">
The outer radius of the torus.
</member>
<member name="ring_sides" type="int" setter="set_ring_sides" getter="get_ring_sides" default="6">
diff --git a/modules/fbx/fbx_parser/FBXAnimation.cpp b/modules/fbx/fbx_parser/FBXAnimation.cpp
index 8c43aac8f6..8627c95012 100644
--- a/modules/fbx/fbx_parser/FBXAnimation.cpp
+++ b/modules/fbx/fbx_parser/FBXAnimation.cpp
@@ -130,7 +130,7 @@ AnimationCurve::~AnimationCurve() {
AnimationCurveNode::AnimationCurveNode(uint64_t id, const ElementPtr element, const std::string &name,
const Document &doc, const char *const *target_prop_whitelist /*= nullptr*/,
size_t whitelist_size /*= 0*/) :
- Object(id, element, name), target(), doc(doc) {
+ Object(id, element, name), doc(doc) {
// find target node
const char *whitelist[] = { "Model", "NodeAttribute", "Deformer" };
const std::vector<const Connection *> &conns = doc.GetConnectionsBySourceSequenced(ID(), whitelist, 3);
diff --git a/modules/fbx/fbx_parser/FBXDeformer.cpp b/modules/fbx/fbx_parser/FBXDeformer.cpp
index b888afd90e..a2b216ab09 100644
--- a/modules/fbx/fbx_parser/FBXDeformer.cpp
+++ b/modules/fbx/fbx_parser/FBXDeformer.cpp
@@ -104,7 +104,7 @@ Constraint::~Constraint() {
// ------------------------------------------------------------------------------------------------
Cluster::Cluster(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name) :
- Deformer(id, element, doc, name), valid_transformAssociateModel(false) {
+ Deformer(id, element, doc, name) {
const ScopePtr sc = GetRequiredScope(element);
// for( auto element : sc.Elements())
// {
@@ -177,7 +177,7 @@ Cluster::~Cluster() {
// ------------------------------------------------------------------------------------------------
Skin::Skin(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name) :
- Deformer(id, element, doc, name), accuracy(0.0f) {
+ Deformer(id, element, doc, name) {
const ScopePtr sc = GetRequiredScope(element);
// keep this it is used for debugging and any FBX format changes
diff --git a/modules/fbx/fbx_parser/FBXParser.cpp b/modules/fbx/fbx_parser/FBXParser.cpp
index d8ccb4179c..e345b7fc18 100644
--- a/modules/fbx/fbx_parser/FBXParser.cpp
+++ b/modules/fbx/fbx_parser/FBXParser.cpp
@@ -235,7 +235,7 @@ Scope::~Scope() {
// ------------------------------------------------------------------------------------------------
Parser::Parser(const TokenList &tokens, bool is_binary) :
- corrupt(false), tokens(tokens), cursor(tokens.begin()), is_binary(is_binary) {
+ tokens(tokens), cursor(tokens.begin()), is_binary(is_binary) {
root = new_Scope(*this, true);
scopes.push_back(root);
}
diff --git a/modules/fbx/fbx_parser/FBXProperties.cpp b/modules/fbx/fbx_parser/FBXProperties.cpp
index 531f0743d6..7cbb3a2eda 100644
--- a/modules/fbx/fbx_parser/FBXProperties.cpp
+++ b/modules/fbx/fbx_parser/FBXProperties.cpp
@@ -145,8 +145,7 @@ std::string PeekPropertyName(const Element &element) {
} // namespace
// ------------------------------------------------------------------------------------------------
-PropertyTable::PropertyTable() :
- element(nullptr) {
+PropertyTable::PropertyTable() {
}
// Is used when dealing with FBX Objects not metadata.
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 0d295c3a51..d11174227a 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -1586,7 +1586,7 @@ void GDScriptAnalyzer::resolve_match_pattern(GDScriptParser::PatternNode *p_matc
if (p_match_pattern->dictionary[i].key) {
reduce_expression(p_match_pattern->dictionary[i].key);
if (!p_match_pattern->dictionary[i].key->is_constant) {
- push_error(R"(Expression in dictionary pattern key must be a constant.)", p_match_pattern->expression);
+ push_error(R"(Expression in dictionary pattern key must be a constant.)", p_match_pattern->dictionary[i].key);
}
}
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index 05ea061798..9977b88aa1 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -786,6 +786,8 @@ GDScriptTokenizer::Token GDScriptTokenizer::string() {
}
String result;
+ char32_t prev = 0;
+ int prev_pos = 0;
for (;;) {
// Consume actual string.
@@ -852,9 +854,11 @@ GDScriptTokenizer::Token GDScriptTokenizer::string() {
case '\\':
escaped = '\\';
break;
- case 'u':
+ case 'U':
+ case 'u': {
// Hexadecimal sequence.
- for (int i = 0; i < 4; i++) {
+ int hex_len = (code == 'U') ? 6 : 4;
+ for (int j = 0; j < hex_len; j++) {
if (_is_at_end()) {
return make_error("Unterminated string.");
}
@@ -886,7 +890,7 @@ GDScriptTokenizer::Token GDScriptTokenizer::string() {
_advance();
}
- break;
+ } break;
case '\r':
if (_peek() != '\n') {
// Carriage return without newline in string. (???)
@@ -909,11 +913,53 @@ GDScriptTokenizer::Token GDScriptTokenizer::string() {
valid_escape = false;
break;
}
+ // Parse UTF-16 pair.
+ if (valid_escape) {
+ if ((escaped & 0xfffffc00) == 0xd800) {
+ if (prev == 0) {
+ prev = escaped;
+ prev_pos = column - 2;
+ continue;
+ } else {
+ Token error = make_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
+ error.start_column = column - 2;
+ error.leftmost_column = error.start_column;
+ push_error(error);
+ valid_escape = false;
+ prev = 0;
+ }
+ } else if ((escaped & 0xfffffc00) == 0xdc00) {
+ if (prev == 0) {
+ Token error = make_error("Invalid UTF-16 sequence in string, unpaired trail surrogate");
+ error.start_column = column - 2;
+ error.leftmost_column = error.start_column;
+ push_error(error);
+ valid_escape = false;
+ } else {
+ escaped = (prev << 10UL) + escaped - ((0xd800 << 10UL) + 0xdc00 - 0x10000);
+ prev = 0;
+ }
+ }
+ if (prev != 0) {
+ Token error = make_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
+ error.start_column = prev_pos;
+ error.leftmost_column = error.start_column;
+ push_error(error);
+ prev = 0;
+ }
+ }
if (valid_escape) {
result += escaped;
}
} else if (ch == quote_char) {
+ if (prev != 0) {
+ Token error = make_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
+ error.start_column = prev_pos;
+ error.leftmost_column = error.start_column;
+ push_error(error);
+ prev = 0;
+ }
_advance();
if (is_multiline) {
if (_peek() == quote_char && _peek(1) == quote_char) {
@@ -930,6 +976,13 @@ GDScriptTokenizer::Token GDScriptTokenizer::string() {
break;
}
} else {
+ if (prev != 0) {
+ Token error = make_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
+ error.start_column = prev_pos;
+ error.leftmost_column = error.start_column;
+ push_error(error);
+ prev = 0;
+ }
result += ch;
_advance();
if (ch == '\n') {
@@ -937,6 +990,13 @@ GDScriptTokenizer::Token GDScriptTokenizer::string() {
}
}
}
+ if (prev != 0) {
+ Token error = make_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
+ error.start_column = prev_pos;
+ error.leftmost_column = error.start_column;
+ push_error(error);
+ prev = 0;
+ }
// Make the literal.
Variant string;
diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp
index a944844226..ed879b088a 100644
--- a/modules/gdscript/language_server/gdscript_workspace.cpp
+++ b/modules/gdscript/language_server/gdscript_workspace.cpp
@@ -269,7 +269,7 @@ Array GDScriptWorkspace::symbol(const Dictionary &p_params) {
Vector<lsp::DocumentedSymbolInformation> script_symbols;
E.value->get_symbols().symbol_tree_as_list(E.key, script_symbols);
for (int i = 0; i < script_symbols.size(); ++i) {
- if (query.is_subsequence_ofi(script_symbols[i].name)) {
+ if (query.is_subsequence_ofn(script_symbols[i].name)) {
lsp::DocumentedSymbolInformation symbol = script_symbols[i];
symbol.location.uri = get_file_uri(symbol.location.uri);
arr.push_back(symbol.to_json());
@@ -585,7 +585,7 @@ void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<S
stack.push_back(owner_scene_node);
while (!stack.is_empty()) {
- current = stack.pop_back();
+ current = Object::cast_to<Node>(stack.pop_back());
Ref<GDScript> script = current->get_script();
if (script.is_valid() && script->get_path() == path) {
break;
diff --git a/modules/glslang/glslang_resource_limits.h b/modules/glslang/glslang_resource_limits.h
index 05390f95ad..02d3daff07 100644
--- a/modules/glslang/glslang_resource_limits.h
+++ b/modules/glslang/glslang_resource_limits.h
@@ -132,15 +132,15 @@ const TBuiltInResource DefaultTBuiltInResource = {
/* .maxDualSourceDrawBuffersEXT = */ 1,
/* .limits = */ {
- /* .nonInductiveForLoops = */ 1,
- /* .whileLoops = */ 1,
- /* .doWhileLoops = */ 1,
- /* .generalUniformIndexing = */ 1,
- /* .generalAttributeMatrixVectorIndexing = */ 1,
- /* .generalVaryingIndexing = */ 1,
- /* .generalSamplerIndexing = */ 1,
- /* .generalVariableIndexing = */ 1,
- /* .generalConstantMatrixVectorIndexing = */ 1,
+ /* .nonInductiveForLoops = */ true,
+ /* .whileLoops = */ true,
+ /* .doWhileLoops = */ true,
+ /* .generalUniformIndexing = */ true,
+ /* .generalAttributeMatrixVectorIndexing = */ true,
+ /* .generalVaryingIndexing = */ true,
+ /* .generalSamplerIndexing = */ true,
+ /* .generalVariableIndexing = */ true,
+ /* .generalConstantMatrixVectorIndexing = */ true,
}
};
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 5a931ed839..51608273a1 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -6843,6 +6843,7 @@ Error GLTFDocument::write_to_filesystem(Ref<GLTFState> state, const String &p_pa
}
Node *GLTFDocument::generate_scene(Ref<GLTFState> state, int32_t p_bake_fps) {
+ ERR_FAIL_NULL_V(state, nullptr);
ERR_FAIL_INDEX_V(0, state->root_nodes.size(), nullptr);
GLTFNodeIndex gltf_root = state->root_nodes.write[0];
Node *gltf_root_node = state->get_scene_node(gltf_root);
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index 320901787d..84510fc71e 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -889,7 +889,7 @@ void GridMapEditor::update_palette() {
name = "#" + itos(id);
}
- if (!filter.is_empty() && !filter.is_subsequence_ofi(name)) {
+ if (!filter.is_empty() && !filter.is_subsequence_ofn(name)) {
continue;
}
diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp
index 49044c4afe..8cd23ffb24 100644
--- a/modules/mobile_vr/mobile_vr_interface.cpp
+++ b/modules/mobile_vr/mobile_vr_interface.cpp
@@ -463,7 +463,7 @@ CameraMatrix MobileVRInterface::get_projection_for_view(uint32_t p_view, double
return eye;
};
-Vector<BlitToScreen> MobileVRInterface::commit_views(RID p_render_target, const Rect2 &p_screen_rect) {
+Vector<BlitToScreen> MobileVRInterface::post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) {
_THREAD_SAFE_METHOD_
Vector<BlitToScreen> blit_to_screen;
diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h
index 47dc33c0c7..8ecca3a2ae 100644
--- a/modules/mobile_vr/mobile_vr_interface.h
+++ b/modules/mobile_vr/mobile_vr_interface.h
@@ -151,7 +151,7 @@ public:
virtual Transform3D get_camera_transform() override;
virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override;
virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override;
- virtual Vector<BlitToScreen> commit_views(RID p_render_target, const Rect2 &p_screen_rect) override;
+ virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override;
virtual void process() override;
diff --git a/modules/mono/build_scripts/mono_reg_utils.py b/modules/mono/build_scripts/mono_reg_utils.py
index 93a66ebf6f..43c1ec8f8a 100644
--- a/modules/mono/build_scripts/mono_reg_utils.py
+++ b/modules/mono/build_scripts/mono_reg_utils.py
@@ -96,10 +96,10 @@ def find_msbuild_tools_path_reg():
raise ValueError("Cannot find `installationPath` entry")
except ValueError as e:
print("Error reading output from vswhere: " + e.message)
- except OSError:
- pass # Fine, vswhere not found
- except (subprocess.CalledProcessError, OSError):
- pass
+ except subprocess.CalledProcessError as e:
+ print(e.output)
+ except OSError as e:
+ print(e)
# Try to find 14.0 in the Registry
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index 2be588cac4..2de923c125 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -103,8 +103,6 @@ private:
bool valid = false;
bool reload_invalidated = false;
- bool builtin;
-
GDMonoClass *base = nullptr;
GDMonoClass *native = nullptr;
GDMonoClass *script_class = nullptr;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
index a89dca6c34..eba0ea9a79 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
@@ -727,7 +727,7 @@ namespace Godot
/// <summary>
/// Check whether this string is a subsequence of the given string.
/// </summary>
- /// <seealso cref="IsSubsequenceOfI(string, string)"/>
+ /// <seealso cref="IsSubsequenceOfN(string, string)"/>
/// <param name="instance">The subsequence to search.</param>
/// <param name="text">The string that contains the subsequence.</param>
/// <param name="caseSensitive">If <see langword="true"/>, the check is case sensitive.</param>
@@ -779,7 +779,7 @@ namespace Godot
/// <param name="instance">The subsequence to search.</param>
/// <param name="text">The string that contains the subsequence.</param>
/// <returns>If the string is a subsequence of the given string.</returns>
- public static bool IsSubsequenceOfI(this string instance, string text)
+ public static bool IsSubsequenceOfN(this string instance, string text)
{
return instance.IsSubsequenceOf(text, caseSensitive: false);
}
diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp
index 77fe9cdd19..52d5379e8b 100644
--- a/modules/navigation/navigation_mesh_generator.cpp
+++ b/modules/navigation/navigation_mesh_generator.cpp
@@ -140,12 +140,12 @@ void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, cons
}
}
-void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_vertices, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) {
+void NavigationMeshGenerator::_parse_geometry(const Transform3D &p_navmesh_transform, Node *p_node, Vector<float> &p_vertices, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) {
if (Object::cast_to<MeshInstance3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(p_node);
Ref<Mesh> mesh = mesh_instance->get_mesh();
if (mesh.is_valid()) {
- _add_mesh(mesh, p_accumulated_transform * mesh_instance->get_transform(), p_vertices, p_indices);
+ _add_mesh(mesh, p_navmesh_transform * mesh_instance->get_global_transform(), p_vertices, p_indices);
}
}
@@ -159,7 +159,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
n = multimesh->get_instance_count();
}
for (int i = 0; i < n; i++) {
- _add_mesh(mesh, p_accumulated_transform * multimesh->get_instance_transform(i), p_vertices, p_indices);
+ _add_mesh(mesh, p_navmesh_transform * multimesh_instance->get_global_transform() * multimesh->get_instance_transform(i), p_vertices, p_indices);
}
}
}
@@ -171,7 +171,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
if (!meshes.is_empty()) {
Ref<Mesh> mesh = meshes[1];
if (mesh.is_valid()) {
- _add_mesh(mesh, p_accumulated_transform * csg_shape->get_transform(), p_vertices, p_indices);
+ _add_mesh(mesh, p_navmesh_transform * csg_shape->get_global_transform(), p_vertices, p_indices);
}
}
}
@@ -186,7 +186,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
if (Object::cast_to<CollisionShape3D>(child)) {
CollisionShape3D *col_shape = Object::cast_to<CollisionShape3D>(child);
- Transform3D transform = p_accumulated_transform * static_body->get_transform() * col_shape->get_transform();
+ Transform3D transform = p_navmesh_transform * static_body->get_global_transform() * col_shape->get_transform();
Ref<Mesh> mesh;
Ref<Shape3D> s = col_shape->get_shape();
@@ -270,11 +270,11 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
if (gridmap) {
if (p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
Array meshes = gridmap->get_meshes();
- Transform3D xform = gridmap->get_transform();
+ Transform3D xform = gridmap->get_global_transform();
for (int i = 0; i < meshes.size(); i += 2) {
Ref<Mesh> mesh = meshes[i + 1];
if (mesh.is_valid()) {
- _add_mesh(mesh, p_accumulated_transform * xform * (Transform3D)meshes[i], p_vertices, p_indices);
+ _add_mesh(mesh, p_navmesh_transform * xform * (Transform3D)meshes[i], p_vertices, p_indices);
}
}
}
@@ -364,14 +364,9 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
}
#endif
- if (Object::cast_to<Node3D>(p_node)) {
- Node3D *spatial = Object::cast_to<Node3D>(p_node);
- p_accumulated_transform = p_accumulated_transform * spatial->get_transform();
- }
-
if (p_recurse_children) {
for (int i = 0; i < p_node->get_child_count(); i++) {
- _parse_geometry(p_accumulated_transform, p_node->get_child(i), p_vertices, p_indices, p_generate_from, p_collision_mask, p_recurse_children);
+ _parse_geometry(p_navmesh_transform, p_node->get_child(i), p_vertices, p_indices, p_generate_from, p_collision_mask, p_recurse_children);
}
}
}
@@ -616,7 +611,7 @@ void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node)
p_node->get_tree()->get_nodes_in_group(p_nav_mesh->get_source_group_name(), &parse_nodes);
}
- Transform3D navmesh_xform = Object::cast_to<Node3D>(p_node)->get_transform().affine_inverse();
+ Transform3D navmesh_xform = Object::cast_to<Node3D>(p_node)->get_global_transform().affine_inverse();
for (Node *E : parse_nodes) {
NavigationMesh::ParsedGeometryType geometry_type = p_nav_mesh->get_parsed_geometry_type();
uint32_t collision_mask = p_nav_mesh->get_collision_mask();
diff --git a/modules/navigation/navigation_mesh_generator.h b/modules/navigation/navigation_mesh_generator.h
index 1ffdd39aee..21f7a4941b 100644
--- a/modules/navigation/navigation_mesh_generator.h
+++ b/modules/navigation/navigation_mesh_generator.h
@@ -52,7 +52,7 @@ protected:
static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_vertices);
static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices);
static void _add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices);
- static void _parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_vertices, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children);
+ static void _parse_geometry(const Transform3D &p_navmesh_transform, Node *p_node, Vector<float> &p_vertices, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children);
static void _convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh);
static void _build_recast_navigation_mesh(
diff --git a/modules/ogg/ogg_packet_sequence.h b/modules/ogg/ogg_packet_sequence.h
index 7e56b14a24..73e3cb4fff 100644
--- a/modules/ogg/ogg_packet_sequence.h
+++ b/modules/ogg/ogg_packet_sequence.h
@@ -104,7 +104,7 @@ class OGGPacketSequencePlayback : public RefCounted {
mutable ogg_packet *packet;
- uint64_t data_version;
+ uint64_t data_version = 0;
mutable int64_t packetno = 0;
diff --git a/modules/text_server_adv/SCsub b/modules/text_server_adv/SCsub
index d6a96282f3..6a06619840 100644
--- a/modules/text_server_adv/SCsub
+++ b/modules/text_server_adv/SCsub
@@ -62,7 +62,6 @@ if env["builtin_harfbuzz"]:
#'src/hb-gobject-structs.cc',
"src/hb-icu.cc",
"src/hb-map.cc",
- "src/hb-ms-feature-ranges.cc",
"src/hb-number.cc",
"src/hb-ot-cff1-table.cc",
"src/hb-ot-cff2-table.cc",
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index e0ee809331..e50a5337cb 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -2901,7 +2901,7 @@ void TextServerAdvanced::font_set_global_oversampling(float p_oversampling) {
List<RID> text_bufs;
shaped_owner.get_owned_list(&text_bufs);
for (const RID &E : text_bufs) {
- invalidate(shaped_owner.get_or_null(E));
+ invalidate(shaped_owner.get_or_null(E), false);
}
}
}
@@ -2936,7 +2936,7 @@ int TextServerAdvanced::_convert_pos_inv(const ShapedTextDataAdvanced *p_sd, int
return limit;
}
-void TextServerAdvanced::invalidate(TextServerAdvanced::ShapedTextDataAdvanced *p_shaped) {
+void TextServerAdvanced::invalidate(TextServerAdvanced::ShapedTextDataAdvanced *p_shaped, bool p_text) {
p_shaped->valid = false;
p_shaped->sort_valid = false;
p_shaped->line_breaks_valid = false;
@@ -2951,27 +2951,32 @@ void TextServerAdvanced::invalidate(TextServerAdvanced::ShapedTextDataAdvanced *
p_shaped->glyphs_logical.clear();
p_shaped->overrun_trim_data = TrimData();
p_shaped->utf16 = Char16String();
- if (p_shaped->script_iter != nullptr) {
- memdelete(p_shaped->script_iter);
- p_shaped->script_iter = nullptr;
- }
for (int i = 0; i < p_shaped->bidi_iter.size(); i++) {
ubidi_close(p_shaped->bidi_iter[i]);
}
p_shaped->bidi_iter.clear();
+
+ if (p_text) {
+ if (p_shaped->script_iter != nullptr) {
+ memdelete(p_shaped->script_iter);
+ p_shaped->script_iter = nullptr;
+ }
+ p_shaped->break_ops_valid = false;
+ p_shaped->js_ops_valid = false;
+ }
}
void TextServerAdvanced::full_copy(ShapedTextDataAdvanced *p_shaped) {
ShapedTextDataAdvanced *parent = shaped_owner.get_or_null(p_shaped->parent);
- for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : parent->objects) {
+ for (const KeyValue<Variant, ShapedTextDataAdvanced::EmbeddedObject> &E : parent->objects) {
if (E.value.pos >= p_shaped->start && E.value.pos < p_shaped->end) {
p_shaped->objects[E.key] = E.value;
}
}
- for (int k = 0; k < parent->spans.size(); k++) {
- ShapedTextDataAdvanced::Span span = parent->spans[k];
+ for (int i = 0; i < parent->spans.size(); i++) {
+ ShapedTextDataAdvanced::Span span = parent->spans[i];
if (span.start >= p_shaped->end || span.end <= p_shaped->start) {
continue;
}
@@ -3004,7 +3009,7 @@ void TextServerAdvanced::shaped_text_clear(RID p_shaped) {
sd->spans.clear();
sd->objects.clear();
sd->bidi_override.clear();
- invalidate(sd);
+ invalidate(sd, true);
}
void TextServerAdvanced::shaped_text_set_direction(RID p_shaped, TextServer::Direction p_direction) {
@@ -3017,7 +3022,7 @@ void TextServerAdvanced::shaped_text_set_direction(RID p_shaped, TextServer::Dir
full_copy(sd);
}
sd->direction = p_direction;
- invalidate(sd);
+ invalidate(sd, false);
}
}
@@ -3047,7 +3052,7 @@ void TextServerAdvanced::shaped_text_set_custom_punctuation(RID p_shaped, const
full_copy(sd);
}
sd->custom_punct = p_punct;
- invalidate(sd);
+ invalidate(sd, false);
}
}
@@ -3070,7 +3075,7 @@ void TextServerAdvanced::shaped_text_set_bidi_override(RID p_shaped, const Array
for (int i = 0; i < p_override.size(); i++) {
sd->bidi_override.push_back(p_override[i]);
}
- invalidate(sd);
+ invalidate(sd, false);
}
void TextServerAdvanced::shaped_text_set_orientation(RID p_shaped, TextServer::Orientation p_orientation) {
@@ -3083,7 +3088,7 @@ void TextServerAdvanced::shaped_text_set_orientation(RID p_shaped, TextServer::O
full_copy(sd);
}
sd->orientation = p_orientation;
- invalidate(sd);
+ invalidate(sd, false);
}
}
@@ -3095,7 +3100,7 @@ void TextServerAdvanced::shaped_text_set_preserve_invalid(RID p_shaped, bool p_e
ERR_FAIL_COND(sd->parent != RID());
if (sd->preserve_invalid != p_enabled) {
sd->preserve_invalid = p_enabled;
- invalidate(sd);
+ invalidate(sd, false);
}
}
@@ -3117,7 +3122,7 @@ void TextServerAdvanced::shaped_text_set_preserve_control(RID p_shaped, bool p_e
full_copy(sd);
}
sd->preserve_control = p_enabled;
- invalidate(sd);
+ invalidate(sd, false);
}
}
@@ -3137,7 +3142,41 @@ TextServer::Orientation TextServerAdvanced::shaped_text_get_orientation(RID p_sh
return sd->orientation;
}
-bool TextServerAdvanced::shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) {
+int TextServerAdvanced::shaped_get_span_count(RID p_shaped) const {
+ ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
+ ERR_FAIL_COND_V(!sd, 0);
+ return sd->spans.size();
+}
+
+Variant TextServerAdvanced::shaped_get_span_meta(RID p_shaped, int p_index) const {
+ ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
+ ERR_FAIL_COND_V(!sd, Variant());
+ ERR_FAIL_INDEX_V(p_index, sd->spans.size(), Variant());
+ return sd->spans[p_index].meta;
+}
+
+void TextServerAdvanced::shaped_set_span_update_font(RID p_shaped, int p_index, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features) {
+ ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
+ ERR_FAIL_COND(!sd);
+ ERR_FAIL_INDEX(p_index, sd->spans.size());
+
+ ShapedTextDataAdvanced::Span &span = sd->spans.write[p_index];
+ bool changed = (span.font_size != p_size) || (span.features != p_opentype_features) || (p_fonts.size() != span.fonts.size());
+ if (!changed) {
+ for (int i = 0; i < p_fonts.size(); i++) {
+ changed = changed || (span.fonts[i] != p_fonts[i]);
+ }
+ }
+ if (changed) {
+ span.fonts = p_fonts;
+ span.font_size = p_size;
+ span.features = p_opentype_features;
+
+ invalidate(sd, false);
+ }
+}
+
+bool TextServerAdvanced::shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
ERR_FAIL_COND_V(p_size <= 0, false);
@@ -3162,11 +3201,12 @@ bool TextServerAdvanced::shaped_text_add_string(RID p_shaped, const String &p_te
span.font_size = p_size;
span.language = p_language;
span.features = p_opentype_features;
+ span.meta = p_meta;
sd->spans.push_back(span);
sd->text += p_text;
sd->end += p_text.length();
- invalidate(sd);
+ invalidate(sd, true);
return true;
}
@@ -3196,13 +3236,13 @@ bool TextServerAdvanced::shaped_text_add_object(RID p_shaped, Variant p_key, con
sd->text += String::chr(0xfffc).repeat(p_length);
sd->end += p_length;
sd->objects[p_key] = obj;
- invalidate(sd);
+ invalidate(sd, true);
return true;
}
bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ ShapedTextDataAdvanced *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
@@ -3222,7 +3262,7 @@ bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key,
Glyph gl = sd->glyphs[i];
Variant key;
if (gl.count == 1) {
- for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
+ for (const KeyValue<Variant, ShapedTextDataAdvanced::EmbeddedObject> &E : sd->objects) {
if (E.value.pos == gl.start) {
key = E.key;
break;
@@ -3262,75 +3302,78 @@ bool TextServerAdvanced::shaped_text_resize_object(RID p_shaped, Variant p_key,
sd->width += gl.advance * gl.repeat;
}
}
+ _realign(sd);
+ }
+ return true;
+}
- // Align embedded objects to baseline.
- float full_ascent = sd->ascent;
- float full_descent = sd->descent;
- for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
- if ((E.value.pos >= sd->start) && (E.value.pos < sd->end)) {
- if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
- case INLINE_ALIGNMENT_TO_TOP: {
- E.value.rect.position.y = -sd->ascent;
- } break;
- case INLINE_ALIGNMENT_TO_CENTER: {
- E.value.rect.position.y = (-sd->ascent + sd->descent) / 2;
- } break;
- case INLINE_ALIGNMENT_TO_BASELINE: {
- E.value.rect.position.y = 0;
- } break;
- case INLINE_ALIGNMENT_TO_BOTTOM: {
- E.value.rect.position.y = sd->descent;
- } break;
- }
- switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
- case INLINE_ALIGNMENT_BOTTOM_TO: {
- E.value.rect.position.y -= E.value.rect.size.y;
- } break;
- case INLINE_ALIGNMENT_CENTER_TO: {
- E.value.rect.position.y -= E.value.rect.size.y / 2;
- } break;
- case INLINE_ALIGNMENT_TOP_TO: {
- // NOP
- } break;
- }
- full_ascent = MAX(full_ascent, -E.value.rect.position.y);
- full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y);
- } else {
- switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
- case INLINE_ALIGNMENT_TO_TOP: {
- E.value.rect.position.x = -sd->ascent;
- } break;
- case INLINE_ALIGNMENT_TO_CENTER: {
- E.value.rect.position.x = (-sd->ascent + sd->descent) / 2;
- } break;
- case INLINE_ALIGNMENT_TO_BASELINE: {
- E.value.rect.position.x = 0;
- } break;
- case INLINE_ALIGNMENT_TO_BOTTOM: {
- E.value.rect.position.x = sd->descent;
- } break;
- }
- switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
- case INLINE_ALIGNMENT_BOTTOM_TO: {
- E.value.rect.position.x -= E.value.rect.size.x;
- } break;
- case INLINE_ALIGNMENT_CENTER_TO: {
- E.value.rect.position.x -= E.value.rect.size.x / 2;
- } break;
- case INLINE_ALIGNMENT_TOP_TO: {
- // NOP
- } break;
- }
- full_ascent = MAX(full_ascent, -E.value.rect.position.x);
- full_descent = MAX(full_descent, E.value.rect.position.x + E.value.rect.size.x);
+void TextServerAdvanced::_realign(ShapedTextDataAdvanced *p_sd) const {
+ // Align embedded objects to baseline.
+ float full_ascent = p_sd->ascent;
+ float full_descent = p_sd->descent;
+ for (KeyValue<Variant, ShapedTextDataAdvanced::EmbeddedObject> &E : p_sd->objects) {
+ if ((E.value.pos >= p_sd->start) && (E.value.pos < p_sd->end)) {
+ if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
+ E.value.rect.position.y = -p_sd->ascent;
+ } break;
+ case INLINE_ALIGNMENT_TO_CENTER: {
+ E.value.rect.position.y = (-p_sd->ascent + p_sd->descent) / 2;
+ } break;
+ case INLINE_ALIGNMENT_TO_BASELINE: {
+ E.value.rect.position.y = 0;
+ } break;
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
+ E.value.rect.position.y = p_sd->descent;
+ } break;
+ }
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
+ E.value.rect.position.y -= E.value.rect.size.y;
+ } break;
+ case INLINE_ALIGNMENT_CENTER_TO: {
+ E.value.rect.position.y -= E.value.rect.size.y / 2;
+ } break;
+ case INLINE_ALIGNMENT_TOP_TO: {
+ // NOP
+ } break;
+ }
+ full_ascent = MAX(full_ascent, -E.value.rect.position.y);
+ full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y);
+ } else {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
+ E.value.rect.position.x = -p_sd->ascent;
+ } break;
+ case INLINE_ALIGNMENT_TO_CENTER: {
+ E.value.rect.position.x = (-p_sd->ascent + p_sd->descent) / 2;
+ } break;
+ case INLINE_ALIGNMENT_TO_BASELINE: {
+ E.value.rect.position.x = 0;
+ } break;
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
+ E.value.rect.position.x = p_sd->descent;
+ } break;
+ }
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
+ E.value.rect.position.x -= E.value.rect.size.x;
+ } break;
+ case INLINE_ALIGNMENT_CENTER_TO: {
+ E.value.rect.position.x -= E.value.rect.size.x / 2;
+ } break;
+ case INLINE_ALIGNMENT_TOP_TO: {
+ // NOP
+ } break;
}
+ full_ascent = MAX(full_ascent, -E.value.rect.position.x);
+ full_descent = MAX(full_descent, E.value.rect.position.x + E.value.rect.size.x);
}
}
- sd->ascent = full_ascent;
- sd->descent = full_descent;
}
- return true;
+ p_sd->ascent = full_ascent;
+ p_sd->descent = full_descent;
}
RID TextServerAdvanced::shaped_text_substr(RID p_shaped, int p_start, int p_length) const {
@@ -3423,7 +3466,7 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S
Variant key;
bool find_embedded = false;
if (gl.count == 1) {
- for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : p_sd->objects) {
+ for (const KeyValue<Variant, ShapedTextDataAdvanced::EmbeddedObject> &E : p_sd->objects) {
if (E.value.pos == gl.start) {
find_embedded = true;
key = E.key;
@@ -3466,72 +3509,7 @@ bool TextServerAdvanced::_shape_substr(ShapedTextDataAdvanced *p_new_sd, const S
}
}
- // Align embedded objects to baseline.
- float full_ascent = p_new_sd->ascent;
- float full_descent = p_new_sd->descent;
- for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : p_new_sd->objects) {
- if ((E.value.pos >= p_new_sd->start) && (E.value.pos < p_new_sd->end)) {
- if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
- case INLINE_ALIGNMENT_TO_TOP: {
- E.value.rect.position.y = -p_new_sd->ascent;
- } break;
- case INLINE_ALIGNMENT_TO_CENTER: {
- E.value.rect.position.y = (-p_new_sd->ascent + p_new_sd->descent) / 2;
- } break;
- case INLINE_ALIGNMENT_TO_BASELINE: {
- E.value.rect.position.y = 0;
- } break;
- case INLINE_ALIGNMENT_TO_BOTTOM: {
- E.value.rect.position.y = p_new_sd->descent;
- } break;
- }
- switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
- case INLINE_ALIGNMENT_BOTTOM_TO: {
- E.value.rect.position.y -= E.value.rect.size.y;
- } break;
- case INLINE_ALIGNMENT_CENTER_TO: {
- E.value.rect.position.y -= E.value.rect.size.y / 2;
- } break;
- case INLINE_ALIGNMENT_TOP_TO: {
- // NOP
- } break;
- }
- full_ascent = MAX(full_ascent, -E.value.rect.position.y);
- full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y);
- } else {
- switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
- case INLINE_ALIGNMENT_TO_TOP: {
- E.value.rect.position.x = -p_new_sd->ascent;
- } break;
- case INLINE_ALIGNMENT_TO_CENTER: {
- E.value.rect.position.x = (-p_new_sd->ascent + p_new_sd->descent) / 2;
- } break;
- case INLINE_ALIGNMENT_TO_BASELINE: {
- E.value.rect.position.x = 0;
- } break;
- case INLINE_ALIGNMENT_TO_BOTTOM: {
- E.value.rect.position.x = p_new_sd->descent;
- } break;
- }
- switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
- case INLINE_ALIGNMENT_BOTTOM_TO: {
- E.value.rect.position.x -= E.value.rect.size.x;
- } break;
- case INLINE_ALIGNMENT_CENTER_TO: {
- E.value.rect.position.x -= E.value.rect.size.x / 2;
- } break;
- case INLINE_ALIGNMENT_TOP_TO: {
- // NOP
- } break;
- }
- full_ascent = MAX(full_ascent, -E.value.rect.position.x);
- full_descent = MAX(full_descent, E.value.rect.position.x + E.value.rect.size.x);
- }
- }
- }
- p_new_sd->ascent = full_ascent;
- p_new_sd->descent = full_descent;
+ _realign(p_new_sd);
}
p_new_sd->valid = true;
@@ -3968,40 +3946,43 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) {
const UChar *data = sd->utf16.ptr();
- HashMap<int, bool> breaks;
- UErrorCode err = U_ZERO_ERROR;
- int i = 0;
- while (i < sd->spans.size()) {
- String language = sd->spans[i].language;
- int r_start = sd->spans[i].start;
- while (i + 1 < sd->spans.size() && language == sd->spans[i + 1].language) {
- i++;
- }
- int r_end = sd->spans[i].end;
- UBreakIterator *bi = ubrk_open(UBRK_LINE, language.ascii().get_data(), data + _convert_pos_inv(sd, r_start), _convert_pos_inv(sd, r_end - r_start), &err);
- if (U_FAILURE(err)) {
- // No data loaded - use fallback.
- for (int j = r_start; j < r_end; j++) {
- char32_t c = sd->text[j - sd->start];
- if (is_whitespace(c)) {
- breaks[j + 1] = false;
- }
- if (is_linebreak(c)) {
- breaks[j + 1] = true;
- }
+ if (!sd->break_ops_valid) {
+ sd->breaks.clear();
+ UErrorCode err = U_ZERO_ERROR;
+ int i = 0;
+ while (i < sd->spans.size()) {
+ String language = sd->spans[i].language;
+ int r_start = sd->spans[i].start;
+ while (i + 1 < sd->spans.size() && language == sd->spans[i + 1].language) {
+ i++;
}
- } else {
- while (ubrk_next(bi) != UBRK_DONE) {
- int pos = _convert_pos(sd, ubrk_current(bi)) + r_start;
- if ((ubrk_getRuleStatus(bi) >= UBRK_LINE_HARD) && (ubrk_getRuleStatus(bi) < UBRK_LINE_HARD_LIMIT)) {
- breaks[pos] = true;
- } else if ((ubrk_getRuleStatus(bi) >= UBRK_LINE_SOFT) && (ubrk_getRuleStatus(bi) < UBRK_LINE_SOFT_LIMIT)) {
- breaks[pos] = false;
+ int r_end = sd->spans[i].end;
+ UBreakIterator *bi = ubrk_open(UBRK_LINE, language.ascii().get_data(), data + _convert_pos_inv(sd, r_start), _convert_pos_inv(sd, r_end - r_start), &err);
+ if (U_FAILURE(err)) {
+ // No data loaded - use fallback.
+ for (int j = r_start; j < r_end; j++) {
+ char32_t c = sd->text[j - sd->start];
+ if (is_whitespace(c)) {
+ sd->breaks[j + 1] = false;
+ }
+ if (is_linebreak(c)) {
+ sd->breaks[j + 1] = true;
+ }
+ }
+ } else {
+ while (ubrk_next(bi) != UBRK_DONE) {
+ int pos = _convert_pos(sd, ubrk_current(bi)) + r_start;
+ if ((ubrk_getRuleStatus(bi) >= UBRK_LINE_HARD) && (ubrk_getRuleStatus(bi) < UBRK_LINE_HARD_LIMIT)) {
+ sd->breaks[pos] = true;
+ } else if ((ubrk_getRuleStatus(bi) >= UBRK_LINE_SOFT) && (ubrk_getRuleStatus(bi) < UBRK_LINE_SOFT_LIMIT)) {
+ sd->breaks[pos] = false;
+ }
}
}
+ ubrk_close(bi);
+ i++;
}
- ubrk_close(bi);
- i++;
+ sd->break_ops_valid = true;
}
sd->sort_valid = false;
@@ -4013,7 +3994,7 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) {
int c_punct_size = sd->custom_punct.length();
const char32_t *c_punct = sd->custom_punct.ptr();
- for (i = 0; i < sd_size; i++) {
+ for (int i = 0; i < sd_size; i++) {
if (sd_glyphs[i].count > 0) {
char32_t c = ch[sd_glyphs[i].start - sd->start];
if (c == 0xfffc) {
@@ -4040,8 +4021,8 @@ bool TextServerAdvanced::shaped_text_update_breaks(RID p_shaped) {
if (is_underscore(c)) {
sd_glyphs[i].flags |= GRAPHEME_IS_UNDERSCORE;
}
- if (breaks.has(sd_glyphs[i].end)) {
- if (breaks[sd_glyphs[i].end] && (is_linebreak(c))) {
+ if (sd->breaks.has(sd_glyphs[i].end)) {
+ if (sd->breaks[sd_glyphs[i].end] && (is_linebreak(c))) {
sd_glyphs[i].flags |= GRAPHEME_IS_BREAK_HARD;
} else if (is_whitespace(c)) {
sd_glyphs[i].flags |= GRAPHEME_IS_BREAK_SOFT;
@@ -4186,41 +4167,45 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(RID p_shaped) {
const UChar *data = sd->utf16.ptr();
int32_t data_size = sd->utf16.length();
- Map<int, bool> jstops;
+ if (!sd->js_ops_valid) {
+ sd->jstops.clear();
- // Use ICU word iterator and custom kashida detection.
- UErrorCode err = U_ZERO_ERROR;
- UBreakIterator *bi = ubrk_open(UBRK_WORD, "", data, data_size, &err);
- if (U_FAILURE(err)) {
- // No data - use fallback.
- int limit = 0;
- for (int i = 0; i < sd->text.length(); i++) {
- if (is_whitespace(data[i])) {
- int ks = _generate_kashida_justification_opportunies(sd->text, limit, i) + sd->start;
- if (ks != -1) {
- jstops[ks] = true;
- }
- limit = i + 1;
+ // Use ICU word iterator and custom kashida detection.
+ UErrorCode err = U_ZERO_ERROR;
+ UBreakIterator *bi = ubrk_open(UBRK_WORD, "", data, data_size, &err);
+ if (U_FAILURE(err)) {
+ // No data - use fallback.
+ int limit = 0;
+ for (int i = 0; i < sd->text.length(); i++) {
+ if (is_whitespace(data[i])) {
+ int ks = _generate_kashida_justification_opportunies(sd->text, limit, i) + sd->start;
+ if (ks != -1) {
+ sd->jstops[ks] = true;
+ }
+ limit = i + 1;
+ }
}
- }
- int ks = _generate_kashida_justification_opportunies(sd->text, limit, sd->text.length()) + sd->start;
- if (ks != -1) {
- jstops[ks] = true;
- }
- } else {
- int limit = 0;
- while (ubrk_next(bi) != UBRK_DONE) {
- if (ubrk_getRuleStatus(bi) != UBRK_WORD_NONE) {
- int i = _convert_pos(sd, ubrk_current(bi));
- jstops[i + sd->start] = false;
- int ks = _generate_kashida_justification_opportunies(sd->text, limit, i);
- if (ks != -1) {
- jstops[ks + sd->start] = true;
- }
- limit = i;
+ int ks = _generate_kashida_justification_opportunies(sd->text, limit, sd->text.length()) + sd->start;
+ if (ks != -1) {
+ sd->jstops[ks] = true;
}
+ } else {
+ int limit = 0;
+ while (ubrk_next(bi) != UBRK_DONE) {
+ if (ubrk_getRuleStatus(bi) != UBRK_WORD_NONE) {
+ int i = _convert_pos(sd, ubrk_current(bi));
+ sd->jstops[i + sd->start] = false;
+ int ks = _generate_kashida_justification_opportunies(sd->text, limit, i);
+ if (ks != -1) {
+ sd->jstops[ks + sd->start] = true;
+ }
+ limit = i;
+ }
+ }
+ ubrk_close(bi);
}
- ubrk_close(bi);
+
+ sd->js_ops_valid = true;
}
sd->sort_valid = false;
@@ -4228,18 +4213,18 @@ bool TextServerAdvanced::shaped_text_update_justification_ops(RID p_shaped) {
Glyph *sd_glyphs = sd->glyphs.ptrw();
int sd_size = sd->glyphs.size();
- if (jstops.size() > 0) {
+ if (sd->jstops.size() > 0) {
for (int i = 0; i < sd_size; i++) {
if (sd_glyphs[i].count > 0) {
char32_t c = sd->text[sd_glyphs[i].start - sd->start];
if (c == 0x0640) {
sd_glyphs[i].flags |= GRAPHEME_IS_ELONGATION;
}
- if (jstops.has(sd_glyphs[i].start)) {
+ if (sd->jstops.has(sd_glyphs[i].start)) {
if (c == 0xfffc) {
continue;
}
- if (jstops[sd_glyphs[i].start]) {
+ if (sd->jstops[sd_glyphs[i].start]) {
if (c != 0x0640) {
if (sd_glyphs[i].font_rid != RID()) {
Glyph gl = _shape_single_glyph(sd, 0x0640, HB_SCRIPT_ARABIC, HB_DIRECTION_RTL, sd->glyphs[i].font_rid, sd->glyphs[i].font_size);
@@ -4574,7 +4559,7 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) {
return true;
}
- invalidate(sd);
+ invalidate(sd, false);
if (sd->parent != RID()) {
shaped_text_shape(sd->parent);
ShapedTextDataAdvanced *parent_sd = shaped_owner.get_or_null(sd->parent);
@@ -4733,70 +4718,7 @@ bool TextServerAdvanced::shaped_text_shape(RID p_shaped) {
}
}
- // Align embedded objects to baseline.
- float full_ascent = sd->ascent;
- float full_descent = sd->descent;
- for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
- if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
- case INLINE_ALIGNMENT_TO_TOP: {
- E.value.rect.position.y = -sd->ascent;
- } break;
- case INLINE_ALIGNMENT_TO_CENTER: {
- E.value.rect.position.y = (-sd->ascent + sd->descent) / 2;
- } break;
- case INLINE_ALIGNMENT_TO_BASELINE: {
- E.value.rect.position.y = 0;
- } break;
- case INLINE_ALIGNMENT_TO_BOTTOM: {
- E.value.rect.position.y = sd->descent;
- } break;
- }
- switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
- case INLINE_ALIGNMENT_BOTTOM_TO: {
- E.value.rect.position.y -= E.value.rect.size.y;
- } break;
- case INLINE_ALIGNMENT_CENTER_TO: {
- E.value.rect.position.y -= E.value.rect.size.y / 2;
- } break;
- case INLINE_ALIGNMENT_TOP_TO: {
- // NOP
- } break;
- }
- full_ascent = MAX(full_ascent, -E.value.rect.position.y);
- full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y);
- } else {
- switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
- case INLINE_ALIGNMENT_TO_TOP: {
- E.value.rect.position.x = -sd->ascent;
- } break;
- case INLINE_ALIGNMENT_TO_CENTER: {
- E.value.rect.position.x = (-sd->ascent + sd->descent) / 2;
- } break;
- case INLINE_ALIGNMENT_TO_BASELINE: {
- E.value.rect.position.x = 0;
- } break;
- case INLINE_ALIGNMENT_TO_BOTTOM: {
- E.value.rect.position.x = sd->descent;
- } break;
- }
- switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
- case INLINE_ALIGNMENT_BOTTOM_TO: {
- E.value.rect.position.x -= E.value.rect.size.x;
- } break;
- case INLINE_ALIGNMENT_CENTER_TO: {
- E.value.rect.position.x -= E.value.rect.size.x / 2;
- } break;
- case INLINE_ALIGNMENT_TOP_TO: {
- // NOP
- } break;
- }
- full_ascent = MAX(full_ascent, -E.value.rect.position.x);
- full_descent = MAX(full_descent, E.value.rect.position.x + E.value.rect.size.x);
- }
- }
- sd->ascent = full_ascent;
- sd->descent = full_descent;
+ _realign(sd);
sd->valid = true;
return sd->valid;
}
@@ -4863,7 +4785,7 @@ Array TextServerAdvanced::shaped_text_get_objects(RID p_shaped) const {
ERR_FAIL_COND_V(!sd, ret);
MutexLock lock(sd->mutex);
- for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
+ for (const KeyValue<Variant, ShapedTextDataAdvanced::EmbeddedObject> &E : sd->objects) {
ret.push_back(E.key);
}
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index f2ae24cae6..145d740b68 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -242,6 +242,21 @@ class TextServerAdvanced : public TextServer {
// Shaped text cache data.
struct ShapedTextDataAdvanced : public ShapedTextData {
+ struct Span {
+ int start = -1;
+ int end = -1;
+
+ Vector<RID> fonts;
+ int font_size = 0;
+
+ Variant embedded_key;
+
+ String language;
+ Dictionary features;
+ Variant meta;
+ };
+ Vector<Span> spans;
+
/* Intermediate data */
Char16String utf16;
Vector<UBiDi *> bidi_iter;
@@ -249,6 +264,11 @@ class TextServerAdvanced : public TextServer {
ScriptIterator *script_iter = nullptr;
hb_buffer_t *hb_buffer = nullptr;
+ HashMap<int, bool> jstops;
+ HashMap<int, bool> breaks;
+ bool break_ops_valid = false;
+ bool js_ops_valid = false;
+
~ShapedTextDataAdvanced() {
for (int i = 0; i < bidi_iter.size(); i++) {
ubidi_close(bidi_iter[i]);
@@ -268,6 +288,7 @@ class TextServerAdvanced : public TextServer {
mutable RID_PtrOwner<FontDataAdvanced> font_owner;
mutable RID_PtrOwner<ShapedTextDataAdvanced> shaped_owner;
+ void _realign(ShapedTextDataAdvanced *p_sd) const;
int _convert_pos(const ShapedTextDataAdvanced *p_sd, int p_pos) const;
int _convert_pos_inv(const ShapedTextDataAdvanced *p_sd, int p_pos) const;
bool _shape_substr(ShapedTextDataAdvanced *p_new_sd, const ShapedTextDataAdvanced *p_sd, int p_start, int p_length) const;
@@ -302,7 +323,7 @@ protected:
static void _bind_methods(){};
void full_copy(ShapedTextDataAdvanced *p_shaped);
- void invalidate(ShapedTextDataAdvanced *p_shaped);
+ void invalidate(ShapedTextDataAdvanced *p_shaped, bool p_text = false);
public:
virtual bool has_feature(Feature p_feature) const override;
@@ -482,10 +503,14 @@ public:
virtual void shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) override;
virtual bool shaped_text_get_preserve_control(RID p_shaped) const override;
- virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") override;
+ virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override;
virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) override;
virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
+ virtual int shaped_get_span_count(RID p_shaped) const override;
+ virtual Variant shaped_get_span_meta(RID p_shaped, int p_index) const override;
+ virtual void shaped_set_span_update_font(RID p_shaped, int p_index, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary()) override;
+
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override;
virtual RID shaped_text_get_parent(RID p_shaped) const override;
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp
index ffbd2da22d..dd520a2e40 100644
--- a/modules/text_server_fb/text_server_fb.cpp
+++ b/modules/text_server_fb/text_server_fb.cpp
@@ -91,7 +91,7 @@ void TextServerFallback::free(RID p_rid) {
font_owner.free(p_rid);
memdelete(fd);
} else if (shaped_owner.owns(p_rid)) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_rid);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_rid);
shaped_owner.free(p_rid);
memdelete(sd);
}
@@ -127,8 +127,9 @@ _FORCE_INLINE_ int32_t ot_tag_from_string(const char *p_str, int p_len) {
char tag[4];
uint32_t i;
- if (!p_str || !p_len || !*p_str)
+ if (!p_str || !p_len || !*p_str) {
return OT_TAG(0, 0, 0, 0);
+ }
if (p_len < 0 || p_len > 4) {
p_len = 4;
@@ -2060,7 +2061,7 @@ void TextServerFallback::font_set_global_oversampling(float p_oversampling) {
/* Shaped text buffer interface */
/*************************************************************************/
-void TextServerFallback::invalidate(ShapedTextData *p_shaped) {
+void TextServerFallback::invalidate(ShapedTextDataFallback *p_shaped) {
p_shaped->valid = false;
p_shaped->sort_valid = false;
p_shaped->line_breaks_valid = false;
@@ -2074,17 +2075,17 @@ void TextServerFallback::invalidate(ShapedTextData *p_shaped) {
p_shaped->glyphs_logical.clear();
}
-void TextServerFallback::full_copy(ShapedTextData *p_shaped) {
- ShapedTextData *parent = shaped_owner.get_or_null(p_shaped->parent);
+void TextServerFallback::full_copy(ShapedTextDataFallback *p_shaped) {
+ ShapedTextDataFallback *parent = shaped_owner.get_or_null(p_shaped->parent);
- for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : parent->objects) {
+ for (const KeyValue<Variant, ShapedTextDataFallback::EmbeddedObject> &E : parent->objects) {
if (E.value.pos >= p_shaped->start && E.value.pos < p_shaped->end) {
p_shaped->objects[E.key] = E.value;
}
}
for (int k = 0; k < parent->spans.size(); k++) {
- ShapedTextData::Span span = parent->spans[k];
+ ShapedTextDataFallback::Span span = parent->spans[k];
if (span.start >= p_shaped->end || span.end <= p_shaped->start) {
continue;
}
@@ -2098,7 +2099,7 @@ void TextServerFallback::full_copy(ShapedTextData *p_shaped) {
RID TextServerFallback::create_shaped_text(TextServer::Direction p_direction, TextServer::Orientation p_orientation) {
_THREAD_SAFE_METHOD_
- ShapedTextData *sd = memnew(ShapedTextData);
+ ShapedTextDataFallback *sd = memnew(ShapedTextDataFallback);
sd->direction = p_direction;
sd->orientation = p_orientation;
@@ -2106,7 +2107,7 @@ RID TextServerFallback::create_shaped_text(TextServer::Direction p_direction, Te
}
void TextServerFallback::shaped_text_clear(RID p_shaped) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
MutexLock lock(sd->mutex);
@@ -2135,7 +2136,7 @@ TextServer::Direction TextServerFallback::shaped_text_get_inferred_direction(RID
void TextServerFallback::shaped_text_set_custom_punctuation(RID p_shaped, const String &p_punct) {
_THREAD_SAFE_METHOD_
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
if (sd->custom_punct != p_punct) {
@@ -2149,13 +2150,13 @@ void TextServerFallback::shaped_text_set_custom_punctuation(RID p_shaped, const
String TextServerFallback::shaped_text_get_custom_punctuation(RID p_shaped) const {
_THREAD_SAFE_METHOD_
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, String());
return sd->custom_punct;
}
void TextServerFallback::shaped_text_set_orientation(RID p_shaped, TextServer::Orientation p_orientation) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
MutexLock lock(sd->mutex);
@@ -2173,7 +2174,7 @@ void TextServerFallback::shaped_text_set_bidi_override(RID p_shaped, const Array
}
TextServer::Orientation TextServerFallback::shaped_text_get_orientation(RID p_shaped) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, TextServer::ORIENTATION_HORIZONTAL);
MutexLock lock(sd->mutex);
@@ -2181,7 +2182,7 @@ TextServer::Orientation TextServerFallback::shaped_text_get_orientation(RID p_sh
}
void TextServerFallback::shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
MutexLock lock(sd->mutex);
ERR_FAIL_COND(!sd);
@@ -2195,7 +2196,7 @@ void TextServerFallback::shaped_text_set_preserve_invalid(RID p_shaped, bool p_e
}
bool TextServerFallback::shaped_text_get_preserve_invalid(RID p_shaped) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
@@ -2203,7 +2204,7 @@ bool TextServerFallback::shaped_text_get_preserve_invalid(RID p_shaped) const {
}
void TextServerFallback::shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND(!sd);
MutexLock lock(sd->mutex);
@@ -2217,15 +2218,52 @@ void TextServerFallback::shaped_text_set_preserve_control(RID p_shaped, bool p_e
}
bool TextServerFallback::shaped_text_get_preserve_control(RID p_shaped) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
return sd->preserve_control;
}
-bool TextServerFallback::shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+int TextServerFallback::shaped_get_span_count(RID p_shaped) const {
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
+ ERR_FAIL_COND_V(!sd, 0);
+ return sd->spans.size();
+}
+
+Variant TextServerFallback::shaped_get_span_meta(RID p_shaped, int p_index) const {
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
+ ERR_FAIL_COND_V(!sd, Variant());
+ ERR_FAIL_INDEX_V(p_index, sd->spans.size(), Variant());
+ return sd->spans[p_index].meta;
+}
+
+void TextServerFallback::shaped_set_span_update_font(RID p_shaped, int p_index, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features) {
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
+ ERR_FAIL_COND(!sd);
+ ERR_FAIL_INDEX(p_index, sd->spans.size());
+
+ ShapedTextDataFallback::Span &span = sd->spans.write[p_index];
+ span.fonts.clear();
+ // Pre-sort fonts, push fonts with the language support first.
+ Vector<RID> fonts_no_match;
+ int font_count = p_fonts.size();
+ for (int i = 0; i < font_count; i++) {
+ if (font_is_language_supported(p_fonts[i], span.language)) {
+ span.fonts.push_back(p_fonts[i]);
+ } else {
+ fonts_no_match.push_back(p_fonts[i]);
+ }
+ }
+ span.fonts.append_array(fonts_no_match);
+ span.font_size = p_size;
+ span.features = p_opentype_features;
+
+ sd->valid = false;
+}
+
+bool TextServerFallback::shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
@@ -2243,7 +2281,7 @@ bool TextServerFallback::shaped_text_add_string(RID p_shaped, const String &p_te
full_copy(sd);
}
- ShapedTextData::Span span;
+ ShapedTextDataFallback::Span span;
span.start = sd->text.length();
span.end = span.start + p_text.length();
@@ -2262,6 +2300,7 @@ bool TextServerFallback::shaped_text_add_string(RID p_shaped, const String &p_te
ERR_FAIL_COND_V(span.fonts.is_empty(), false);
span.font_size = p_size;
span.language = p_language;
+ span.meta = p_meta;
sd->spans.push_back(span);
sd->text += p_text;
@@ -2272,7 +2311,7 @@ bool TextServerFallback::shaped_text_add_string(RID p_shaped, const String &p_te
}
bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align, int p_length) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
@@ -2283,12 +2322,12 @@ bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, con
full_copy(sd);
}
- ShapedTextData::Span span;
+ ShapedTextDataFallback::Span span;
span.start = sd->start + sd->text.length();
span.end = span.start + p_length;
span.embedded_key = p_key;
- ShapedTextData::EmbeddedObject obj;
+ ShapedTextDataFallback::EmbeddedObject obj;
obj.inline_align = p_inline_align;
obj.rect.size = p_size;
obj.pos = span.start;
@@ -2303,7 +2342,7 @@ bool TextServerFallback::shaped_text_add_object(RID p_shaped, Variant p_key, con
}
bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
@@ -2323,7 +2362,7 @@ bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key,
Glyph gl = sd->glyphs[i];
Variant key;
if (gl.count == 1) {
- for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
+ for (const KeyValue<Variant, ShapedTextDataFallback::EmbeddedObject> &E : sd->objects) {
if (E.value.pos == gl.start) {
key = E.key;
break;
@@ -2363,79 +2402,82 @@ bool TextServerFallback::shaped_text_resize_object(RID p_shaped, Variant p_key,
sd->width += gl.advance * gl.repeat;
}
}
+ _realign(sd);
+ }
+ return true;
+}
- // Align embedded objects to baseline.
- float full_ascent = sd->ascent;
- float full_descent = sd->descent;
- for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
- if ((E.value.pos >= sd->start) && (E.value.pos < sd->end)) {
- if (sd->orientation == ORIENTATION_HORIZONTAL) {
- switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
- case INLINE_ALIGNMENT_TO_TOP: {
- E.value.rect.position.y = -sd->ascent;
- } break;
- case INLINE_ALIGNMENT_TO_CENTER: {
- E.value.rect.position.y = (-sd->ascent + sd->descent) / 2;
- } break;
- case INLINE_ALIGNMENT_TO_BASELINE: {
- E.value.rect.position.y = 0;
- } break;
- case INLINE_ALIGNMENT_TO_BOTTOM: {
- E.value.rect.position.y = sd->descent;
- } break;
- }
- switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
- case INLINE_ALIGNMENT_BOTTOM_TO: {
- E.value.rect.position.y -= E.value.rect.size.y;
- } break;
- case INLINE_ALIGNMENT_CENTER_TO: {
- E.value.rect.position.y -= E.value.rect.size.y / 2;
- } break;
- case INLINE_ALIGNMENT_TOP_TO: {
- // NOP
- } break;
- }
- full_ascent = MAX(full_ascent, -E.value.rect.position.y);
- full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y);
- } else {
- switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
- case INLINE_ALIGNMENT_TO_TOP: {
- E.value.rect.position.x = -sd->ascent;
- } break;
- case INLINE_ALIGNMENT_TO_CENTER: {
- E.value.rect.position.x = (-sd->ascent + sd->descent) / 2;
- } break;
- case INLINE_ALIGNMENT_TO_BASELINE: {
- E.value.rect.position.x = 0;
- } break;
- case INLINE_ALIGNMENT_TO_BOTTOM: {
- E.value.rect.position.x = sd->descent;
- } break;
- }
- switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
- case INLINE_ALIGNMENT_BOTTOM_TO: {
- E.value.rect.position.x -= E.value.rect.size.x;
- } break;
- case INLINE_ALIGNMENT_CENTER_TO: {
- E.value.rect.position.x -= E.value.rect.size.x / 2;
- } break;
- case INLINE_ALIGNMENT_TOP_TO: {
- // NOP
- } break;
- }
- full_ascent = MAX(full_ascent, -E.value.rect.position.x);
- full_descent = MAX(full_descent, E.value.rect.position.x + E.value.rect.size.x);
+void TextServerFallback::_realign(ShapedTextDataFallback *p_sd) const {
+ // Align embedded objects to baseline.
+ float full_ascent = p_sd->ascent;
+ float full_descent = p_sd->descent;
+ for (KeyValue<Variant, ShapedTextDataFallback::EmbeddedObject> &E : p_sd->objects) {
+ if ((E.value.pos >= p_sd->start) && (E.value.pos < p_sd->end)) {
+ if (p_sd->orientation == ORIENTATION_HORIZONTAL) {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
+ E.value.rect.position.y = -p_sd->ascent;
+ } break;
+ case INLINE_ALIGNMENT_TO_CENTER: {
+ E.value.rect.position.y = (-p_sd->ascent + p_sd->descent) / 2;
+ } break;
+ case INLINE_ALIGNMENT_TO_BASELINE: {
+ E.value.rect.position.y = 0;
+ } break;
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
+ E.value.rect.position.y = p_sd->descent;
+ } break;
+ }
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
+ E.value.rect.position.y -= E.value.rect.size.y;
+ } break;
+ case INLINE_ALIGNMENT_CENTER_TO: {
+ E.value.rect.position.y -= E.value.rect.size.y / 2;
+ } break;
+ case INLINE_ALIGNMENT_TOP_TO: {
+ // NOP
+ } break;
+ }
+ full_ascent = MAX(full_ascent, -E.value.rect.position.y);
+ full_descent = MAX(full_descent, E.value.rect.position.y + E.value.rect.size.y);
+ } else {
+ switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
+ case INLINE_ALIGNMENT_TO_TOP: {
+ E.value.rect.position.x = -p_sd->ascent;
+ } break;
+ case INLINE_ALIGNMENT_TO_CENTER: {
+ E.value.rect.position.x = (-p_sd->ascent + p_sd->descent) / 2;
+ } break;
+ case INLINE_ALIGNMENT_TO_BASELINE: {
+ E.value.rect.position.x = 0;
+ } break;
+ case INLINE_ALIGNMENT_TO_BOTTOM: {
+ E.value.rect.position.x = p_sd->descent;
+ } break;
+ }
+ switch (E.value.inline_align & INLINE_ALIGNMENT_IMAGE_MASK) {
+ case INLINE_ALIGNMENT_BOTTOM_TO: {
+ E.value.rect.position.x -= E.value.rect.size.x;
+ } break;
+ case INLINE_ALIGNMENT_CENTER_TO: {
+ E.value.rect.position.x -= E.value.rect.size.x / 2;
+ } break;
+ case INLINE_ALIGNMENT_TOP_TO: {
+ // NOP
+ } break;
}
+ full_ascent = MAX(full_ascent, -E.value.rect.position.x);
+ full_descent = MAX(full_descent, E.value.rect.position.x + E.value.rect.size.x);
}
}
- sd->ascent = full_ascent;
- sd->descent = full_descent;
}
- return true;
+ p_sd->ascent = full_ascent;
+ p_sd->descent = full_descent;
}
RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_length) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, RID());
MutexLock lock(sd->mutex);
@@ -2449,7 +2491,7 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng
ERR_FAIL_COND_V(sd->start > p_start || sd->end < p_start, RID());
ERR_FAIL_COND_V(sd->end < p_start + p_length, RID());
- ShapedTextData *new_sd = memnew(ShapedTextData);
+ ShapedTextDataFallback *new_sd = memnew(ShapedTextDataFallback);
new_sd->parent = p_shaped;
new_sd->start = p_start;
new_sd->end = p_start + p_length;
@@ -2475,7 +2517,7 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng
Variant key;
bool find_embedded = false;
if (gl.count == 1) {
- for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
+ for (const KeyValue<Variant, ShapedTextDataFallback::EmbeddedObject> &E : sd->objects) {
if (E.value.pos == gl.start) {
find_embedded = true;
key = E.key;
@@ -2519,7 +2561,7 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng
// Align embedded objects to baseline.
float full_ascent = new_sd->ascent;
float full_descent = new_sd->descent;
- for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : new_sd->objects) {
+ for (KeyValue<Variant, ShapedTextDataFallback::EmbeddedObject> &E : new_sd->objects) {
if ((E.value.pos >= new_sd->start) && (E.value.pos < new_sd->end)) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
@@ -2589,7 +2631,7 @@ RID TextServerFallback::shaped_text_substr(RID p_shaped, int p_start, int p_leng
}
RID TextServerFallback::shaped_text_get_parent(RID p_shaped) const {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, RID());
MutexLock lock(sd->mutex);
@@ -2597,7 +2639,7 @@ RID TextServerFallback::shaped_text_get_parent(RID p_shaped) const {
}
float TextServerFallback::shaped_text_fit_to_width(RID p_shaped, float p_width, uint16_t /*JustificationFlag*/ p_jst_flags) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
MutexLock lock(sd->mutex);
@@ -2706,7 +2748,7 @@ float TextServerFallback::shaped_text_fit_to_width(RID p_shaped, float p_width,
}
float TextServerFallback::shaped_text_tab_align(RID p_shaped, const PackedFloat32Array &p_tab_stops) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
MutexLock lock(sd->mutex);
@@ -2762,7 +2804,7 @@ float TextServerFallback::shaped_text_tab_align(RID p_shaped, const PackedFloat3
}
bool TextServerFallback::shaped_text_update_breaks(RID p_shaped) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
@@ -2818,7 +2860,7 @@ bool TextServerFallback::shaped_text_update_breaks(RID p_shaped) {
}
bool TextServerFallback::shaped_text_update_justification_ops(RID p_shaped) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
@@ -2834,7 +2876,7 @@ bool TextServerFallback::shaped_text_update_justification_ops(RID p_shaped) {
}
void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, float p_width, uint16_t p_trim_flags) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped_line);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped_line);
ERR_FAIL_COND_MSG(!sd, "ShapedTextDataFallback invalid.");
MutexLock lock(sd->mutex);
@@ -2862,9 +2904,9 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, fl
return;
}
- Vector<ShapedTextData::Span> &spans = sd->spans;
+ Vector<ShapedTextDataFallback::Span> &spans = sd->spans;
if (sd->parent != RID()) {
- ShapedTextData *parent_sd = shaped_owner.get_or_null(sd->parent);
+ ShapedTextDataFallback *parent_sd = shaped_owner.get_or_null(sd->parent);
ERR_FAIL_COND(!parent_sd->valid);
spans = parent_sd->spans;
}
@@ -2986,39 +3028,39 @@ void TextServerFallback::shaped_text_overrun_trim_to_width(RID p_shaped_line, fl
}
int TextServerFallback::shaped_text_get_trim_pos(RID p_shaped) const {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
- ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextData invalid.");
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
+ ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextDataFallback invalid.");
MutexLock lock(sd->mutex);
return sd->overrun_trim_data.trim_pos;
}
int TextServerFallback::shaped_text_get_ellipsis_pos(RID p_shaped) const {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
- ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextData invalid.");
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
+ ERR_FAIL_COND_V_MSG(!sd, -1, "ShapedTextDataFallback invalid.");
MutexLock lock(sd->mutex);
return sd->overrun_trim_data.ellipsis_pos;
}
const Glyph *TextServerFallback::shaped_text_get_ellipsis_glyphs(RID p_shaped) const {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
- ERR_FAIL_COND_V_MSG(!sd, nullptr, "ShapedTextData invalid.");
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
+ ERR_FAIL_COND_V_MSG(!sd, nullptr, "ShapedTextDataFallback invalid.");
MutexLock lock(sd->mutex);
return sd->overrun_trim_data.ellipsis_glyph_buf.ptr();
}
int TextServerFallback::shaped_text_get_ellipsis_glyph_count(RID p_shaped) const {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
- ERR_FAIL_COND_V_MSG(!sd, 0, "ShapedTextData invalid.");
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
+ ERR_FAIL_COND_V_MSG(!sd, 0, "ShapedTextDataFallback invalid.");
MutexLock lock(sd->mutex);
return sd->overrun_trim_data.ellipsis_glyph_buf.size();
}
bool TextServerFallback::shaped_text_shape(RID p_shaped) {
- ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
@@ -3045,7 +3087,7 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) {
// "Shape" string.
for (int i = 0; i < sd->spans.size(); i++) {
- const ShapedTextData::Span &span = sd->spans[i];
+ const ShapedTextDataFallback::Span &span = sd->spans[i];
if (span.embedded_key != Variant()) {
// Embedded object.
if (sd->orientation == ORIENTATION_HORIZONTAL) {
@@ -3145,7 +3187,7 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) {
// Align embedded objects to baseline.
float full_ascent = sd->ascent;
float full_descent = sd->descent;
- for (KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
+ for (KeyValue<Variant, ShapedTextDataFallback::EmbeddedObject> &E : sd->objects) {
if (sd->orientation == ORIENTATION_HORIZONTAL) {
switch (E.value.inline_align & INLINE_ALIGNMENT_TEXT_MASK) {
case INLINE_ALIGNMENT_TO_TOP: {
@@ -3211,7 +3253,7 @@ bool TextServerFallback::shaped_text_shape(RID p_shaped) {
}
bool TextServerFallback::shaped_text_is_ready(RID p_shaped) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, false);
MutexLock lock(sd->mutex);
@@ -3219,7 +3261,7 @@ bool TextServerFallback::shaped_text_is_ready(RID p_shaped) const {
}
const Glyph *TextServerFallback::shaped_text_get_glyphs(RID p_shaped) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, nullptr);
MutexLock lock(sd->mutex);
@@ -3230,7 +3272,7 @@ const Glyph *TextServerFallback::shaped_text_get_glyphs(RID p_shaped) const {
}
int TextServerFallback::shaped_text_get_glyph_count(RID p_shaped) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0);
MutexLock lock(sd->mutex);
@@ -3241,7 +3283,7 @@ int TextServerFallback::shaped_text_get_glyph_count(RID p_shaped) const {
}
const Glyph *TextServerFallback::shaped_text_sort_logical(RID p_shaped) {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, nullptr);
MutexLock lock(sd->mutex);
@@ -3253,7 +3295,7 @@ const Glyph *TextServerFallback::shaped_text_sort_logical(RID p_shaped) {
}
Vector2i TextServerFallback::shaped_text_get_range(RID p_shaped) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Vector2i());
MutexLock lock(sd->mutex);
@@ -3262,11 +3304,11 @@ Vector2i TextServerFallback::shaped_text_get_range(RID p_shaped) const {
Array TextServerFallback::shaped_text_get_objects(RID p_shaped) const {
Array ret;
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, ret);
MutexLock lock(sd->mutex);
- for (const KeyValue<Variant, ShapedTextData::EmbeddedObject> &E : sd->objects) {
+ for (const KeyValue<Variant, ShapedTextDataFallback::EmbeddedObject> &E : sd->objects) {
ret.push_back(E.key);
}
@@ -3274,7 +3316,7 @@ Array TextServerFallback::shaped_text_get_objects(RID p_shaped) const {
}
Rect2 TextServerFallback::shaped_text_get_object_rect(RID p_shaped, Variant p_key) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Rect2());
MutexLock lock(sd->mutex);
@@ -3286,7 +3328,7 @@ Rect2 TextServerFallback::shaped_text_get_object_rect(RID p_shaped, Variant p_ke
}
Size2 TextServerFallback::shaped_text_get_size(RID p_shaped) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, Size2());
MutexLock lock(sd->mutex);
@@ -3301,7 +3343,7 @@ Size2 TextServerFallback::shaped_text_get_size(RID p_shaped) const {
}
float TextServerFallback::shaped_text_get_ascent(RID p_shaped) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
MutexLock lock(sd->mutex);
@@ -3312,7 +3354,7 @@ float TextServerFallback::shaped_text_get_ascent(RID p_shaped) const {
}
float TextServerFallback::shaped_text_get_descent(RID p_shaped) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
MutexLock lock(sd->mutex);
@@ -3323,7 +3365,7 @@ float TextServerFallback::shaped_text_get_descent(RID p_shaped) const {
}
float TextServerFallback::shaped_text_get_width(RID p_shaped) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
MutexLock lock(sd->mutex);
@@ -3334,7 +3376,7 @@ float TextServerFallback::shaped_text_get_width(RID p_shaped) const {
}
float TextServerFallback::shaped_text_get_underline_position(RID p_shaped) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
MutexLock lock(sd->mutex);
@@ -3346,7 +3388,7 @@ float TextServerFallback::shaped_text_get_underline_position(RID p_shaped) const
}
float TextServerFallback::shaped_text_get_underline_thickness(RID p_shaped) const {
- const ShapedTextData *sd = shaped_owner.get_or_null(p_shaped);
+ const ShapedTextDataFallback *sd = shaped_owner.get_or_null(p_shaped);
ERR_FAIL_COND_V(!sd, 0.f);
MutexLock lock(sd->mutex);
diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h
index b356b90d2c..be944cde58 100644
--- a/modules/text_server_fb/text_server_fb.h
+++ b/modules/text_server_fb/text_server_fb.h
@@ -203,17 +203,38 @@ class TextServerFallback : public TextServer {
}
}
+ // Shaped text cache data.
+
+ struct ShapedTextDataFallback : public ShapedTextData {
+ struct Span {
+ int start = -1;
+ int end = -1;
+
+ Vector<RID> fonts;
+ int font_size = 0;
+
+ Variant embedded_key;
+
+ String language;
+ Dictionary features;
+ Variant meta;
+ };
+ Vector<Span> spans;
+ };
+
// Common data.
float oversampling = 1.f;
mutable RID_PtrOwner<FontDataFallback> font_owner;
- mutable RID_PtrOwner<ShapedTextData> shaped_owner;
+ mutable RID_PtrOwner<ShapedTextDataFallback> shaped_owner;
+
+ void _realign(ShapedTextDataFallback *p_sd) const;
protected:
static void _bind_methods(){};
- void full_copy(ShapedTextData *p_shaped);
- void invalidate(ShapedTextData *p_shaped);
+ void full_copy(ShapedTextDataFallback *p_shaped);
+ void invalidate(ShapedTextDataFallback *p_shaped);
public:
virtual bool has_feature(Feature p_feature) const override;
@@ -391,10 +412,14 @@ public:
virtual void shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) override;
virtual bool shaped_text_get_preserve_control(RID p_shaped) const override;
- virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") override;
+ virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override;
virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) override;
virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
+ virtual int shaped_get_span_count(RID p_shaped) const override;
+ virtual Variant shaped_get_span_meta(RID p_shaped, int p_index) const override;
+ virtual void shaped_set_span_update_font(RID p_shaped, int p_index, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary()) override;
+
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override;
virtual RID shaped_text_get_parent(RID p_shaped) const override;
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index 9d297fcb93..a9652cbba1 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -337,6 +337,7 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
Ref<Image> img;
img.instantiate();
img->create(w, h, false, Image::FORMAT_RGBA8);
+ texture->create_from_image(img);
} else {
/* tear down the partial theora setup */
diff --git a/modules/visual_script/editor/visual_script_editor.h b/modules/visual_script/editor/visual_script_editor.h
index f1b01aa6dc..b01732b2fd 100644
--- a/modules/visual_script/editor/visual_script_editor.h
+++ b/modules/visual_script/editor/visual_script_editor.h
@@ -173,10 +173,10 @@ class VisualScriptEditor : public ScriptEditorBase {
String member_name;
PortAction port_action;
- int port_action_node;
- int port_action_output;
+ int port_action_node = 0;
+ int port_action_output = 0;
Vector2 port_action_pos;
- int port_action_new_node;
+ int port_action_new_node = 0;
bool saved_pos_dirty = false;
@@ -196,7 +196,7 @@ class VisualScriptEditor : public ScriptEditorBase {
int _create_new_node_from_name(const String &p_text, const Vector2 &p_point);
void _selected_new_virtual_method(const String &p_text, const String &p_category, const bool p_connecting);
- int error_line;
+ int error_line = -1;
void _node_selected(Node *p_node);
void _center_on_node(int p_id);
@@ -267,12 +267,12 @@ class VisualScriptEditor : public ScriptEditorBase {
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
- int editing_id;
- int editing_input;
+ int editing_id = 0;
+ int editing_input = 0;
- bool can_swap;
- int data_disconnect_node;
- int data_disconnect_port;
+ bool can_swap = false;
+ int data_disconnect_node = 0;
+ int data_disconnect_port = 0;
void _default_value_changed();
void _default_value_edited(Node *p_button, int p_id, int p_input_port);
diff --git a/modules/visual_script/editor/visual_script_property_selector.cpp b/modules/visual_script/editor/visual_script_property_selector.cpp
index 1059d126bc..4072dcebe5 100644
--- a/modules/visual_script/editor/visual_script_property_selector.cpp
+++ b/modules/visual_script/editor/visual_script_property_selector.cpp
@@ -379,8 +379,6 @@ void VisualScriptPropertySelector::_bind_methods() {
}
VisualScriptPropertySelector::VisualScriptPropertySelector() {
- virtuals_only = false;
-
vbox = memnew(VBoxContainer);
add_child(vbox);
diff --git a/modules/visual_script/editor/visual_script_property_selector.h b/modules/visual_script/editor/visual_script_property_selector.h
index 3970c4473e..6b5112f1af 100644
--- a/modules/visual_script/editor/visual_script_property_selector.h
+++ b/modules/visual_script/editor/visual_script_property_selector.h
@@ -96,16 +96,16 @@ class VisualScriptPropertySelector : public ConfirmationDialog {
EditorHelpBit *help_bit;
- bool properties;
- bool visual_script_generic;
- bool connecting;
+ bool properties = false;
+ bool visual_script_generic = false;
+ bool connecting = false;
String selected;
Variant::Type type;
String base_type;
String base_script;
ObjectID script;
Object *instance;
- bool virtuals_only;
+ bool virtuals_only = false;
VBoxContainer *vbox;
protected:
diff --git a/modules/visual_script/icons/VisualScript.svg b/modules/visual_script/icons/VisualScript.svg
index 2352ba5d87..bc698247c9 100644
--- a/modules/visual_script/icons/VisualScript.svg
+++ b/modules/visual_script/icons/VisualScript.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><ellipse cx="3" cy="1039.4" fill="#6e6e6e"/><path d="m7 1-.56445 2.2578a5 5 0 0 0 -.68945.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941a5 5 0 0 0 -.28516.68555l-2.2539.5625v2h5.2715a2 2 0 0 1 -.27148-1 2 2 0 0 1 2-2 2 2 0 0 1 2 2 2 2 0 0 1 -.26953 1h5.2695v-2l-2.2578-.56445a5 5 0 0 0 -.2793-.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953a5 5 0 0 0 -.68555-.28516l-.5625-2.2539h-2zm-4 9v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4zm8 0a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v2h2a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/></g></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -1036.4)"><ellipse cx="3" cy="1039.4" fill="#e0e0e0"/><path d="m7 1-.56445 2.2578a5 5 0 0 0 -.68945.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941a5 5 0 0 0 -.28516.68555l-2.2539.5625v2h5.2715a2 2 0 0 1 -.27148-1 2 2 0 0 1 2-2 2 2 0 0 1 2 2 2 2 0 0 1 -.26953 1h5.2695v-2l-2.2578-.56445a5 5 0 0 0 -.2793-.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953a5 5 0 0 0 -.68555-.28516l-.5625-2.2539h-2zm-4 9v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4zm8 0a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v2h2a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2z" fill="#e0e0e0" transform="translate(0 1036.4)"/></g></svg>
diff --git a/modules/visual_script/icons/VisualScriptInternal.svg b/modules/visual_script/icons/VisualScriptInternal.svg
index ea83047a29..8ab39ad929 100644
--- a/modules/visual_script/icons/VisualScriptInternal.svg
+++ b/modules/visual_script/icons/VisualScriptInternal.svg
@@ -1 +1 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="3" cy="3.000024" fill="#6e6e6e" r="0"/><path d="m11 10a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v2h2a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2z" fill="#e0e0e0"/><path d="m3 10v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4z" fill="#e0e0e0"/><path d="m7 1-.56445 2.2578a5 5 0 0 0 -.68945.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941a5 5 0 0 0 -.28516.68555l-2.2539.5625v2h5.2715a2 2 0 0 1 -.27148-1 2 2 0 0 1 2-2 2 2 0 0 1 2 2 2 2 0 0 1 -.26953 1h5.2695v-2l-2.2578-.56445a5 5 0 0 0 -.2793-.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953a5 5 0 0 0 -.68555-.28516l-.5625-2.2539h-2z" fill="none" stroke="#e0e0e0"/></svg>
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><circle cx="3" cy="3.000024" fill="#e0e0e0" r="0"/><path d="m11 10a2 2 0 0 0 -1.7324 1 2 2 0 0 0 0 2 2 2 0 0 0 1.7324 1h-2v2h2a2 2 0 0 0 1.7324-1 2 2 0 0 0 0-2 2 2 0 0 0 -1.7324-1h2v-2z" fill="#e0e0e0"/><path d="m3 10v6h2a3 3 0 0 0 3-3v-3h-2v3a1 1 0 0 1 -1 1v-4z" fill="#e0e0e0"/><path d="m7 1-.56445 2.2578a5 5 0 0 0 -.68945.2793l-1.9883-1.1934-1.4141 1.4141 1.1953 1.9941a5 5 0 0 0 -.28516.68555l-2.2539.5625v2h5.2715a2 2 0 0 1 -.27148-1 2 2 0 0 1 2-2 2 2 0 0 1 2 2 2 2 0 0 1 -.26953 1h5.2695v-2l-2.2578-.56445a5 5 0 0 0 -.2793-.6875l1.1934-1.9902-1.4141-1.4141-1.9941 1.1953a5 5 0 0 0 -.68555-.28516l-.5625-2.2539h-2z" fill="none" stroke="#e0e0e0"/></svg>
diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp
index 2abbd19e12..17a3566ed2 100644
--- a/modules/visual_script/visual_script_expression.cpp
+++ b/modules/visual_script/visual_script_expression.cpp
@@ -328,6 +328,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
};
case '"': {
String str;
+ char32_t prev = 0;
while (true) {
char32_t ch = GET_CHAR();
@@ -364,9 +365,11 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
case 'r':
res = 13;
break;
+ case 'U':
case 'u': {
- // hex number
- for (int j = 0; j < 4; j++) {
+ // Hexadecimal sequence.
+ int hex_len = (next == 'U') ? 6 : 4;
+ for (int j = 0; j < hex_len; j++) {
char32_t c = GET_CHAR();
if (c == 0) {
@@ -403,12 +406,46 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
} break;
}
+ // Parse UTF-16 pair.
+ if ((res & 0xfffffc00) == 0xd800) {
+ if (prev == 0) {
+ prev = res;
+ continue;
+ } else {
+ _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ }
+ } else if ((res & 0xfffffc00) == 0xdc00) {
+ if (prev == 0) {
+ _set_error("Invalid UTF-16 sequence in string, unpaired trail surrogate");
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ } else {
+ res = (prev << 10UL) + res - ((0xd800 << 10UL) + 0xdc00 - 0x10000);
+ prev = 0;
+ }
+ }
+ if (prev != 0) {
+ _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ }
str += res;
-
} else {
+ if (prev != 0) {
+ _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ }
str += ch;
}
}
+ if (prev != 0) {
+ _set_error("Invalid UTF-16 sequence in string, unpaired lead surrogate");
+ r_token.type = TK_ERROR;
+ return ERR_PARSE_ERROR;
+ }
r_token.type = TK_CONSTANT;
r_token.value = str;
diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp
index cc18d48dd8..ef6c1ecdb9 100644
--- a/modules/visual_script/visual_script_func_nodes.cpp
+++ b/modules/visual_script/visual_script_func_nodes.cpp
@@ -912,7 +912,7 @@ int VisualScriptPropertySet::get_output_sequence_port_count() const {
}
bool VisualScriptPropertySet::has_input_sequence_port() const {
- return 1;
+ return true;
}
Node *VisualScriptPropertySet::_get_base_node() const {
diff --git a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml
index 2f2c2c379d..416a674435 100644
--- a/modules/webrtc/doc_classes/WebRTCPeerConnection.xml
+++ b/modules/webrtc/doc_classes/WebRTCPeerConnection.xml
@@ -117,7 +117,7 @@
</methods>
<signals>
<signal name="data_channel_received">
- <argument index="0" name="channel" type="Object" />
+ <argument index="0" name="channel" type="WebRTCDataChannel" />
<description>
Emitted when a new in-band channel is received, i.e. when the channel was created with [code]negotiated: false[/code] (default).
The object will be an instance of [WebRTCDataChannel]. You must keep a reference of it or it will be closed automatically. See [method create_data_channel].
diff --git a/modules/webrtc/webrtc_peer_connection.cpp b/modules/webrtc/webrtc_peer_connection.cpp
index 96cf518c06..7fdf26d3cd 100644
--- a/modules/webrtc/webrtc_peer_connection.cpp
+++ b/modules/webrtc/webrtc_peer_connection.cpp
@@ -69,7 +69,7 @@ void WebRTCPeerConnection::_bind_methods() {
ADD_SIGNAL(MethodInfo("session_description_created", PropertyInfo(Variant::STRING, "type"), PropertyInfo(Variant::STRING, "sdp")));
ADD_SIGNAL(MethodInfo("ice_candidate_created", PropertyInfo(Variant::STRING, "media"), PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::STRING, "name")));
- ADD_SIGNAL(MethodInfo("data_channel_received", PropertyInfo(Variant::OBJECT, "channel")));
+ ADD_SIGNAL(MethodInfo("data_channel_received", PropertyInfo(Variant::OBJECT, "channel", PROPERTY_HINT_RESOURCE_TYPE, "WebRTCDataChannel")));
BIND_ENUM_CONSTANT(STATE_NEW);
BIND_ENUM_CONSTANT(STATE_CONNECTING);
diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp
index 8eb0d8ff90..86b857f72c 100644
--- a/modules/webxr/webxr_interface_js.cpp
+++ b/modules/webxr/webxr_interface_js.cpp
@@ -385,7 +385,7 @@ CameraMatrix WebXRInterfaceJS::get_projection_for_view(uint32_t p_view, double p
return eye;
}
-Vector<BlitToScreen> WebXRInterfaceJS::commit_views(RID p_render_target, const Rect2 &p_screen_rect) {
+Vector<BlitToScreen> WebXRInterfaceJS::post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) {
Vector<BlitToScreen> blit_to_screen;
if (!initialized) {
diff --git a/modules/webxr/webxr_interface_js.h b/modules/webxr/webxr_interface_js.h
index 8eddfbe484..31858194f6 100644
--- a/modules/webxr/webxr_interface_js.h
+++ b/modules/webxr/webxr_interface_js.h
@@ -88,7 +88,7 @@ public:
virtual Transform3D get_camera_transform() override;
virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override;
virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override;
- virtual Vector<BlitToScreen> commit_views(RID p_render_target, const Rect2 &p_screen_rect) override;
+ virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override;
virtual void process() override;
diff --git a/platform/android/SCsub b/platform/android/SCsub
index ecc72019e5..d031d14499 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -18,6 +18,7 @@ android_files = [
"jni_utils.cpp",
"android_keys_utils.cpp",
"display_server_android.cpp",
+ "plugin/godot_plugin_jni.cpp",
"vulkan/vulkan_context_android.cpp",
]
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index 15f61db27c..3d0dabc56e 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -253,6 +253,24 @@ DisplayServer::WindowID DisplayServerAndroid::get_window_at_screen_position(cons
return MAIN_WINDOW_ID;
}
+int64_t DisplayServerAndroid::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+ ERR_FAIL_COND_V(p_window != MAIN_WINDOW_ID, 0);
+ switch (p_handle_type) {
+ case DISPLAY_HANDLE: {
+ return 0; // Not supported.
+ }
+ case WINDOW_HANDLE: {
+ return (int64_t)((OS_Android *)OS::get_singleton())->get_godot_java()->get_activity();
+ }
+ case WINDOW_VIEW: {
+ return 0; // Not supported.
+ }
+ default: {
+ return 0;
+ }
+ }
+}
+
void DisplayServerAndroid::window_attach_instance_id(ObjectID p_instance, DisplayServer::WindowID p_window) {
window_attached_instance_id = p_instance;
}
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
index 6aadc7e1a9..e52e07bf1a 100644
--- a/platform/android/display_server_android.h
+++ b/platform/android/display_server_android.h
@@ -124,6 +124,9 @@ public:
virtual Vector<WindowID> get_window_list() const override;
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override;
+
+ virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override;
+
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) override;
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index 78155fbef3..61d2f897ef 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -975,20 +975,6 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
}
}
- if (tname == "meta-data" && attrname == "name" && value == "xr_mode_metadata_name") {
- // Update the meta-data 'android:name' attribute based on the selected XR mode.
- if (xr_mode_index == XR_MODE_OPENXR) {
- string_table.write[attr_value] = "com.samsung.android.vr.application.mode";
- }
- }
-
- if (tname == "meta-data" && attrname == "value" && value == "xr_mode_metadata_value") {
- // Update the meta-data 'android:value' attribute based on the selected XR mode.
- if (xr_mode_index == XR_MODE_OPENXR) {
- string_table.write[attr_value] = "vr_only";
- }
- }
-
if (tname == "meta-data" && attrname == "name" && value == "xr_hand_tracking_metadata_name") {
if (xr_mode_index == XR_MODE_OPENXR && hand_tracking_index > XR_HAND_TRACKING_NONE) {
string_table.write[attr_value] = "com.oculus.handtracking.frequency";
diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp
index 287b669fd1..babd8173d0 100644
--- a/platform/android/export/gradle_export_util.cpp
+++ b/platform/android/export/gradle_export_util.cpp
@@ -278,7 +278,6 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_
" android:requestLegacyExternalStorage=\"%s\"\n"
" tools:replace=\"android:allowBackup,android:isGame,android:hasFragileUserData,android:requestLegacyExternalStorage\"\n"
" tools:ignore=\"GoogleAppIndexingWarning\">\n\n"
- " <meta-data tools:node=\"remove\" android:name=\"xr_mode_metadata_name\" />\n"
" <meta-data tools:node=\"remove\" android:name=\"xr_hand_tracking_metadata_name\" />\n",
bool_to_string(p_preset->get("user_data_backup/allow")),
bool_to_string(p_preset->get("package/classify_as_game")),
@@ -286,8 +285,6 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_
bool_to_string(p_has_storage_permission));
if (uses_xr) {
- manifest_application_text += " <meta-data tools:node=\"replace\" android:name=\"com.samsung.android.vr.application.mode\" android:value=\"vr_only\" />\n";
-
bool hand_tracking_enabled = (int)(p_preset->get("xr_features/hand_tracking")) > XR_HAND_TRACKING_NONE;
if (hand_tracking_enabled) {
int hand_tracking_frequency_index = p_preset->get("xr_features/hand_tracking_frequency");
@@ -296,6 +293,8 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_
" <meta-data tools:node=\"replace\" android:name=\"com.oculus.handtracking.frequency\" android:value=\"%s\" />\n",
hand_tracking_frequency);
}
+ } else {
+ manifest_application_text += " <meta-data tools:node=\"remove\" android:name=\"com.oculus.supportedDevices\" />\n";
}
manifest_application_text += _get_activity_tag(p_preset);
manifest_application_text += " </application>\n";
diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml
index 3924aacccd..4c4501729d 100644
--- a/platform/android/java/app/AndroidManifest.xml
+++ b/platform/android/java/app/AndroidManifest.xml
@@ -33,11 +33,6 @@
<!-- The following metadata values are replaced when Godot exports, modifying them here has no effect. -->
<!-- Do these changes in the export preset. Adding new ones is fine. -->
- <!-- XR mode metadata. This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. -->
- <meta-data
- android:name="xr_mode_metadata_name"
- android:value="xr_mode_metadata_value" />
-
<!-- XR hand tracking metadata -->
<!-- This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. -->
<!-- Removed at export time if the xr mode is not VR or hand tracking is disabled. -->
@@ -45,6 +40,12 @@
android:name="xr_hand_tracking_metadata_name"
android:value="xr_hand_tracking_metadata_value"/>
+ <!-- Supported Meta devices -->
+ <!-- This is removed by the exporter if the xr mode is not VR. -->
+ <meta-data
+ android:name="com.oculus.supportedDevices"
+ android:value="all" />
+
<activity
android:name=".GodotApp"
android:label="@string/godot_project_name_string"
diff --git a/platform/android/plugin/godot_plugin_jni.cpp b/platform/android/plugin/godot_plugin_jni.cpp
index 2207eec18d..48aeb3d070 100644
--- a/platform/android/plugin/godot_plugin_jni.cpp
+++ b/platform/android/plugin/godot_plugin_jni.cpp
@@ -126,7 +126,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitS
env->DeleteLocalRef(j_param);
};
- singleton->emit_signal(SNAME(signal_name), args, count);
+ singleton->emit_signal(StringName(signal_name), args, count);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterGDNativeLibraries(JNIEnv *env, jclass clazz, jobjectArray gdnlib_paths) {
diff --git a/platform/iphone/display_server_iphone.h b/platform/iphone/display_server_iphone.h
index de04bc88e3..6434483641 100644
--- a/platform/iphone/display_server_iphone.h
+++ b/platform/iphone/display_server_iphone.h
@@ -135,6 +135,8 @@ public:
virtual WindowID
get_window_at_screen_position(const Point2i &p_position) const override;
+ virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override;
+
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
diff --git a/platform/iphone/display_server_iphone.mm b/platform/iphone/display_server_iphone.mm
index 77e1a6078c..48bda89fc3 100644
--- a/platform/iphone/display_server_iphone.mm
+++ b/platform/iphone/display_server_iphone.mm
@@ -407,6 +407,24 @@ DisplayServer::WindowID DisplayServerIPhone::get_window_at_screen_position(const
return MAIN_WINDOW_ID;
}
+int64_t DisplayServerIPhone::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+ ERR_FAIL_COND_V(p_window != MAIN_WINDOW_ID, 0);
+ switch (p_handle_type) {
+ case DISPLAY_HANDLE: {
+ return 0; // Not supported.
+ }
+ case WINDOW_HANDLE: {
+ return (int64_t)AppDelegate.viewController;
+ }
+ case WINDOW_VIEW: {
+ return (int64_t)AppDelegate.viewController.godotView;
+ }
+ default: {
+ return 0;
+ }
+ }
+}
+
void DisplayServerIPhone::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
window_attached_instance_id = p_instance;
}
diff --git a/platform/iphone/export/export_plugin.cpp b/platform/iphone/export/export_plugin.cpp
index ea17f1ac61..fe00b1a3cd 100644
--- a/platform/iphone/export/export_plugin.cpp
+++ b/platform/iphone/export/export_plugin.cpp
@@ -83,7 +83,7 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_store_team_id"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/provisioning_profile_uuid_debug"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/code_sign_identity_debug", PROPERTY_HINT_PLACEHOLDER_TEXT, "iPhone Developer"), "iPhone Developer"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/code_sign_identity_debug", PROPERTY_HINT_PLACEHOLDER_TEXT, "iPhone Developer"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_method_debug", PROPERTY_HINT_ENUM, "App Store,Development,Ad-Hoc,Enterprise"), 1));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/provisioning_profile_uuid_release"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/code_sign_identity_release", PROPERTY_HINT_PLACEHOLDER_TEXT, "iPhone Distribution"), ""));
@@ -178,6 +178,10 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
"scaleAspectFill",
"scaleToFill"
};
+ String dbg_sign_id = p_preset->get("application/code_sign_identity_debug").operator String().is_empty() ? "iPhone Developer" : p_preset->get("application/code_sign_identity_debug");
+ String rel_sign_id = p_preset->get("application/code_sign_identity_release").operator String().is_empty() ? "iPhone Distribution" : p_preset->get("application/code_sign_identity_release");
+ bool dbg_manual = !p_preset->get("application/provisioning_profile_uuid_debug").operator String().is_empty() || (dbg_sign_id != "iPhone Developer");
+ bool rel_manual = !p_preset->get("application/provisioning_profile_uuid_release").operator String().is_empty() || (rel_sign_id != "iPhone Distribution");
String str;
String strnew;
str.parse_utf8((const char *)pfile.ptr(), pfile.size());
@@ -218,13 +222,25 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_
strnew += lines[i].replace("$provisioning_profile_uuid_release", p_preset->get("application/provisioning_profile_uuid_release")) + "\n";
} else if (lines[i].find("$provisioning_profile_uuid_debug") != -1) {
strnew += lines[i].replace("$provisioning_profile_uuid_debug", p_preset->get("application/provisioning_profile_uuid_debug")) + "\n";
+ } else if (lines[i].find("$code_sign_style_debug") != -1) {
+ if (dbg_manual) {
+ strnew += lines[i].replace("$code_sign_style_debug", "Manual") + "\n";
+ } else {
+ strnew += lines[i].replace("$code_sign_style_debug", "Automatic") + "\n";
+ }
+ } else if (lines[i].find("$code_sign_style_release") != -1) {
+ if (rel_manual) {
+ strnew += lines[i].replace("$code_sign_style_release", "Manual") + "\n";
+ } else {
+ strnew += lines[i].replace("$code_sign_style_release", "Automatic") + "\n";
+ }
} else if (lines[i].find("$provisioning_profile_uuid") != -1) {
String uuid = p_debug ? p_preset->get("application/provisioning_profile_uuid_debug") : p_preset->get("application/provisioning_profile_uuid_release");
strnew += lines[i].replace("$provisioning_profile_uuid", uuid) + "\n";
} else if (lines[i].find("$code_sign_identity_debug") != -1) {
- strnew += lines[i].replace("$code_sign_identity_debug", p_preset->get("application/code_sign_identity_debug")) + "\n";
+ strnew += lines[i].replace("$code_sign_identity_debug", dbg_sign_id) + "\n";
} else if (lines[i].find("$code_sign_identity_release") != -1) {
- strnew += lines[i].replace("$code_sign_identity_release", p_preset->get("application/code_sign_identity_release")) + "\n";
+ strnew += lines[i].replace("$code_sign_identity_release", rel_sign_id) + "\n";
} else if (lines[i].find("$additional_plist_content") != -1) {
strnew += lines[i].replace("$additional_plist_content", p_config.plist_content) + "\n";
} else if (lines[i].find("$godot_archs") != -1) {
@@ -770,10 +786,18 @@ Error EditorExportPlatformIOS::_codesign(String p_file, void *p_userdata) {
if (p_file.ends_with(".dylib")) {
CodesignData *data = (CodesignData *)p_userdata;
print_line(String("Signing ") + p_file);
+
+ String sign_id;
+ if (data->debug) {
+ sign_id = data->preset->get("application/code_sign_identity_debug").operator String().is_empty() ? "iPhone Developer" : data->preset->get("application/code_sign_identity_debug");
+ } else {
+ sign_id = data->preset->get("application/code_sign_identity_release").operator String().is_empty() ? "iPhone Distribution" : data->preset->get("application/code_sign_identity_release");
+ }
+
List<String> codesign_args;
codesign_args.push_back("-f");
codesign_args.push_back("-s");
- codesign_args.push_back(data->preset->get(data->debug ? "application/code_sign_identity_debug" : "application/code_sign_identity_release"));
+ codesign_args.push_back(sign_id);
codesign_args.push_back(p_file);
return OS::get_singleton()->execute("codesign", codesign_args);
}
@@ -1680,6 +1704,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
archive_args.push_back("-destination");
archive_args.push_back("generic/platform=iOS");
archive_args.push_back("archive");
+ archive_args.push_back("-allowProvisioningUpdates");
archive_args.push_back("-archivePath");
archive_args.push_back(archive_path);
String archive_str;
diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp
index 45aa68ce7c..c946302862 100644
--- a/platform/javascript/http_client_javascript.cpp
+++ b/platform/javascript/http_client_javascript.cpp
@@ -87,6 +87,11 @@ Error HTTPClientJavaScript::request(Method p_method, const String &p_url, const
ERR_FAIL_COND_V(port < 0, ERR_UNCONFIGURED);
ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER);
+ Error err = verify_headers(p_headers);
+ if (err) {
+ return err;
+ }
+
String url = (use_tls ? "https://" : "http://") + host + ":" + itos(port) + p_url;
Vector<CharString> keeper;
Vector<const char *> c_strings;
diff --git a/platform/javascript/js/engine/config.js b/platform/javascript/js/engine/config.js
index ba61b14eb7..5628ddbab5 100644
--- a/platform/javascript/js/engine/config.js
+++ b/platform/javascript/js/engine/config.js
@@ -225,33 +225,34 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
*/
Config.prototype.update = function (opts) {
const config = opts || {};
- function parse(key, def) {
+ const me = this;
+ function parse(key) {
if (typeof (config[key]) === 'undefined') {
- return def;
+ return me[key];
}
return config[key];
}
// Module config
- this.unloadAfterInit = parse('unloadAfterInit', this.unloadAfterInit);
- this.onPrintError = parse('onPrintError', this.onPrintError);
- this.onPrint = parse('onPrint', this.onPrint);
- this.onProgress = parse('onProgress', this.onProgress);
+ this.unloadAfterInit = parse('unloadAfterInit');
+ this.onPrintError = parse('onPrintError');
+ this.onPrint = parse('onPrint');
+ this.onProgress = parse('onProgress');
// Godot config
- this.canvas = parse('canvas', this.canvas);
- this.executable = parse('executable', this.executable);
- this.mainPack = parse('mainPack', this.mainPack);
- this.locale = parse('locale', this.locale);
- this.canvasResizePolicy = parse('canvasResizePolicy', this.canvasResizePolicy);
- this.persistentPaths = parse('persistentPaths', this.persistentPaths);
- this.persistentDrops = parse('persistentDrops', this.persistentDrops);
- this.experimentalVK = parse('experimentalVK', this.experimentalVK);
- this.focusCanvas = parse('focusCanvas', this.focusCanvas);
- this.gdnativeLibs = parse('gdnativeLibs', this.gdnativeLibs);
- this.fileSizes = parse('fileSizes', this.fileSizes);
- this.args = parse('args', this.args);
- this.onExecute = parse('onExecute', this.onExecute);
- this.onExit = parse('onExit', this.onExit);
+ this.canvas = parse('canvas');
+ this.executable = parse('executable');
+ this.mainPack = parse('mainPack');
+ this.locale = parse('locale');
+ this.canvasResizePolicy = parse('canvasResizePolicy');
+ this.persistentPaths = parse('persistentPaths');
+ this.persistentDrops = parse('persistentDrops');
+ this.experimentalVK = parse('experimentalVK');
+ this.focusCanvas = parse('focusCanvas');
+ this.gdnativeLibs = parse('gdnativeLibs');
+ this.fileSizes = parse('fileSizes');
+ this.args = parse('args');
+ this.onExecute = parse('onExecute');
+ this.onExit = parse('onExit');
};
/**
diff --git a/platform/javascript/js/libs/library_godot_input.js b/platform/javascript/js/libs/library_godot_input.js
index 7a4d0d8126..1e64c260f8 100644
--- a/platform/javascript/js/libs/library_godot_input.js
+++ b/platform/javascript/js/libs/library_godot_input.js
@@ -87,7 +87,7 @@ const GodotInputGamepads = {
},
init: function (onchange) {
- GodotEventListeners.samples = [];
+ GodotInputGamepads.samples = [];
function add(pad) {
const guid = GodotInputGamepads.get_guid(pad);
const c_id = GodotRuntime.allocString(pad.id);
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 0ce627ca4f..198eacd1f3 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -323,20 +323,21 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) {
//flush pending motion events
_flush_mouse_motion();
- WindowData &main_window = windows[MAIN_WINDOW_ID];
+ WindowID window_id = windows.has(last_focused_window) ? last_focused_window : MAIN_WINDOW_ID;
+ WindowData &window = windows[window_id];
if (XGrabPointer(
- x11_display, main_window.x11_window, True,
+ x11_display, window.x11_window, True,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
- GrabModeAsync, GrabModeAsync, windows[MAIN_WINDOW_ID].x11_window, None, CurrentTime) != GrabSuccess) {
+ GrabModeAsync, GrabModeAsync, window.x11_window, None, CurrentTime) != GrabSuccess) {
ERR_PRINT("NO GRAB");
}
if (mouse_mode == MOUSE_MODE_CAPTURED) {
- center.x = main_window.size.width / 2;
- center.y = main_window.size.height / 2;
+ center.x = window.size.width / 2;
+ center.y = window.size.height / 2;
- XWarpPointer(x11_display, None, main_window.x11_window,
+ XWarpPointer(x11_display, None, window.x11_window,
0, 0, 0, 0, (int)center.x, (int)center.y);
Input::get_singleton()->set_mouse_position(center);
@@ -358,7 +359,8 @@ void DisplayServerX11::mouse_warp_to_position(const Point2i &p_to) {
if (mouse_mode == MOUSE_MODE_CAPTURED) {
last_mouse_pos = p_to;
} else {
- XWarpPointer(x11_display, None, windows[MAIN_WINDOW_ID].x11_window,
+ WindowID window_id = windows.has(last_focused_window) ? last_focused_window : MAIN_WINDOW_ID;
+ XWarpPointer(x11_display, None, windows[window_id].x11_window,
0, 0, 0, 0, (int)p_to.x, (int)p_to.y);
}
}
@@ -1154,6 +1156,24 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
windows.erase(p_id);
}
+int64_t DisplayServerX11::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+ ERR_FAIL_COND_V(!windows.has(p_window), 0);
+ switch (p_handle_type) {
+ case DISPLAY_HANDLE: {
+ return (int64_t)x11_display;
+ }
+ case WINDOW_HANDLE: {
+ return (int64_t)windows[p_window].x11_window;
+ }
+ case WINDOW_VIEW: {
+ return 0; // Not supported.
+ }
+ default: {
+ return 0;
+ }
+ }
+}
+
void DisplayServerX11::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
@@ -1314,8 +1334,9 @@ int DisplayServerX11::window_get_current_screen(WindowID p_window) const {
void DisplayServerX11::gl_window_make_current(DisplayServer::WindowID p_window_id) {
#if defined(GLES3_ENABLED)
- if (gl_manager)
+ if (gl_manager) {
gl_manager->window_make_current(p_window_id);
+ }
#endif
}
@@ -3334,7 +3355,7 @@ void DisplayServerX11::process_events() {
DEBUG_LOG_X11("[%u] FocusIn window=%lu (%u), mode='%u' \n", frame, event.xfocus.window, window_id, event.xfocus.mode);
WindowData &wd = windows[window_id];
-
+ last_focused_window = window_id;
wd.focused = true;
if (wd.xic) {
@@ -3534,9 +3555,9 @@ void DisplayServerX11::process_events() {
// The X11 API requires filtering one-by-one through the motion
// notify events, in order to figure out which event is the one
// generated by warping the mouse pointer.
-
+ WindowID focused_window_id = windows.has(last_focused_window) ? last_focused_window : MAIN_WINDOW_ID;
while (true) {
- if (mouse_mode == MOUSE_MODE_CAPTURED && event.xmotion.x == windows[MAIN_WINDOW_ID].size.width / 2 && event.xmotion.y == windows[MAIN_WINDOW_ID].size.height / 2) {
+ if (mouse_mode == MOUSE_MODE_CAPTURED && event.xmotion.x == windows[focused_window_id].size.width / 2 && event.xmotion.y == windows[focused_window_id].size.height / 2) {
//this is likely the warp event since it was warped here
center = Vector2(event.xmotion.x, event.xmotion.y);
break;
@@ -3611,9 +3632,8 @@ void DisplayServerX11::process_events() {
// Reset to prevent lingering motion
xi.relative_motion.x = 0;
xi.relative_motion.y = 0;
-
if (mouse_mode == MOUSE_MODE_CAPTURED) {
- pos = Point2i(windows[MAIN_WINDOW_ID].size.width / 2, windows[MAIN_WINDOW_ID].size.height / 2);
+ pos = Point2i(windows[focused_window_id].size.width / 2, windows[focused_window_id].size.height / 2);
}
Ref<InputEventMouseMotion> mm;
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index 8929f528d6..c17e120db5 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -143,7 +143,7 @@ class DisplayServerX11 : public DisplayServer {
bool borderless = false;
bool resize_disabled = false;
Vector2i last_position_before_fs;
- bool focused = false;
+ bool focused = true;
bool minimized = false;
unsigned int focus_order = 0;
@@ -151,6 +151,8 @@ class DisplayServerX11 : public DisplayServer {
Map<WindowID, WindowData> windows;
+ WindowID last_focused_window = INVALID_WINDOW_ID;
+
WindowID window_id_counter = MAIN_WINDOW_ID;
WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect);
@@ -316,6 +318,8 @@ public:
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override;
+ virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override;
+
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
diff --git a/platform/linuxbsd/gl_manager_x11.cpp b/platform/linuxbsd/gl_manager_x11.cpp
index 1721d0e0b3..d3fb1d6705 100644
--- a/platform/linuxbsd/gl_manager_x11.cpp
+++ b/platform/linuxbsd/gl_manager_x11.cpp
@@ -68,8 +68,9 @@ static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) {
int GLManager_X11::_find_or_create_display(Display *p_x11_display) {
for (unsigned int n = 0; n < _displays.size(); n++) {
const GLDisplay &d = _displays[n];
- if (d.x11_display == p_x11_display)
+ if (d.x11_display == p_x11_display) {
return n;
+ }
}
// create
@@ -82,8 +83,7 @@ int GLManager_X11::_find_or_create_display(Display *p_x11_display) {
GLDisplay &d = _displays[new_display_id];
d.context = memnew(GLManager_X11_Private);
- ;
- d.context->glx_context = 0;
+ d.context->glx_context = nullptr;
//Error err = _create_context(d);
_create_context(d);
@@ -124,7 +124,7 @@ Error GLManager_X11::_create_context(GLDisplay &gl_display) {
};
int fbcount;
- GLXFBConfig fbconfig = 0;
+ GLXFBConfig fbconfig = nullptr;
XVisualInfo *vi = nullptr;
gl_display.x_swa.event_mask = StructureNotifyMask;
@@ -137,8 +137,9 @@ Error GLManager_X11::_create_context(GLDisplay &gl_display) {
for (int i = 0; i < fbcount; i++) {
vi = (XVisualInfo *)glXGetVisualFromFBConfig(x11_display, fbc[i]);
- if (!vi)
+ if (!vi) {
continue;
+ }
XRenderPictFormat *pict_format = XRenderFindVisualFormat(x11_display, vi->visual);
if (!pict_format) {
@@ -262,22 +263,26 @@ void GLManager_X11::window_destroy(DisplayServer::WindowID p_window_id) {
}
void GLManager_X11::release_current() {
- if (!_current_window)
+ if (!_current_window) {
return;
+ }
glXMakeCurrent(_x_windisp.x11_display, None, nullptr);
}
void GLManager_X11::window_make_current(DisplayServer::WindowID p_window_id) {
- if (p_window_id == -1)
+ if (p_window_id == -1) {
return;
+ }
GLWindow &win = _windows[p_window_id];
- if (!win.in_use)
+ if (!win.in_use) {
return;
+ }
// noop
- if (&win == _current_window)
+ if (&win == _current_window) {
return;
+ }
const GLDisplay &disp = get_display(win.gldisplay_id);
@@ -287,8 +292,9 @@ void GLManager_X11::window_make_current(DisplayServer::WindowID p_window_id) {
}
void GLManager_X11::make_current() {
- if (!_current_window)
+ if (!_current_window) {
return;
+ }
if (!_current_window->in_use) {
WARN_PRINT("current window not in use!");
return;
@@ -301,8 +307,9 @@ void GLManager_X11::swap_buffers() {
// NO NEED TO CALL SWAP BUFFERS for each window...
// see https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glXSwapBuffers.xml
- if (!_current_window)
+ if (!_current_window) {
return;
+ }
if (!_current_window->in_use) {
WARN_PRINT("current window not in use!");
return;
@@ -335,19 +342,23 @@ void GLManager_X11::set_use_vsync(bool p_use) {
}
// we need an active window to get a display to set the vsync
- if (!_current_window)
+ if (!_current_window) {
return;
+ }
const GLDisplay &disp = get_current_display();
if (!setup) {
setup = true;
String extensions = glXQueryExtensionsString(disp.x11_display, DefaultScreen(disp.x11_display));
- if (extensions.find("GLX_EXT_swap_control") != -1)
+ if (extensions.find("GLX_EXT_swap_control") != -1) {
glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalEXT");
- if (extensions.find("GLX_MESA_swap_control") != -1)
+ }
+ if (extensions.find("GLX_MESA_swap_control") != -1) {
glXSwapIntervalMESA = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalMESA");
- if (extensions.find("GLX_SGI_swap_control") != -1)
+ }
+ if (extensions.find("GLX_SGI_swap_control") != -1) {
glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddressARB((const GLubyte *)"glXSwapIntervalSGI");
+ }
}
int val = p_use ? 1 : 0;
if (glXSwapIntervalMESA) {
@@ -357,8 +368,9 @@ void GLManager_X11::set_use_vsync(bool p_use) {
} else if (glXSwapIntervalEXT) {
GLXDrawable drawable = glXGetCurrentDrawable();
glXSwapIntervalEXT(disp.x11_display, drawable, val);
- } else
+ } else {
return;
+ }
use_vsync = p_use;
}
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp
index b5f127bb16..e95a865636 100644
--- a/platform/linuxbsd/os_linuxbsd.cpp
+++ b/platform/linuxbsd/os_linuxbsd.cpp
@@ -448,7 +448,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
// Create needed directories for decided trash can location.
{
- DirAccess *dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ DirAccessRef dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
Error err = dir_access->make_dir_recursive(trash_path);
// Issue an error if trash can is not created properly.
@@ -457,7 +457,6 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
ERR_FAIL_COND_V_MSG(err != OK, err, "Could not create the trash path \"" + trash_path + "\"/files");
err = dir_access->make_dir_recursive(trash_path + "/info");
ERR_FAIL_COND_V_MSG(err != OK, err, "Could not create the trash path \"" + trash_path + "\"/info");
- memdelete(dir_access);
}
// The trash can is successfully created, now we check that we don't exceed our file name length limit.
@@ -497,16 +496,15 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
String trash_info = "[Trash Info]\nPath=" + p_path.uri_encode() + "\nDeletionDate=" + timestamp + "\n";
{
Error err;
- FileAccess *file = FileAccess::open(trash_path + "/info/" + file_name + ".trashinfo", FileAccess::WRITE, &err);
+ FileAccessRef file = FileAccess::open(trash_path + "/info/" + file_name + ".trashinfo", FileAccess::WRITE, &err);
ERR_FAIL_COND_V_MSG(err != OK, err, "Can't create trashinfo file:" + trash_path + "/info/" + file_name + ".trashinfo");
file->store_string(trash_info);
file->close();
// Rename our resource before moving it to the trash can.
- DirAccess *dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ DirAccessRef dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
err = dir_access->rename(p_path, p_path.get_base_dir() + "/" + file_name);
ERR_FAIL_COND_V_MSG(err != OK, err, "Can't rename file \"" + p_path + "\"");
- memdelete(dir_access);
}
// Move the given resource to the trash can.
diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h
index d609a84e50..719a45c2a8 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/osx/display_server_osx.h
@@ -145,6 +145,8 @@ public:
Map<WindowID, WindowData> windows;
+ WindowID last_focused_window = INVALID_WINDOW_ID;
+
WindowID window_id_counter = MAIN_WINDOW_ID;
WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, const Rect2i &p_rect);
@@ -282,6 +284,8 @@ public:
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override;
+ virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override;
+
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
virtual void gl_window_make_current(DisplayServer::WindowID p_window_id) override;
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 1340aad9b2..f7add5b688 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -321,6 +321,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
DS_OSX->window_focused = true;
+ DS_OSX->last_focused_window = window_id;
DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN);
}
@@ -355,6 +356,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
DS_OSX->window_focused = true;
+ DS_OSX->last_focused_window = window_id;
DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN);
}
@@ -1913,7 +1915,8 @@ void DisplayServerOSX::mouse_set_mode(MouseMode p_mode) {
return;
}
- WindowData &wd = windows[MAIN_WINDOW_ID];
+ WindowID window_id = windows.has(last_focused_window) ? last_focused_window : MAIN_WINDOW_ID;
+ WindowData &wd = windows[window_id];
if (p_mode == MOUSE_MODE_CAPTURED) {
// Apple Docs state that the display parameter is not used.
// "This parameter is not used. By default, you may pass kCGDirectMainDisplay."
@@ -1972,7 +1975,8 @@ void DisplayServerOSX::mouse_warp_to_position(const Point2i &p_to) {
if (mouse_mode == MOUSE_MODE_CAPTURED) {
last_mouse_pos = p_to;
} else {
- WindowData &wd = windows[MAIN_WINDOW_ID];
+ WindowID window_id = windows.has(last_focused_window) ? last_focused_window : MAIN_WINDOW_ID;
+ WindowData &wd = windows[window_id];
//local point in window coords
const NSRect contentRect = [wd.window_view frame];
@@ -3526,6 +3530,24 @@ DisplayServer::WindowID DisplayServerOSX::get_window_at_screen_position(const Po
return INVALID_WINDOW_ID;
}
+int64_t DisplayServerOSX::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+ ERR_FAIL_COND_V(!windows.has(p_window), 0);
+ switch (p_handle_type) {
+ case DISPLAY_HANDLE: {
+ return 0; // Not supported.
+ }
+ case WINDOW_HANDLE: {
+ return (int64_t)windows[p_window].window_object;
+ }
+ case WINDOW_VIEW: {
+ return (int64_t)windows[p_window].window_view;
+ }
+ default: {
+ return 0;
+ }
+ }
+}
+
void DisplayServerOSX::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
_THREAD_SAFE_METHOD_
diff --git a/platform/osx/export/export_plugin.cpp b/platform/osx/export/export_plugin.cpp
index 4d1f72f5c9..f0b58efb63 100644
--- a/platform/osx/export/export_plugin.cpp
+++ b/platform/osx/export/export_plugin.cpp
@@ -777,6 +777,24 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
err = tmp_app_dir->make_dir_recursive(tmp_app_path_name + "/Contents/Resources");
}
+ Vector<String> translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations");
+ if (translations.size() > 0) {
+ {
+ String fname = tmp_app_path_name + "/Contents/Resources/en.lproj";
+ tmp_app_dir->make_dir_recursive(fname);
+ FileAccessRef f = FileAccess::open(fname + "/InfoPlist.strings", FileAccess::WRITE);
+ }
+
+ for (const String &E : translations) {
+ Ref<Translation> tr = ResourceLoader::load(E);
+ if (tr.is_valid()) {
+ String fname = tmp_app_path_name + "/Contents/Resources/" + tr->get_locale() + ".lproj";
+ tmp_app_dir->make_dir_recursive(fname);
+ FileAccessRef f = FileAccess::open(fname + "/InfoPlist.strings", FileAccess::WRITE);
+ }
+ }
+ }
+
// Now process our template.
bool found_binary = false;
Vector<String> dylibs_found;
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index c9e2251b35..d288c27016 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -97,7 +97,10 @@ String DisplayServerWindows::get_name() const {
void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) {
if (windows.has(MAIN_WINDOW_ID) && (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED || p_mode == MOUSE_MODE_CONFINED_HIDDEN)) {
// Mouse is grabbed (captured or confined).
- WindowData &wd = windows[MAIN_WINDOW_ID];
+
+ WindowID window_id = windows.has(last_focused_window) ? last_focused_window : MAIN_WINDOW_ID;
+
+ WindowData &wd = windows[window_id];
RECT clipRect;
GetClientRect(wd.hWnd, &clipRect);
@@ -570,6 +573,24 @@ void DisplayServerWindows::gl_window_make_current(DisplayServer::WindowID p_wind
#endif
}
+int64_t DisplayServerWindows::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+ ERR_FAIL_COND_V(!windows.has(p_window), 0);
+ switch (p_handle_type) {
+ case DISPLAY_HANDLE: {
+ return 0; // Not supported.
+ }
+ case WINDOW_HANDLE: {
+ return (int64_t)windows[p_window].hWnd;
+ }
+ case WINDOW_VIEW: {
+ return 0; // Not supported.
+ }
+ default: {
+ return 0;
+ }
+ }
+}
+
void DisplayServerWindows::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
_THREAD_SAFE_METHOD_
@@ -688,6 +709,15 @@ void DisplayServerWindows::window_set_current_screen(int p_screen, WindowID p_wi
Vector2 ofs = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window));
window_set_position(ofs + screen_get_position(p_screen), p_window);
}
+
+ // Don't let the mouse leave the window when resizing to a smaller resolution.
+ if (mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) {
+ RECT crect;
+ GetClientRect(wd.hWnd, &crect);
+ ClientToScreen(wd.hWnd, (POINT *)&crect.left);
+ ClientToScreen(wd.hWnd, (POINT *)&crect.right);
+ ClipCursor(&crect);
+ }
}
Point2i DisplayServerWindows::window_get_position(WindowID p_window) const {
@@ -1050,6 +1080,15 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
SystemParametersInfoA(SPI_SETMOUSETRAILS, 0, 0, 0);
}
}
+
+ // Don't let the mouse leave the window when resizing to a smaller resolution.
+ if (mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) {
+ RECT crect;
+ GetClientRect(wd.hWnd, &crect);
+ ClientToScreen(wd.hWnd, (POINT *)&crect.left);
+ ClientToScreen(wd.hWnd, (POINT *)&crect.right);
+ ClipCursor(&crect);
+ }
}
DisplayServer::WindowMode DisplayServerWindows::window_get_mode(WindowID p_window) const {
@@ -2879,6 +2918,9 @@ void DisplayServerWindows::_process_activate_event(WindowID p_window_id, WPARAM
alt_mem = false;
control_mem = false;
shift_mem = false;
+
+ // Restore mouse mode.
+ _set_mouse_mode_impl(mouse_mode);
} else { // WM_INACTIVE.
Input::get_singleton()->release_pressed_events();
_send_window_event(windows[p_window_id], WINDOW_EVENT_FOCUS_OUT);
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index 3593dc1a05..803c2d4836 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -472,6 +472,8 @@ public:
virtual void show_window(WindowID p_window) override;
virtual void delete_sub_window(WindowID p_window) override;
+ virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override;
+
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override;
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp
index 68762db3a9..d30d0afc5c 100644
--- a/platform/windows/export/export_plugin.cpp
+++ b/platform/windows/export/export_plugin.cpp
@@ -76,8 +76,8 @@ void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "codesign/custom_options"), PackedStringArray()));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0.0"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Company Name"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_description"), ""));
@@ -89,6 +89,7 @@ void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset>
String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit");
if (rcedit_path.is_empty()) {
+ WARN_PRINT("The rcedit tool is not configured in the Editor Settings (Export > Windows > Rcedit). No custom icon or app information data will be embedded in the exported executable.");
return;
}
@@ -327,3 +328,46 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
return OK;
}
+
+bool EditorExportPlatformWindows::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
+ String err = "";
+ bool valid = EditorExportPlatformPC::can_export(p_preset, err, r_missing_templates);
+
+ String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit");
+ if (rcedit_path.is_empty()) {
+ err += TTR("The rcedit tool must be configured in the Editor Settings (Export > Windows > Rcedit) to change the icon or app information data.") + "\n";
+ }
+
+ String icon_path = ProjectSettings::get_singleton()->globalize_path(p_preset->get("application/icon"));
+ if (!icon_path.is_empty() && !FileAccess::exists(icon_path)) {
+ err += TTR("Invalid icon path:") + " " + icon_path + "\n";
+ }
+
+ // Only non-negative integers can exist in the version string.
+
+ String file_version = p_preset->get("application/file_version");
+ if (!file_version.is_empty()) {
+ PackedStringArray version_array = file_version.split(".", false);
+ if (version_array.size() != 4 || !version_array[0].is_valid_int() ||
+ !version_array[1].is_valid_int() || !version_array[2].is_valid_int() ||
+ !version_array[3].is_valid_int() || file_version.find("-") > -1) {
+ err += TTR("Invalid file version:") + " " + file_version + "\n";
+ }
+ }
+
+ String product_version = p_preset->get("application/product_version");
+ if (!product_version.is_empty()) {
+ PackedStringArray version_array = product_version.split(".", false);
+ if (version_array.size() != 4 || !version_array[0].is_valid_int() ||
+ !version_array[1].is_valid_int() || !version_array[2].is_valid_int() ||
+ !version_array[3].is_valid_int() || product_version.find("-") > -1) {
+ err += TTR("Invalid product version:") + " " + product_version + "\n";
+ }
+ }
+
+ if (!err.is_empty()) {
+ r_error = err;
+ }
+
+ return valid;
+}
diff --git a/platform/windows/export/export_plugin.h b/platform/windows/export/export_plugin.h
index 351333aa42..89e5b1b635 100644
--- a/platform/windows/export/export_plugin.h
+++ b/platform/windows/export/export_plugin.h
@@ -47,6 +47,7 @@ public:
virtual Error sign_shared_object(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) override;
virtual void get_export_options(List<ExportOption> *r_options) override;
virtual bool get_export_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override;
+ virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const override;
};
#endif
diff --git a/platform/windows/godot_windows.cpp b/platform/windows/godot_windows.cpp
index 7819ab9a32..618d5670d2 100644
--- a/platform/windows/godot_windows.cpp
+++ b/platform/windows/godot_windows.cpp
@@ -39,7 +39,7 @@
#ifndef TOOLS_ENABLED
#if defined _MSC_VER
#pragma section("pck", read)
-__declspec(allocate("pck")) static char dummy[8] = { 0 };
+__declspec(allocate("pck")) static const char dummy[8] = { 0 };
#elif defined __GNUC__
static const char dummy[8] __attribute__((section("pck"), used)) = { 0 };
#endif
@@ -140,6 +140,11 @@ int widechar_main(int argc, wchar_t **argv) {
setlocale(LC_CTYPE, "");
+#ifndef TOOLS_ENABLED
+ // Workaround to prevent LTCG (MSVC LTO) from removing "pck" section
+ const char *dummy_guard = dummy;
+#endif
+
char **argv_utf8 = new char *[argc];
for (int i = 0; i < argc; ++i) {
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 06b8fea681..d844531071 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -83,15 +83,23 @@ static String format_error_message(DWORD id) {
return msg;
}
+void RedirectStream(const char *p_file_name, const char *p_mode, FILE *p_cpp_stream, const DWORD p_std_handle) {
+ const HANDLE h_existing = GetStdHandle(p_std_handle);
+ if (h_existing != INVALID_HANDLE_VALUE) { // Redirect only if attached console have a valid handle.
+ const HANDLE h_cpp = reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(p_cpp_stream)));
+ if (h_cpp == INVALID_HANDLE_VALUE) { // Redirect only if it's not already redirected to the pipe or file.
+ FILE *fp = p_cpp_stream;
+ freopen_s(&fp, p_file_name, p_mode, p_cpp_stream); // Redirect stream.
+ setvbuf(p_cpp_stream, nullptr, _IONBF, 0); // Disable stream buffering.
+ }
+ }
+}
+
void RedirectIOToConsole() {
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
- FILE *fpstdin = stdin;
- FILE *fpstdout = stdout;
- FILE *fpstderr = stderr;
-
- freopen_s(&fpstdin, "CONIN$", "r", stdin);
- freopen_s(&fpstdout, "CONOUT$", "w", stdout);
- freopen_s(&fpstderr, "CONOUT$", "w", stderr);
+ RedirectStream("CONIN$", "r", stdin, STD_INPUT_HANDLE);
+ RedirectStream("CONOUT$", "w", stdout, STD_OUTPUT_HANDLE);
+ RedirectStream("CONOUT$", "w", stderr, STD_ERROR_HANDLE);
printf("\n"); // Make sure our output is starting from the new line.
}
@@ -385,14 +393,14 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
}
inherit_handles = true;
}
- DWORD creaton_flags = NORMAL_PRIORITY_CLASS;
+ DWORD creation_flags = NORMAL_PRIORITY_CLASS;
if (p_open_console) {
- creaton_flags |= CREATE_NEW_CONSOLE;
+ creation_flags |= CREATE_NEW_CONSOLE;
} else {
- creaton_flags |= CREATE_NO_WINDOW;
+ creation_flags |= CREATE_NO_WINDOW;
}
- int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, inherit_handles, creaton_flags, nullptr, nullptr, si_w, &pi.pi);
+ int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, inherit_handles, creation_flags, nullptr, nullptr, si_w, &pi.pi);
if (!ret && r_pipe) {
CloseHandle(pipe[0]); // Cleanup pipe handles.
CloseHandle(pipe[1]);
@@ -446,14 +454,14 @@ Error OS_Windows::create_process(const String &p_path, const List<String> &p_arg
ZeroMemory(&pi.pi, sizeof(pi.pi));
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
- DWORD creaton_flags = NORMAL_PRIORITY_CLASS;
+ DWORD creation_flags = NORMAL_PRIORITY_CLASS;
if (p_open_console) {
- creaton_flags |= CREATE_NEW_CONSOLE;
+ creation_flags |= CREATE_NEW_CONSOLE;
} else {
- creaton_flags |= CREATE_NO_WINDOW;
+ creation_flags |= CREATE_NO_WINDOW;
}
- int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, creaton_flags, nullptr, nullptr, si_w, &pi.pi);
+ int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, creation_flags, nullptr, nullptr, si_w, &pi.pi);
ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command);
ProcessID pid = pi.pi.dwProcessId;
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp
index 4916eb573c..decb3d0dd8 100644
--- a/scene/2d/animated_sprite_2d.cpp
+++ b/scene/2d/animated_sprite_2d.cpp
@@ -417,7 +417,7 @@ void AnimatedSprite2D::_reset_timeout() {
void AnimatedSprite2D::set_animation(const StringName &p_animation) {
ERR_FAIL_COND_MSG(frames == nullptr, vformat("There is no animation with name '%s'.", p_animation));
- ERR_FAIL_COND_MSG(frames->get_animation_names().find(p_animation) == -1, vformat("There is no animation with name '%s'.", p_animation));
+ ERR_FAIL_COND_MSG(!frames->get_animation_names().has(p_animation), vformat("There is no animation with name '%s'.", p_animation));
if (animation == p_animation) {
return;
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index 0f4e3c8bed..70c7e48fd4 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -268,7 +268,7 @@ uint32_t CollisionObject2D::create_shape_owner(Object *p_owner) {
id = shapes.back()->key() + 1;
}
- sd.owner = p_owner;
+ sd.owner_id = p_owner ? p_owner->get_instance_id() : ObjectID();
shapes[id] = sd;
@@ -382,7 +382,7 @@ Transform2D CollisionObject2D::shape_owner_get_transform(uint32_t p_owner) const
Object *CollisionObject2D::shape_owner_get_owner(uint32_t p_owner) const {
ERR_FAIL_COND_V(!shapes.has(p_owner), nullptr);
- return shapes[p_owner].owner;
+ return ObjectDB::get_instance(shapes[p_owner].owner_id);
}
void CollisionObject2D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2D> &p_shape) {
diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h
index 9463b2c429..f2b7eecc7b 100644
--- a/scene/2d/collision_object_2d.h
+++ b/scene/2d/collision_object_2d.h
@@ -59,7 +59,7 @@ private:
PhysicsServer2D::BodyMode body_mode = PhysicsServer2D::BODY_MODE_STATIC;
struct ShapeData {
- Object *owner = nullptr;
+ ObjectID owner_id;
Transform2D xform;
struct Shape {
Ref<Shape2D> shape;
diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp
index 1a6aaecaa8..7f2290bdc7 100644
--- a/scene/2d/line_2d.cpp
+++ b/scene/2d/line_2d.cpp
@@ -133,7 +133,7 @@ int Line2D::get_point_count() const {
void Line2D::clear_points() {
int count = _points.size();
if (count > 0) {
- _points.resize(0);
+ _points.clear();
update();
}
}
diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp
index e5df089771..fad54070a5 100644
--- a/scene/2d/navigation_obstacle_2d.cpp
+++ b/scene/2d/navigation_obstacle_2d.cpp
@@ -53,9 +53,9 @@ void NavigationObstacle2D::_validate_property(PropertyInfo &p_property) const {
void NavigationObstacle2D::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_READY: {
- initialize_agent();
+ case NOTIFICATION_ENTER_TREE: {
parent_node2d = Object::cast_to<Node2D>(get_parent());
+ reevaluate_agent_radius();
if (parent_node2d != nullptr) {
// place agent on navigation map first or else the RVO agent callback creation fails silently later
NavigationServer2D::get_singleton()->agent_set_map(get_rid(), parent_node2d->get_world_2d()->get_navigation_map());
@@ -83,6 +83,7 @@ void NavigationObstacle2D::_notification(int p_what) {
NavigationObstacle2D::NavigationObstacle2D() {
agent = NavigationServer2D::get_singleton()->agent_create();
+ initialize_agent();
}
NavigationObstacle2D::~NavigationObstacle2D() {
@@ -110,7 +111,7 @@ void NavigationObstacle2D::initialize_agent() {
void NavigationObstacle2D::reevaluate_agent_radius() {
if (!estimate_radius) {
NavigationServer2D::get_singleton()->agent_set_radius(agent, radius);
- } else if (parent_node2d) {
+ } else if (parent_node2d && parent_node2d->is_inside_tree()) {
NavigationServer2D::get_singleton()->agent_set_radius(agent, estimate_agent_radius());
}
}
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index 34f5830d8d..4bead978f1 100644
--- a/scene/2d/navigation_region_2d.cpp
+++ b/scene/2d/navigation_region_2d.cpp
@@ -299,7 +299,7 @@ void NavigationPolygon::make_polygons_from_outlines() {
}
polygons.clear();
- vertices.resize(0);
+ vertices.clear();
Map<Vector2, int> points;
for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) {
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 01fa109384..fb611addf8 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -34,8 +34,8 @@
#include "scene/scene_string_names.h"
void PhysicsBody2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("move_and_collide", "linear_velocity", "test_only", "safe_margin"), &PhysicsBody2D::_move, DEFVAL(false), DEFVAL(0.08));
- ClassDB::bind_method(D_METHOD("test_move", "from", "linear_velocity", "collision", "safe_margin"), &PhysicsBody2D::test_move, DEFVAL(Variant()), DEFVAL(0.08));
+ ClassDB::bind_method(D_METHOD("move_and_collide", "distance", "test_only", "safe_margin"), &PhysicsBody2D::_move, DEFVAL(false), DEFVAL(0.08));
+ ClassDB::bind_method(D_METHOD("test_move", "from", "distance", "collision", "safe_margin"), &PhysicsBody2D::test_move, DEFVAL(Variant()), DEFVAL(0.08));
ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody2D::get_collision_exceptions);
ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody2D::add_collision_exception_with);
@@ -54,11 +54,8 @@ PhysicsBody2D::~PhysicsBody2D() {
}
}
-Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_linear_velocity, bool p_test_only, real_t p_margin) {
- // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
- double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
-
- PhysicsServer2D::MotionParameters parameters(get_global_transform(), p_linear_velocity * delta, p_margin);
+Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_distance, bool p_test_only, real_t p_margin) {
+ PhysicsServer2D::MotionParameters parameters(get_global_transform(), p_distance, p_margin);
PhysicsServer2D::MotionResult result;
if (move_and_collide(parameters, result, p_test_only)) {
@@ -129,7 +126,7 @@ bool PhysicsBody2D::move_and_collide(const PhysicsServer2D::MotionParameters &p_
return colliding;
}
-bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_linear_velocity, const Ref<KinematicCollision2D> &r_collision, real_t p_margin) {
+bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_distance, const Ref<KinematicCollision2D> &r_collision, real_t p_margin) {
ERR_FAIL_COND_V(!is_inside_tree(), false);
PhysicsServer2D::MotionResult *r = nullptr;
@@ -141,10 +138,7 @@ bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_linear
r = &temp_result;
}
- // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky.
- double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
-
- PhysicsServer2D::MotionParameters parameters(p_from, p_linear_velocity * delta, p_margin);
+ PhysicsServer2D::MotionParameters parameters(p_from, p_distance, p_margin);
bool colliding = PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), parameters, r);
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index f1cc100a58..cfaa2570fb 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -47,11 +47,11 @@ protected:
Ref<KinematicCollision2D> motion_cache;
- Ref<KinematicCollision2D> _move(const Vector2 &p_linear_velocity, bool p_test_only = false, real_t p_margin = 0.08);
+ Ref<KinematicCollision2D> _move(const Vector2 &p_distance, bool p_test_only = false, real_t p_margin = 0.08);
public:
bool move_and_collide(const PhysicsServer2D::MotionParameters &p_parameters, PhysicsServer2D::MotionResult &r_result, bool p_test_only = false, bool p_cancel_sliding = true);
- bool test_move(const Transform2D &p_from, const Vector2 &p_linear_velocity, const Ref<KinematicCollision2D> &r_collision = Ref<KinematicCollision2D>(), real_t p_margin = 0.08);
+ bool test_move(const Transform2D &p_from, const Vector2 &p_distance, const Ref<KinematicCollision2D> &r_collision = Ref<KinematicCollision2D>(), real_t p_margin = 0.08);
TypedArray<PhysicsBody2D> get_collision_exceptions();
void add_collision_exception_with(Node *p_node); //must be physicsbody
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 1fdd8b05a6..9521667854 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -263,26 +263,18 @@ void RayCast2D::add_exception_rid(const RID &p_rid) {
exclude.insert(p_rid);
}
-void RayCast2D::add_exception(const Object *p_object) {
- ERR_FAIL_NULL(p_object);
- const CollisionObject2D *co = Object::cast_to<CollisionObject2D>(p_object);
- if (!co) {
- return;
- }
- add_exception_rid(co->get_rid());
+void RayCast2D::add_exception(const CollisionObject2D *p_node) {
+ ERR_FAIL_NULL_MSG(p_node, "The passed Node must be an instance of CollisionObject2D.");
+ add_exception_rid(p_node->get_rid());
}
void RayCast2D::remove_exception_rid(const RID &p_rid) {
exclude.erase(p_rid);
}
-void RayCast2D::remove_exception(const Object *p_object) {
- ERR_FAIL_NULL(p_object);
- const CollisionObject2D *co = Object::cast_to<CollisionObject2D>(p_object);
- if (!co) {
- return;
- }
- remove_exception_rid(co->get_rid());
+void RayCast2D::remove_exception(const CollisionObject2D *p_node) {
+ ERR_FAIL_NULL_MSG(p_node, "The passed Node must be an instance of CollisionObject2D.");
+ remove_exception_rid(p_node->get_rid());
}
void RayCast2D::clear_exceptions() {
diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h
index a1015c6ce0..2c6f2d5c00 100644
--- a/scene/2d/ray_cast_2d.h
+++ b/scene/2d/ray_cast_2d.h
@@ -33,6 +33,8 @@
#include "scene/2d/node_2d.h"
+class CollisionObject2D;
+
class RayCast2D : public Node2D {
GDCLASS(RayCast2D, Node2D);
@@ -94,9 +96,9 @@ public:
Vector2 get_collision_normal() const;
void add_exception_rid(const RID &p_rid);
- void add_exception(const Object *p_object);
+ void add_exception(const CollisionObject2D *p_node);
void remove_exception_rid(const RID &p_rid);
- void remove_exception(const Object *p_object);
+ void remove_exception(const CollisionObject2D *p_node);
void clear_exceptions();
RayCast2D();
diff --git a/scene/2d/shape_cast_2d.cpp b/scene/2d/shape_cast_2d.cpp
index 10194861b4..24199c96b5 100644
--- a/scene/2d/shape_cast_2d.cpp
+++ b/scene/2d/shape_cast_2d.cpp
@@ -322,26 +322,18 @@ void ShapeCast2D::add_exception_rid(const RID &p_rid) {
exclude.insert(p_rid);
}
-void ShapeCast2D::add_exception(const Object *p_object) {
- ERR_FAIL_NULL(p_object);
- const CollisionObject2D *co = Object::cast_to<CollisionObject2D>(p_object);
- if (!co) {
- return;
- }
- add_exception_rid(co->get_rid());
+void ShapeCast2D::add_exception(const CollisionObject2D *p_node) {
+ ERR_FAIL_NULL_MSG(p_node, "The passed Node must be an instance of CollisionObject2D.");
+ add_exception_rid(p_node->get_rid());
}
void ShapeCast2D::remove_exception_rid(const RID &p_rid) {
exclude.erase(p_rid);
}
-void ShapeCast2D::remove_exception(const Object *p_object) {
- ERR_FAIL_NULL(p_object);
- const CollisionObject2D *co = Object::cast_to<CollisionObject2D>(p_object);
- if (!co) {
- return;
- }
- remove_exception_rid(co->get_rid());
+void ShapeCast2D::remove_exception(const CollisionObject2D *p_node) {
+ ERR_FAIL_NULL_MSG(p_node, "The passed Node must be an instance of CollisionObject2D.");
+ remove_exception_rid(p_node->get_rid());
}
void ShapeCast2D::clear_exceptions() {
diff --git a/scene/2d/shape_cast_2d.h b/scene/2d/shape_cast_2d.h
index 7e1ebeb315..ea36b25068 100644
--- a/scene/2d/shape_cast_2d.h
+++ b/scene/2d/shape_cast_2d.h
@@ -34,6 +34,8 @@
#include "scene/2d/node_2d.h"
#include "scene/resources/shape_2d.h"
+class CollisionObject2D;
+
class ShapeCast2D : public Node2D {
GDCLASS(ShapeCast2D, Node2D);
@@ -109,9 +111,9 @@ public:
real_t get_closest_collision_unsafe_fraction() const;
void add_exception_rid(const RID &p_rid);
- void add_exception(const Object *p_object);
+ void add_exception(const CollisionObject2D *p_node);
void remove_exception_rid(const RID &p_rid);
- void remove_exception(const Object *p_object);
+ void remove_exception(const CollisionObject2D *p_node);
void clear_exceptions();
TypedArray<String> get_configuration_warnings() const override;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 25c83b0c8f..02ca1ba2aa 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -1119,7 +1119,7 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
if (q.runtime_tile_data_cache.has(E_cell.value)) {
tile_data = q.runtime_tile_data_cache[E_cell.value];
} else {
- tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile));
+ tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
}
Ref<ShaderMaterial> mat = tile_data->get_material();
@@ -1311,7 +1311,7 @@ void TileMap::draw_tile(RID p_canvas_item, Vector2i p_position, const Ref<TileSe
}
// Get tile data.
- const TileData *tile_data = p_tile_data_override ? p_tile_data_override : Object::cast_to<TileData>(atlas_source->get_tile_data(p_atlas_coords, p_alternative_tile));
+ const TileData *tile_data = p_tile_data_override ? p_tile_data_override : atlas_source->get_tile_data(p_atlas_coords, p_alternative_tile);
// Get the tile modulation.
Color modulate = tile_data->get_modulate() * p_modulation;
@@ -1474,7 +1474,7 @@ void TileMap::_physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r
if (q.runtime_tile_data_cache.has(E_cell->get())) {
tile_data = q.runtime_tile_data_cache[E_cell->get()];
} else {
- tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile));
+ tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
}
for (int tile_set_physics_layer = 0; tile_set_physics_layer < tile_set->get_physics_layers_count(); tile_set_physics_layer++) {
Ref<PhysicsMaterial> physics_material = tile_set->get_physics_layer_physics_material(tile_set_physics_layer);
@@ -1671,7 +1671,7 @@ void TileMap::_navigation_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
if (q.runtime_tile_data_cache.has(E_cell->get())) {
tile_data = q.runtime_tile_data_cache[E_cell->get()];
} else {
- tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile));
+ tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
}
q.navigation_regions[E_cell->get()].resize(tile_set->get_navigation_layers_count());
@@ -1760,7 +1760,7 @@ void TileMap::_navigation_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
if (p_quadrant->runtime_tile_data_cache.has(E_cell->get())) {
tile_data = p_quadrant->runtime_tile_data_cache[E_cell->get()];
} else {
- tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile));
+ tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
}
Transform2D xform;
@@ -2204,7 +2204,7 @@ Set<TileMap::TerrainConstraint> TileMap::get_terrain_constraints_from_removed_ce
Ref<TileSetSource> source = tile_set->get_source(neighbor_cell.source_id);
Ref<TileSetAtlasSource> atlas_source = source;
if (atlas_source.is_valid()) {
- TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(neighbor_cell.get_atlas_coords(), neighbor_cell.alternative_tile));
+ TileData *tile_data = atlas_source->get_tile_data(neighbor_cell.get_atlas_coords(), neighbor_cell.alternative_tile);
if (tile_data && tile_data->get_terrain_set() == p_terrain_set) {
neighbor_tile_data = tile_data;
}
@@ -2580,7 +2580,7 @@ void TileMap::_build_runtime_update_tile_data(SelfList<TileMapQuadrant>::List &r
if (atlas_source) {
bool ret = false;
if (GDVIRTUAL_CALL(_use_tile_data_runtime_update, q.layer, E_cell.value, ret) && ret) {
- TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile));
+ TileData *tile_data = atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile);
// Create the runtime TileData.
TileData *tile_data_runtime_use = tile_data->duplicate();
@@ -3648,9 +3648,6 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_dirty_quadrants"), &TileMap::_update_dirty_quadrants);
- ClassDB::bind_method(D_METHOD("_set_tile_data", "layer", "data"), &TileMap::_set_tile_data);
- ClassDB::bind_method(D_METHOD("_get_tile_data", "layer"), &TileMap::_get_tile_data);
-
ClassDB::bind_method(D_METHOD("_tile_set_changed_deferred_update"), &TileMap::_tile_set_changed_deferred_update);
GDVIRTUAL_BIND(_use_tile_data_runtime_update, "layer", "coords");
diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp
index df7c044f9e..3ab09550fa 100644
--- a/scene/3d/collision_object_3d.cpp
+++ b/scene/3d/collision_object_3d.cpp
@@ -484,7 +484,7 @@ uint32_t CollisionObject3D::create_shape_owner(Object *p_owner) {
id = shapes.back()->key() + 1;
}
- sd.owner = p_owner;
+ sd.owner_id = p_owner ? p_owner->get_instance_id() : ObjectID();
shapes[id] = sd;
@@ -563,7 +563,7 @@ Transform3D CollisionObject3D::shape_owner_get_transform(uint32_t p_owner) const
Object *CollisionObject3D::shape_owner_get_owner(uint32_t p_owner) const {
ERR_FAIL_COND_V(!shapes.has(p_owner), nullptr);
- return shapes[p_owner].owner;
+ return ObjectDB::get_instance(shapes[p_owner].owner_id);
}
void CollisionObject3D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape3D> &p_shape) {
diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h
index f560753543..e92843d784 100644
--- a/scene/3d/collision_object_3d.h
+++ b/scene/3d/collision_object_3d.h
@@ -57,7 +57,7 @@ private:
PhysicsServer3D::BodyMode body_mode = PhysicsServer3D::BODY_MODE_STATIC;
struct ShapeData {
- Object *owner = nullptr;
+ ObjectID owner_id;
Transform3D xform;
struct ShapeBase {
RID debug_shape;
diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp
index b1f6f0cf91..ba6c50d98c 100644
--- a/scene/3d/navigation_obstacle_3d.cpp
+++ b/scene/3d/navigation_obstacle_3d.cpp
@@ -54,9 +54,9 @@ void NavigationObstacle3D::_validate_property(PropertyInfo &p_property) const {
void NavigationObstacle3D::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_READY: {
- initialize_agent();
+ case NOTIFICATION_ENTER_TREE: {
parent_node3d = Object::cast_to<Node3D>(get_parent());
+ reevaluate_agent_radius();
if (parent_node3d != nullptr) {
// place agent on navigation map first or else the RVO agent callback creation fails silently later
NavigationServer3D::get_singleton()->agent_set_map(get_rid(), parent_node3d->get_world_3d()->get_navigation_map());
@@ -91,6 +91,7 @@ void NavigationObstacle3D::_notification(int p_what) {
NavigationObstacle3D::NavigationObstacle3D() {
agent = NavigationServer3D::get_singleton()->agent_create();
+ initialize_agent();
}
NavigationObstacle3D::~NavigationObstacle3D() {
@@ -118,7 +119,7 @@ void NavigationObstacle3D::initialize_agent() {
void NavigationObstacle3D::reevaluate_agent_radius() {
if (!estimate_radius) {
NavigationServer3D::get_singleton()->agent_set_radius(agent, radius);
- } else if (parent_node3d) {
+ } else if (parent_node3d && parent_node3d->is_inside_tree()) {
NavigationServer3D::get_singleton()->agent_set_radius(agent, estimate_agent_radius());
}
}
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index 515d2cfdc7..cad1201d63 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -300,8 +300,9 @@ Node3D *Node3D::get_parent_node_3d() const {
}
Transform3D Node3D::get_relative_transform(const Node *p_parent) const {
- if (p_parent == this)
+ if (p_parent == this) {
return Transform3D();
+ }
ERR_FAIL_COND_V(!data.parent, Transform3D());
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index 1a707024c5..13a38f3b9f 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -34,8 +34,8 @@
#include "scene/scene_string_names.h"
void PhysicsBody3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("move_and_collide", "linear_velocity", "test_only", "safe_margin", "max_collisions"), &PhysicsBody3D::_move, DEFVAL(false), DEFVAL(0.001), DEFVAL(1));
- ClassDB::bind_method(D_METHOD("test_move", "from", "linear_velocity", "collision", "safe_margin", "max_collisions"), &PhysicsBody3D::test_move, DEFVAL(Variant()), DEFVAL(0.001), DEFVAL(1));
+ ClassDB::bind_method(D_METHOD("move_and_collide", "distance", "test_only", "safe_margin", "max_collisions"), &PhysicsBody3D::_move, DEFVAL(false), DEFVAL(0.001), DEFVAL(1));
+ ClassDB::bind_method(D_METHOD("test_move", "from", "distance", "collision", "safe_margin", "max_collisions"), &PhysicsBody3D::test_move, DEFVAL(Variant()), DEFVAL(0.001), DEFVAL(1));
ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &PhysicsBody3D::set_axis_lock);
ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &PhysicsBody3D::get_axis_lock);
@@ -91,11 +91,8 @@ void PhysicsBody3D::remove_collision_exception_with(Node *p_node) {
PhysicsServer3D::get_singleton()->body_remove_collision_exception(get_rid(), collision_object->get_rid());
}
-Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_linear_velocity, bool p_test_only, real_t p_margin, int p_max_collisions) {
- // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky
- double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
-
- PhysicsServer3D::MotionParameters parameters(get_global_transform(), p_linear_velocity * delta, p_margin);
+Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_distance, bool p_test_only, real_t p_margin, int p_max_collisions) {
+ PhysicsServer3D::MotionParameters parameters(get_global_transform(), p_distance, p_margin);
parameters.max_collisions = p_max_collisions;
PhysicsServer3D::MotionResult result;
@@ -170,7 +167,7 @@ bool PhysicsBody3D::move_and_collide(const PhysicsServer3D::MotionParameters &p_
return colliding;
}
-bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_linear_velocity, const Ref<KinematicCollision3D> &r_collision, real_t p_margin, int p_max_collisions) {
+bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_distance, const Ref<KinematicCollision3D> &r_collision, real_t p_margin, int p_max_collisions) {
ERR_FAIL_COND_V(!is_inside_tree(), false);
PhysicsServer3D::MotionResult *r = nullptr;
@@ -182,10 +179,7 @@ bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_linear
r = &temp_result;
}
- // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky
- double delta = Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time();
-
- PhysicsServer3D::MotionParameters parameters(p_from, p_linear_velocity * delta, p_margin);
+ PhysicsServer3D::MotionParameters parameters(p_from, p_distance, p_margin);
bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), parameters, r);
diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h
index 65a763b21e..67dc7382c3 100644
--- a/scene/3d/physics_body_3d.h
+++ b/scene/3d/physics_body_3d.h
@@ -50,11 +50,11 @@ protected:
uint16_t locked_axis = 0;
- Ref<KinematicCollision3D> _move(const Vector3 &p_linear_velocity, bool p_test_only = false, real_t p_margin = 0.001, int p_max_collisions = 1);
+ Ref<KinematicCollision3D> _move(const Vector3 &p_distance, bool p_test_only = false, real_t p_margin = 0.001, int p_max_collisions = 1);
public:
bool move_and_collide(const PhysicsServer3D::MotionParameters &p_parameters, PhysicsServer3D::MotionResult &r_result, bool p_test_only = false, bool p_cancel_sliding = true);
- bool test_move(const Transform3D &p_from, const Vector3 &p_linear_velocity, const Ref<KinematicCollision3D> &r_collision = Ref<KinematicCollision3D>(), real_t p_margin = 0.001, int p_max_collisions = 1);
+ bool test_move(const Transform3D &p_from, const Vector3 &p_distance, const Ref<KinematicCollision3D> &r_collision = Ref<KinematicCollision3D>(), real_t p_margin = 0.001, int p_max_collisions = 1);
void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock);
bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const;
diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp
index 3bb65d07a0..b71c54dcf9 100644
--- a/scene/3d/ray_cast_3d.cpp
+++ b/scene/3d/ray_cast_3d.cpp
@@ -243,26 +243,18 @@ void RayCast3D::add_exception_rid(const RID &p_rid) {
exclude.insert(p_rid);
}
-void RayCast3D::add_exception(const Object *p_object) {
- ERR_FAIL_NULL(p_object);
- const CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_object);
- if (!co) {
- return;
- }
- add_exception_rid(co->get_rid());
+void RayCast3D::add_exception(const CollisionObject3D *p_node) {
+ ERR_FAIL_NULL_MSG(p_node, "The passed Node must be an instance of CollisionObject3D.");
+ add_exception_rid(p_node->get_rid());
}
void RayCast3D::remove_exception_rid(const RID &p_rid) {
exclude.erase(p_rid);
}
-void RayCast3D::remove_exception(const Object *p_object) {
- ERR_FAIL_NULL(p_object);
- const CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_object);
- if (!co) {
- return;
- }
- remove_exception_rid(co->get_rid());
+void RayCast3D::remove_exception(const CollisionObject3D *p_node) {
+ ERR_FAIL_NULL_MSG(p_node, "The passed Node must be an instance of CollisionObject3D.");
+ remove_exception_rid(p_node->get_rid());
}
void RayCast3D::clear_exceptions() {
diff --git a/scene/3d/ray_cast_3d.h b/scene/3d/ray_cast_3d.h
index a53e2c83fc..ad85001591 100644
--- a/scene/3d/ray_cast_3d.h
+++ b/scene/3d/ray_cast_3d.h
@@ -33,6 +33,8 @@
#include "scene/3d/node_3d.h"
+class CollisionObject3D;
+
class RayCast3D : public Node3D {
GDCLASS(RayCast3D, Node3D);
@@ -116,9 +118,9 @@ public:
Vector3 get_collision_normal() const;
void add_exception_rid(const RID &p_rid);
- void add_exception(const Object *p_object);
+ void add_exception(const CollisionObject3D *p_node);
void remove_exception_rid(const RID &p_rid);
- void remove_exception(const Object *p_object);
+ void remove_exception(const CollisionObject3D *p_node);
void clear_exceptions();
RayCast3D();
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index a37fce9469..331d58927b 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -1088,8 +1088,9 @@ void AnimatedSprite3D::set_frame(int p_frame) {
if (frames->has_animation(animation)) {
int limit = frames->get_frame_count(animation);
- if (p_frame >= limit)
+ if (p_frame >= limit) {
p_frame = limit - 1;
+ }
}
if (p_frame < 0) {
diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp
index 33939d4cd6..849316c568 100644
--- a/scene/animation/animation_blend_space_1d.cpp
+++ b/scene/animation/animation_blend_space_1d.cpp
@@ -292,10 +292,10 @@ double AnimationNodeBlendSpace1D::process(double p_time, bool p_seek) {
// actually blend the animations now
- float max_time_remaining = 0.0;
+ double max_time_remaining = 0.0;
for (int i = 0; i < blend_points_used; i++) {
- float remaining = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, weights[i], FILTER_IGNORE, false);
+ double remaining = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, weights[i], FILTER_IGNORE, false);
max_time_remaining = MAX(max_time_remaining, remaining);
}
diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp
index f169e79751..a3aa3f6cc8 100644
--- a/scene/animation/animation_blend_space_2d.cpp
+++ b/scene/animation/animation_blend_space_2d.cpp
@@ -438,7 +438,7 @@ double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek) {
Vector2 blend_pos = get_parameter(blend_position);
int closest = get_parameter(this->closest);
double length_internal = get_parameter(this->length_internal);
- float mind = 0.0; //time of min distance point
+ double mind = 0.0; //time of min distance point
if (blend_mode == BLEND_MODE_INTERPOLATED) {
if (triangles.size() == 0) {
@@ -502,7 +502,7 @@ double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek) {
for (int j = 0; j < 3; j++) {
if (i == triangle_points[j]) {
//blend with the given weight
- float t = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, blend_weights[j], FILTER_IGNORE, false);
+ double t = blend_node(blend_points[i].name, blend_points[i].node, p_time, p_seek, blend_weights[j], FILTER_IGNORE, false);
if (first || t < mind) {
mind = t;
first = false;
@@ -530,7 +530,7 @@ double AnimationNodeBlendSpace2D::process(double p_time, bool p_seek) {
}
if (new_closest != closest && new_closest != -1) {
- float from = 0.0;
+ double from = 0.0;
if (blend_mode == BLEND_MODE_DISCRETE_CARRY && closest != -1) {
//for ping-pong loop
Ref<AnimationNodeAnimation> na_c = static_cast<Ref<AnimationNodeAnimation>>(blend_points[closest].node);
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 2740103a4a..3b55dd4a42 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -371,6 +371,8 @@ void AnimationNodeOneShot::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeOneShot::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeOneShot::is_using_sync);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "mix_mode", PROPERTY_HINT_ENUM, "Blend,Add"), "set_mix_mode", "get_mix_mode");
+
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fadein_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_fadein_time", "get_fadein_time");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fadeout_time", PROPERTY_HINT_RANGE, "0,60,0.01,or_greater"), "set_fadeout_time", "get_fadeout_time");
@@ -748,7 +750,7 @@ double AnimationNodeTransition::process(double p_time, bool p_seek) {
return 0;
}
- float rem = 0.0;
+ double rem = 0.0;
if (prev < 0) { // process current animation, check for transition
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index a551417778..d153b882f9 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -88,7 +88,7 @@ void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) {
}
}
-void AnimationNode::blend_animation(const StringName &p_animation, real_t p_time, real_t p_delta, bool p_seeked, real_t p_blend, int p_pingponged) {
+void AnimationNode::blend_animation(const StringName &p_animation, double p_time, double p_delta, bool p_seeked, real_t p_blend, int p_pingponged) {
ERR_FAIL_COND(!state);
ERR_FAIL_COND(!state->player->has_animation(p_animation));
@@ -119,13 +119,13 @@ void AnimationNode::blend_animation(const StringName &p_animation, real_t p_time
state->animation_states.push_back(anim_state);
}
-real_t AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, real_t p_time, bool p_seek, const Vector<StringName> &p_connections) {
+double AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, double p_time, bool p_seek, const Vector<StringName> &p_connections) {
base_path = p_base_path;
parent = p_parent;
connections = p_connections;
state = p_state;
- real_t t = process(p_time, p_seek);
+ double t = process(p_time, p_seek);
state = nullptr;
parent = nullptr;
@@ -144,7 +144,7 @@ void AnimationNode::make_invalid(const String &p_reason) {
state->invalid_reasons += String::utf8("• ") + p_reason;
}
-real_t AnimationNode::blend_input(int p_input, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter, bool p_optimize) {
+double AnimationNode::blend_input(int p_input, double p_time, bool p_seek, real_t p_blend, FilterAction p_filter, bool p_optimize) {
ERR_FAIL_INDEX_V(p_input, inputs.size(), 0);
ERR_FAIL_COND_V(!state, 0);
@@ -163,7 +163,7 @@ real_t AnimationNode::blend_input(int p_input, real_t p_time, bool p_seek, real_
//inputs.write[p_input].last_pass = state->last_pass;
real_t activity = 0.0;
- real_t ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), nullptr, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity);
+ double ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), nullptr, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity);
Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path);
@@ -174,11 +174,11 @@ real_t AnimationNode::blend_input(int p_input, real_t p_time, bool p_seek, real_
return ret;
}
-real_t AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter, bool p_optimize) {
+double AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, double p_time, bool p_seek, real_t p_blend, FilterAction p_filter, bool p_optimize) {
return _blend_node(p_sub_path, Vector<StringName>(), this, p_node, p_time, p_seek, p_blend, p_filter, p_optimize);
}
-real_t AnimationNode::_blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter, bool p_optimize, real_t *r_max) {
+double AnimationNode::_blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, double p_time, bool p_seek, real_t p_blend, FilterAction p_filter, bool p_optimize, real_t *r_max) {
ERR_FAIL_COND_V(!p_node.is_valid(), 0);
ERR_FAIL_COND_V(!state, 0);
@@ -796,7 +796,7 @@ void AnimationTree::_clear_caches() {
cache_valid = false;
}
-void AnimationTree::_process_graph(real_t p_delta) {
+void AnimationTree::_process_graph(double p_delta) {
_update_properties(); //if properties need updating, update them
//check all tracks, see if they need modification
@@ -1335,10 +1335,10 @@ void AnimationTree::_process_graph(real_t p_delta) {
t->playing = false;
playing_caches.erase(t);
} else {
- real_t start_ofs = a->audio_track_get_key_start_offset(i, idx);
+ double start_ofs = a->audio_track_get_key_start_offset(i, idx);
start_ofs += time - a->track_get_key_time(i, idx);
- real_t end_ofs = a->audio_track_get_key_end_offset(i, idx);
- real_t len = stream->get_length();
+ double end_ofs = a->audio_track_get_key_end_offset(i, idx);
+ double len = stream->get_length();
if (start_ofs > len - end_ofs) {
t->object->call("stop");
@@ -1374,9 +1374,9 @@ void AnimationTree::_process_graph(real_t p_delta) {
t->playing = false;
playing_caches.erase(t);
} else {
- real_t start_ofs = a->audio_track_get_key_start_offset(i, idx);
- real_t end_ofs = a->audio_track_get_key_end_offset(i, idx);
- real_t len = stream->get_length();
+ double start_ofs = a->audio_track_get_key_start_offset(i, idx);
+ double end_ofs = a->audio_track_get_key_end_offset(i, idx);
+ double len = stream->get_length();
t->object->call("set_stream", stream);
t->object->call("play", start_ofs);
@@ -1407,7 +1407,7 @@ void AnimationTree::_process_graph(real_t p_delta) {
}
}
} else if (t->len > 0) {
- real_t len = t->start > time ? (a->get_length() - t->start) + time : time - t->start;
+ double len = t->start > time ? (a->get_length() - t->start) + time : time - t->start;
if (len > t->len) {
stop = true;
@@ -1455,7 +1455,7 @@ void AnimationTree::_process_graph(real_t p_delta) {
Ref<Animation> anim = player2->get_animation(anim_name);
- real_t at_anim_pos = 0.0;
+ double at_anim_pos = 0.0;
switch (anim->get_loop_mode()) {
case Animation::LoopMode::LOOP_NONE: {
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index 11c9bcd4ef..705ee91c76 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -83,7 +83,7 @@ public:
Vector<real_t> blends;
State *state = nullptr;
- real_t _pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, real_t p_time, bool p_seek, const Vector<StringName> &p_connections);
+ double _pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, double p_time, bool p_seek, const Vector<StringName> &p_connections);
//all this is temporary
StringName base_path;
@@ -96,12 +96,12 @@ public:
Array _get_filters() const;
void _set_filters(const Array &p_filters);
friend class AnimationNodeBlendTree;
- real_t _blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true, real_t *r_max = nullptr);
+ double _blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, double p_time, bool p_seek, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true, real_t *r_max = nullptr);
protected:
- void blend_animation(const StringName &p_animation, real_t p_time, real_t p_delta, bool p_seeked, real_t p_blend, int p_pingponged = 0);
- real_t blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true);
- real_t blend_input(int p_input, real_t p_time, bool p_seek, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true);
+ void blend_animation(const StringName &p_animation, double p_time, double p_delta, bool p_seeked, real_t p_blend, int p_pingponged = 0);
+ double blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, double p_time, bool p_seek, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true);
+ double blend_input(int p_input, double p_time, bool p_seek, real_t p_blend, FilterAction p_filter = FILTER_IGNORE, bool p_optimize = true);
void make_invalid(const String &p_reason);
@@ -234,8 +234,8 @@ private:
struct TrackCacheAudio : public TrackCache {
bool playing = false;
- real_t start = 0.0;
- real_t len = 0.0;
+ double start = 0.0;
+ double len = 0.0;
TrackCacheAudio() {
type = Animation::TYPE_AUDIO;
@@ -265,7 +265,7 @@ private:
void _clear_caches();
bool _update_caches(AnimationPlayer *player);
- void _process_graph(real_t p_delta);
+ void _process_graph(double p_delta);
uint64_t setup_pass = 1;
uint64_t process_pass = 1;
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index a37c6f5355..a2fed718be 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -249,8 +249,6 @@ bool Tween::custom_step(float p_delta) {
}
bool Tween::step(float p_delta) {
- ERR_FAIL_COND_V_MSG(tweeners.is_empty(), false, "Tween started, but has no Tweeners.");
-
if (dead) {
return false;
}
@@ -271,6 +269,7 @@ bool Tween::step(float p_delta) {
}
if (!started) {
+ ERR_FAIL_COND_V_MSG(tweeners.is_empty(), false, "Tween started, but has no Tweeners.");
current_step = 0;
loops_done = 0;
start_tweeners();
@@ -284,6 +283,10 @@ bool Tween::step(float p_delta) {
float step_delta = rem_delta;
step_active = false;
+#ifdef DEBUG_ENABLED
+ float prev_delta = rem_delta;
+#endif
+
for (Ref<Tweener> &tweener : tweeners.write[current_step]) {
// Modified inside Tweener.step().
float temp_delta = rem_delta;
@@ -313,6 +316,12 @@ bool Tween::step(float p_delta) {
start_tweeners();
}
}
+
+#ifdef DEBUG_ENABLED
+ if (Math::is_equal_approx(rem_delta, prev_delta) && running && loops <= 0) {
+ ERR_FAIL_V_MSG(false, "Infinite loop detected. Check set_loops() description for more info.");
+ }
+#endif
}
return true;
diff --git a/scene/debugger/scene_debugger.h b/scene/debugger/scene_debugger.h
index 432317a423..c8298391bb 100644
--- a/scene/debugger/scene_debugger.h
+++ b/scene/debugger/scene_debugger.h
@@ -37,6 +37,7 @@
#include "core/variant/array.h"
class Script;
+class Node;
class SceneDebugger {
public:
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index bcb2b0c50e..da2ef6c5ec 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -382,8 +382,11 @@ Ref<ButtonGroup> BaseButton::get_button_group() const {
}
void BaseButton::set_shortcut_context(Node *p_node) {
- ERR_FAIL_NULL_MSG(p_node, "Shortcut context node can't be null.");
- shortcut_context = p_node->get_instance_id();
+ if (p_node != nullptr) {
+ shortcut_context = p_node->get_instance_id();
+ } else {
+ shortcut_context = ObjectID();
+ }
}
Node *BaseButton::get_shortcut_context() const {
@@ -400,7 +403,7 @@ bool BaseButton::_is_focus_owner_in_shorcut_context() const {
}
Node *ctx_node = get_shortcut_context();
- Control *vp_focus = get_focus_owner();
+ Control *vp_focus = get_viewport() ? get_viewport()->gui_get_focus_owner() : nullptr;
// If the context is valid and the viewport focus is valid, check if the context is the focus or is a parent of it.
return ctx_node && vp_focus && (ctx_node == vp_focus || ctx_node->is_ancestor_of(vp_focus));
@@ -441,6 +444,7 @@ void BaseButton::_bind_methods() {
ADD_SIGNAL(MethodInfo("button_up"));
ADD_SIGNAL(MethodInfo("button_down"));
ADD_SIGNAL(MethodInfo("toggled", PropertyInfo(Variant::BOOL, "button_pressed")));
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "toggle_mode"), "set_toggle_mode", "is_toggle_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_in_tooltip"), "set_shortcut_in_tooltip", "is_shortcut_in_tooltip_enabled");
@@ -500,7 +504,8 @@ BaseButton *ButtonGroup::get_pressed_button() {
void ButtonGroup::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_pressed_button"), &ButtonGroup::get_pressed_button);
ClassDB::bind_method(D_METHOD("get_buttons"), &ButtonGroup::_get_buttons);
- ADD_SIGNAL(MethodInfo("pressed", PropertyInfo(Variant::OBJECT, "button")));
+
+ ADD_SIGNAL(MethodInfo("pressed", PropertyInfo(Variant::OBJECT, "button", PROPERTY_HINT_RESOURCE_TYPE, "BaseButton")));
}
ButtonGroup::ButtonGroup() {
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 552dd28513..3ed1b873af 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -197,6 +197,8 @@ void Button::_notification(int p_what) {
color = get_theme_color(SNAME("font_disabled_color"));
if (has_theme_color(SNAME("icon_disabled_color"))) {
color_icon = get_theme_color(SNAME("icon_disabled_color"));
+ } else {
+ color_icon.a = 0.4;
}
} break;
@@ -232,9 +234,6 @@ void Button::_notification(int p_what) {
}
if (!_icon.is_null()) {
int valign = size.height - style->get_minimum_size().y;
- if (is_disabled()) {
- color_icon.a = 0.4;
- }
float icon_ofs_region = 0.0;
Point2 style_offset;
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 8924c37c50..22def607ed 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -571,6 +571,8 @@ Control::CursorShape CodeEdit::get_cursor_shape(const Point2 &p_pos) const {
// Overridable actions
void CodeEdit::_handle_unicode_input_internal(const uint32_t p_unicode) {
bool had_selection = has_selection();
+ String selection_text = (had_selection ? get_selected_text() : "");
+
if (had_selection) {
begin_complex_operation();
delete_selection();
@@ -591,27 +593,38 @@ void CodeEdit::_handle_unicode_input_internal(const uint32_t p_unicode) {
if (auto_brace_completion_enabled) {
int cl = get_caret_line();
int cc = get_caret_column();
- int caret_move_offset = 1;
-
- int post_brace_pair = cc < get_line(cl).length() ? _get_auto_brace_pair_close_at_pos(cl, cc) : -1;
- if (has_string_delimiter(chr) && cc > 0 && _is_char(get_line(cl)[cc - 1]) && post_brace_pair == -1) {
- insert_text_at_caret(chr);
- } else if (cc < get_line(cl).length() && _is_char(get_line(cl)[cc])) {
- insert_text_at_caret(chr);
- } else if (post_brace_pair != -1 && auto_brace_completion_pairs[post_brace_pair].close_key[0] == chr[0]) {
- caret_move_offset = auto_brace_completion_pairs[post_brace_pair].close_key.length();
- } else if (is_in_comment(cl, cc) != -1 || (is_in_string(cl, cc) != -1 && has_string_delimiter(chr))) {
+ if (had_selection) {
insert_text_at_caret(chr);
+
+ String close_key = get_auto_brace_completion_close_key(chr);
+ if (!close_key.is_empty()) {
+ insert_text_at_caret(selection_text + close_key);
+ set_caret_column(get_caret_column() - 1);
+ }
} else {
- insert_text_at_caret(chr);
+ int caret_move_offset = 1;
+
+ int post_brace_pair = cc < get_line(cl).length() ? _get_auto_brace_pair_close_at_pos(cl, cc) : -1;
+
+ if (has_string_delimiter(chr) && cc > 0 && _is_char(get_line(cl)[cc - 1]) && post_brace_pair == -1) {
+ insert_text_at_caret(chr);
+ } else if (cc < get_line(cl).length() && _is_char(get_line(cl)[cc])) {
+ insert_text_at_caret(chr);
+ } else if (post_brace_pair != -1 && auto_brace_completion_pairs[post_brace_pair].close_key[0] == chr[0]) {
+ caret_move_offset = auto_brace_completion_pairs[post_brace_pair].close_key.length();
+ } else if (is_in_comment(cl, cc) != -1 || (is_in_string(cl, cc) != -1 && has_string_delimiter(chr))) {
+ insert_text_at_caret(chr);
+ } else {
+ insert_text_at_caret(chr);
- int pre_brace_pair = _get_auto_brace_pair_open_at_pos(cl, cc + 1);
- if (pre_brace_pair != -1) {
- insert_text_at_caret(auto_brace_completion_pairs[pre_brace_pair].close_key);
+ int pre_brace_pair = _get_auto_brace_pair_open_at_pos(cl, cc + 1);
+ if (pre_brace_pair != -1) {
+ insert_text_at_caret(auto_brace_completion_pairs[pre_brace_pair].close_key);
+ }
}
+ set_caret_column(cc + caret_move_offset);
}
- set_caret_column(cc + caret_move_offset);
} else {
insert_text_at_caret(chr);
}
@@ -2857,7 +2870,7 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
completion_options_casei.push_back(option);
} else if (s.is_subsequence_of(option.display)) {
completion_options_subseq.push_back(option);
- } else if (s.is_subsequence_ofi(option.display)) {
+ } else if (s.is_subsequence_ofn(option.display)) {
completion_options_subseq_casei.push_back(option);
}
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 562ea8a8f7..fdae8e2f1f 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -576,6 +576,11 @@ void Control::_update_canvas_item_transform() {
Transform2D xform = _get_internal_transform();
xform[2] += get_position();
+ // We use a little workaround to avoid flickering when moving the pivot with _edit_set_pivot()
+ if (is_inside_tree() && Math::abs(Math::sin(data.rotation * 4.0f)) < 0.00001f && get_viewport()->is_snap_controls_to_pixels_enabled()) {
+ xform[2] = xform[2].round();
+ }
+
RenderingServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), xform);
}
@@ -2191,8 +2196,7 @@ void Control::release_focus() {
return;
}
- get_viewport()->_gui_remove_focus();
- update();
+ get_viewport()->gui_release_focus();
}
bool Control::is_top_level_control() const {
@@ -2595,11 +2599,6 @@ Control::MouseFilter Control::get_mouse_filter() const {
return data.mouse_filter;
}
-Control *Control::get_focus_owner() const {
- ERR_FAIL_COND_V(!is_inside_tree(), nullptr);
- return get_viewport()->_gui_get_focus_owner();
-}
-
void Control::warp_mouse(const Point2 &p_to_pos) {
ERR_FAIL_COND(!is_inside_tree());
get_viewport()->warp_mouse(get_global_transform().xform(p_to_pos));
@@ -2889,7 +2888,6 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("release_focus"), &Control::release_focus);
ClassDB::bind_method(D_METHOD("find_prev_valid_focus"), &Control::find_prev_valid_focus);
ClassDB::bind_method(D_METHOD("find_next_valid_focus"), &Control::find_next_valid_focus);
- ClassDB::bind_method(D_METHOD("get_focus_owner"), &Control::get_focus_owner);
ClassDB::bind_method(D_METHOD("set_h_size_flags", "flags"), &Control::set_h_size_flags);
ClassDB::bind_method(D_METHOD("get_h_size_flags"), &Control::get_h_size_flags);
diff --git a/scene/gui/control.h b/scene/gui/control.h
index bf79f790e7..962135280f 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -462,8 +462,6 @@ public:
void set_focus_previous(const NodePath &p_prev);
NodePath get_focus_previous() const;
- Control *get_focus_owner() const;
-
void set_mouse_filter(MouseFilter p_filter);
MouseFilter get_mouse_filter() const;
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index e5bd6f4882..dad84461f4 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -169,7 +169,14 @@ void FileDialog::update_dir() {
dir->set_text(dir_access->get_current_dir(false));
if (drives->is_visible()) {
- drives->select(dir_access->get_current_drive());
+ if (dir_access->get_current_dir().is_network_share_path()) {
+ _update_drives(false);
+ drives->add_item(RTR("Network"));
+ drives->set_item_disabled(drives->get_item_count() - 1, true);
+ drives->select(drives->get_item_count() - 1);
+ } else {
+ drives->select(dir_access->get_current_drive());
+ }
}
// Deselect any item, to make "Select Current Folder" button text by default.
@@ -846,7 +853,7 @@ void FileDialog::_select_drive(int p_idx) {
_push_history();
}
-void FileDialog::_update_drives() {
+void FileDialog::_update_drives(bool p_select) {
int dc = dir_access->get_drive_count();
if (dc == 0 || access != ACCESS_FILESYSTEM) {
drives->hide();
@@ -864,7 +871,9 @@ void FileDialog::_update_drives() {
drives->add_item(dir_access->get_drive(i));
}
- drives->select(dir_access->get_current_drive());
+ if (p_select) {
+ drives->select(dir_access->get_current_drive());
+ }
}
}
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 9f8bc02b2a..36a6b262b0 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -132,7 +132,7 @@ private:
void _go_back();
void _go_forward();
- void _update_drives();
+ void _update_drives(bool p_select = true);
virtual void unhandled_input(const Ref<InputEvent> &p_event) override;
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 2be76473b0..95575a8226 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -1692,8 +1692,9 @@ int GraphEdit::_set_operations(SET_OPERATIONS p_operation, Set<StringName> &r_u,
switch (p_operation) {
case GraphEdit::IS_EQUAL: {
for (Set<StringName>::Element *E = r_u.front(); E; E = E->next()) {
- if (!r_v.has(E->get()))
+ if (!r_v.has(E->get())) {
return 0;
+ }
}
return r_u.size() == r_v.size();
} break;
@@ -1702,8 +1703,9 @@ int GraphEdit::_set_operations(SET_OPERATIONS p_operation, Set<StringName> &r_u,
return 1;
}
for (Set<StringName>::Element *E = r_u.front(); E; E = E->next()) {
- if (!r_v.has(E->get()))
+ if (!r_v.has(E->get())) {
return 0;
+ }
}
return 1;
} break;
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index fab420d593..852aaaab24 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -82,9 +82,11 @@ void Label::_shape() {
Ref<StyleBox> style = get_theme_stylebox(SNAME("normal"), SNAME("Label"));
int width = (get_size().width - style->get_minimum_size().width);
- if (dirty) {
+ if (dirty || font_dirty) {
String lang = (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale();
- TS->shaped_text_clear(text_rid);
+ if (dirty) {
+ TS->shaped_text_clear(text_rid);
+ }
if (text_direction == Control::TEXT_DIRECTION_INHERITED) {
TS->shaped_text_set_direction(text_rid, is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
} else {
@@ -97,9 +99,17 @@ void Label::_shape() {
if (visible_chars >= 0 && visible_chars_behavior == VC_CHARS_BEFORE_SHAPING) {
text = text.substr(0, visible_chars);
}
- TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, opentype_features, lang);
+ if (dirty) {
+ TS->shaped_text_add_string(text_rid, text, font->get_rids(), font_size, opentype_features, lang);
+ } else {
+ int spans = TS->shaped_get_span_count(text_rid);
+ for (int i = 0; i < spans; i++) {
+ TS->shaped_set_span_update_font(text_rid, i, font->get_rids(), font_size, opentype_features);
+ }
+ }
TS->shaped_text_set_bidi_override(text_rid, structured_text_parser(st_parser, st_args, text));
dirty = false;
+ font_dirty = false;
lines_dirty = true;
}
@@ -276,7 +286,7 @@ void Label::_notification(int p_what) {
RenderingServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), true);
}
- if (dirty || lines_dirty) {
+ if (dirty || font_dirty || lines_dirty) {
_shape();
}
@@ -521,7 +531,7 @@ void Label::_notification(int p_what) {
}
if (p_what == NOTIFICATION_THEME_CHANGED) {
- dirty = true;
+ font_dirty = true;
update();
}
if (p_what == NOTIFICATION_RESIZED) {
@@ -531,7 +541,7 @@ void Label::_notification(int p_what) {
Size2 Label::get_minimum_size() const {
// don't want to mutable everything
- if (dirty || lines_dirty) {
+ if (dirty || font_dirty || lines_dirty) {
const_cast<Label *>(this)->_shape();
}
@@ -555,7 +565,7 @@ int Label::get_line_count() const {
if (!is_inside_tree()) {
return 1;
}
- if (dirty || lines_dirty) {
+ if (dirty || font_dirty || lines_dirty) {
const_cast<Label *>(this)->_shape();
}
@@ -630,7 +640,7 @@ void Label::set_text_direction(Control::TextDirection p_text_direction) {
ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3);
if (text_direction != p_text_direction) {
text_direction = p_text_direction;
- dirty = true;
+ font_dirty = true;
update();
}
}
@@ -638,7 +648,7 @@ void Label::set_text_direction(Control::TextDirection p_text_direction) {
void Label::set_structured_text_bidi_override(Control::StructuredTextParser p_parser) {
if (st_parser != p_parser) {
st_parser = p_parser;
- dirty = true;
+ font_dirty = true;
update();
}
}
@@ -649,7 +659,7 @@ Control::StructuredTextParser Label::get_structured_text_bidi_override() const {
void Label::set_structured_text_bidi_override_options(Array p_args) {
st_args = p_args;
- dirty = true;
+ font_dirty = true;
update();
}
@@ -663,7 +673,7 @@ Control::TextDirection Label::get_text_direction() const {
void Label::clear_opentype_features() {
opentype_features.clear();
- dirty = true;
+ font_dirty = true;
update();
}
@@ -671,7 +681,7 @@ void Label::set_opentype_feature(const String &p_name, int p_value) {
int32_t tag = TS->name_to_tag(p_name);
if (!opentype_features.has(tag) || (int)opentype_features[tag] != p_value) {
opentype_features[tag] = p_value;
- dirty = true;
+ font_dirty = true;
update();
}
}
@@ -798,7 +808,7 @@ int Label::get_max_lines_visible() const {
}
int Label::get_total_character_count() const {
- if (dirty || lines_dirty) {
+ if (dirty || font_dirty || lines_dirty) {
const_cast<Label *>(this)->_shape();
}
@@ -814,13 +824,13 @@ bool Label::_set(const StringName &p_name, const Variant &p_value) {
if (value == -1) {
if (opentype_features.has(tag)) {
opentype_features.erase(tag);
- dirty = true;
+ font_dirty = true;
update();
}
} else {
if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
opentype_features[tag] = value;
- dirty = true;
+ font_dirty = true;
update();
}
}
diff --git a/scene/gui/label.h b/scene/gui/label.h
index 354e9c664d..0b931b3084 100644
--- a/scene/gui/label.h
+++ b/scene/gui/label.h
@@ -73,6 +73,7 @@ private:
bool lines_dirty = true;
bool dirty = true;
+ bool font_dirty = true;
RID text_rid;
Vector<RID> lines_rid;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 88953fa7db..3aae3377bc 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -752,7 +752,7 @@ void LineEdit::_notification(int p_what) {
// Draw placeholder color.
if (using_placeholder) {
- font_color.a *= placeholder_alpha;
+ font_color = get_theme_color(SNAME("font_placeholder_color"));
}
bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled;
@@ -1476,15 +1476,6 @@ String LineEdit::get_placeholder() const {
return placeholder;
}
-void LineEdit::set_placeholder_alpha(float p_alpha) {
- placeholder_alpha = p_alpha;
- update();
-}
-
-float LineEdit::get_placeholder_alpha() const {
- return placeholder_alpha;
-}
-
void LineEdit::set_caret_column(int p_column) {
if (p_column > (int)text.length()) {
p_column = text.length();
@@ -2245,8 +2236,6 @@ void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_structured_text_bidi_override_options"), &LineEdit::get_structured_text_bidi_override_options);
ClassDB::bind_method(D_METHOD("set_placeholder", "text"), &LineEdit::set_placeholder);
ClassDB::bind_method(D_METHOD("get_placeholder"), &LineEdit::get_placeholder);
- ClassDB::bind_method(D_METHOD("set_placeholder_alpha", "alpha"), &LineEdit::set_placeholder_alpha);
- ClassDB::bind_method(D_METHOD("get_placeholder_alpha"), &LineEdit::get_placeholder_alpha);
ClassDB::bind_method(D_METHOD("set_caret_column", "position"), &LineEdit::set_caret_column);
ClassDB::bind_method(D_METHOD("get_caret_column"), &LineEdit::get_caret_column);
ClassDB::bind_method(D_METHOD("get_scroll_offset"), &LineEdit::get_scroll_offset);
@@ -2328,6 +2317,7 @@ void LineEdit::_bind_methods() {
BIND_ENUM_CONSTANT(MENU_MAX);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "placeholder_text"), "set_placeholder", "get_placeholder");
ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_horizontal_alignment", "get_horizontal_alignment");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_length", PROPERTY_HINT_RANGE, "0,1000,1,or_greater"), "set_max_length", "get_max_length");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable");
@@ -2349,9 +2339,6 @@ void LineEdit::_bind_methods() {
ADD_GROUP("Structured Text", "structured_text_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "structured_text_bidi_override_options"), "set_structured_text_bidi_override_options", "get_structured_text_bidi_override_options");
- ADD_GROUP("Placeholder", "placeholder_");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "placeholder_text"), "set_placeholder", "get_placeholder");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "placeholder_alpha", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_placeholder_alpha", "get_placeholder_alpha");
ADD_GROUP("Caret", "caret_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "set_caret_blink_enabled", "is_caret_blink_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "set_caret_blink_speed", "get_caret_blink_speed");
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index 0c313f71c2..1519c09d73 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -82,7 +82,6 @@ private:
String placeholder;
String placeholder_translated;
String secret_character = "*";
- float placeholder_alpha = 0.6;
String ime_text;
Point2 ime_selection;
@@ -262,9 +261,6 @@ public:
void set_placeholder(String p_text);
String get_placeholder() const;
- void set_placeholder_alpha(float p_alpha);
- float get_placeholder_alpha() const;
-
void set_caret_column(int p_column);
int get_caret_column() const;
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index f7805136f9..a985a9d031 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -98,7 +98,13 @@ void MenuButton::pressed() {
popup->set_position(gp);
popup->set_parent_rect(Rect2(Point2(gp - popup->get_position()), size));
- popup->take_mouse_focus();
+ // If not triggered by the mouse, start the popup with its first item selected.
+ if (popup->get_item_count() > 0 &&
+ ((get_action_mode() == ActionMode::ACTION_MODE_BUTTON_PRESS && Input::get_singleton()->is_action_just_pressed("ui_accept")) ||
+ (get_action_mode() == ActionMode::ACTION_MODE_BUTTON_RELEASE && Input::get_singleton()->is_action_just_released("ui_accept")))) {
+ popup->set_current_index(0);
+ }
+
popup->popup();
}
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 90bb316448..9984ab240a 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -32,6 +32,8 @@
#include "core/string/print_string.h"
+static const int NONE_SELECTED = -1;
+
Size2 OptionButton::get_minimum_size() const {
Size2 minsize = Button::get_minimum_size();
@@ -119,7 +121,7 @@ bool OptionButton::_set(const StringName &p_name, const Variant &p_value) {
int idx = components[1].get_slice("_", 1).to_int();
if (idx == current) {
// Force refreshing currently displayed item.
- current = -1;
+ current = NONE_SELECTED;
_select(idx, false);
}
@@ -154,7 +156,7 @@ void OptionButton::_get_property_list(List<PropertyInfo> *p_list) const {
pi.usage &= ~(!popup->is_item_checked(i) ? PROPERTY_USAGE_STORAGE : 0);
p_list->push_back(pi);
- pi = PropertyInfo(Variant::INT, vformat("popup/item_%d/id", i), PROPERTY_HINT_RANGE, "1,10,1,or_greater");
+ pi = PropertyInfo(Variant::INT, vformat("popup/item_%d/id", i), PROPERTY_HINT_RANGE, "0,10,1,or_greater");
p_list->push_back(pi);
pi = PropertyInfo(Variant::BOOL, vformat("popup/item_%d/disabled", i));
@@ -179,7 +181,14 @@ void OptionButton::pressed() {
Size2 size = get_size() * get_viewport()->get_canvas_transform().get_scale();
popup->set_position(get_screen_position() + Size2(0, size.height * get_global_transform().get_scale().y));
popup->set_size(Size2(size.width, 0));
- popup->set_current_index(current);
+
+ // If not triggered by the mouse, start the popup with the checked item selected.
+ if (popup->get_item_count() > 0 &&
+ ((get_action_mode() == ActionMode::ACTION_MODE_BUTTON_PRESS && Input::get_singleton()->is_action_just_pressed("ui_accept")) ||
+ (get_action_mode() == ActionMode::ACTION_MODE_BUTTON_RELEASE && Input::get_singleton()->is_action_just_released("ui_accept")))) {
+ popup->set_current_index(current > -1 ? current : 0);
+ }
+
popup->popup();
}
@@ -234,6 +243,10 @@ Ref<Texture2D> OptionButton::get_item_icon(int p_idx) const {
}
int OptionButton::get_item_id(int p_idx) const {
+ if (p_idx == NONE_SELECTED) {
+ return NONE_SELECTED;
+ }
+
return popup->get_item_id(p_idx);
}
@@ -266,26 +279,33 @@ void OptionButton::add_separator() {
void OptionButton::clear() {
popup->clear();
set_text("");
- current = -1;
+ current = NONE_SELECTED;
}
void OptionButton::_select(int p_which, bool p_emit) {
- if (p_which < 0) {
- return;
- }
if (p_which == current) {
return;
}
- ERR_FAIL_INDEX(p_which, popup->get_item_count());
+ if (p_which == NONE_SELECTED) {
+ for (int i = 0; i < popup->get_item_count(); i++) {
+ popup->set_item_checked(i, false);
+ }
- for (int i = 0; i < popup->get_item_count(); i++) {
- popup->set_item_checked(i, i == p_which);
- }
+ current = NONE_SELECTED;
+ set_text("");
+ set_icon(NULL);
+ } else {
+ ERR_FAIL_INDEX(p_which, popup->get_item_count());
- current = p_which;
- set_text(popup->get_item_text(current));
- set_icon(popup->get_item_icon(current));
+ for (int i = 0; i < popup->get_item_count(); i++) {
+ popup->set_item_checked(i, i == p_which);
+ }
+
+ current = p_which;
+ set_text(popup->get_item_text(current));
+ set_icon(popup->get_item_icon(current));
+ }
if (is_inside_tree() && p_emit) {
emit_signal(SNAME("item_selected"), current);
@@ -293,7 +313,7 @@ void OptionButton::_select(int p_which, bool p_emit) {
}
void OptionButton::_select_int(int p_which) {
- if (p_which < 0 || p_which >= popup->get_item_count()) {
+ if (p_which < NONE_SELECTED || p_which >= popup->get_item_count()) {
return;
}
_select(p_which, false);
@@ -308,10 +328,6 @@ int OptionButton::get_selected() const {
}
int OptionButton::get_selected_id() const {
- int idx = get_selected();
- if (idx < 0) {
- return 0;
- }
return get_item_id(current);
}
@@ -325,6 +341,9 @@ Variant OptionButton::get_selected_metadata() const {
void OptionButton::remove_item(int p_idx) {
popup->remove_item(p_idx);
+ if (current == p_idx) {
+ _select(NONE_SELECTED);
+ }
}
PopupMenu *OptionButton::get_popup() const {
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index c9fddc3e17..812339dc19 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -192,7 +192,7 @@ void PopupMenu::_activate_submenu(int p_over) {
Popup *submenu_popup = Object::cast_to<Popup>(n);
ERR_FAIL_COND_MSG(!submenu_popup, "Item subnode is not a Popup: " + items[p_over].submenu + ".");
if (submenu_popup->is_visible()) {
- return; //already visible!
+ return; // Already visible.
}
Ref<StyleBox> style = get_theme_stylebox(SNAME("panel"));
@@ -223,24 +223,33 @@ void PopupMenu::_activate_submenu(int p_over) {
submenu_popup->set_close_on_parent_focus(false);
submenu_popup->set_position(submenu_pos);
submenu_popup->set_as_minsize(); // Shrink the popup size to its contents.
- submenu_popup->popup();
- // Set autohide areas
PopupMenu *submenu_pum = Object::cast_to<PopupMenu>(submenu_popup);
- if (submenu_pum) {
- submenu_pum->take_mouse_focus();
- // Make the position of the parent popup relative to submenu popup
- this_rect.position = this_rect.position - submenu_pum->get_position();
-
- // Autohide area above the submenu item
- submenu_pum->clear_autohide_areas();
- submenu_pum->add_autohide_area(Rect2(this_rect.position.x, this_rect.position.y, this_rect.size.x, items[p_over]._ofs_cache + scroll_offset + style->get_offset().height - vsep / 2));
-
- // If there is an area below the submenu item, add an autohide area there.
- if (items[p_over]._ofs_cache + items[p_over]._height_cache + scroll_offset <= control->get_size().height) {
- int from = items[p_over]._ofs_cache + items[p_over]._height_cache + scroll_offset + vsep / 2 + style->get_offset().height;
- submenu_pum->add_autohide_area(Rect2(this_rect.position.x, this_rect.position.y + from, this_rect.size.x, this_rect.size.y - from));
- }
+ if (!submenu_pum) {
+ submenu_popup->popup();
+ return;
+ }
+
+ // If not triggered by the mouse, start the popup with its first item selected.
+ if (submenu_pum->get_item_count() > 0 && Input::get_singleton()->is_action_just_pressed("ui_accept")) {
+ submenu_pum->set_current_index(0);
+ }
+
+ submenu_pum->popup();
+
+ // Set autohide areas.
+
+ // Make the position of the parent popup relative to submenu popup.
+ this_rect.position = this_rect.position - submenu_pum->get_position();
+
+ // Autohide area above the submenu item.
+ submenu_pum->clear_autohide_areas();
+ submenu_pum->add_autohide_area(Rect2(this_rect.position.x, this_rect.position.y, this_rect.size.x, items[p_over]._ofs_cache + scroll_offset + style->get_offset().height - vsep / 2));
+
+ // If there is an area below the submenu item, add an autohide area there.
+ if (items[p_over]._ofs_cache + items[p_over]._height_cache + scroll_offset <= control->get_size().height) {
+ int from = items[p_over]._ofs_cache + items[p_over]._height_cache + scroll_offset + vsep / 2 + style->get_offset().height;
+ submenu_pum->add_autohide_area(Rect2(this_rect.position.x, this_rect.position.y + from, this_rect.size.x, this_rect.size.y - from));
}
}
@@ -810,7 +819,7 @@ void PopupMenu::_notification(int p_what) {
#define ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel) \
item.text = p_label; \
item.xl_text = atr(p_label); \
- item.id = p_id == -1 ? items.size() : p_id; \
+ item.id = p_id == -1 ? items.size() - 1 : p_id; \
item.accel = p_accel;
void PopupMenu::add_item(const String &p_label, int p_id, Key p_accel) {
@@ -892,7 +901,7 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int
_ref_shortcut(p_shortcut); \
item.text = p_shortcut->get_name(); \
item.xl_text = atr(item.text); \
- item.id = p_id == -1 ? items.size() : p_id; \
+ item.id = p_id == -1 ? items.size() - 1 : p_id; \
item.shortcut = p_shortcut; \
item.shortcut_is_global = p_global;
@@ -961,7 +970,7 @@ void PopupMenu::add_submenu_item(const String &p_label, const String &p_submenu,
Item item;
item.text = p_label;
item.xl_text = atr(p_label);
- item.id = p_id == -1 ? items.size() : p_id;
+ item.id = p_id == -1 ? items.size() - 1 : p_id;
item.submenu = p_submenu;
items.push_back(item);
_shape_item(items.size() - 1);
@@ -1747,6 +1756,7 @@ void PopupMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_item_tooltip", "index"), &PopupMenu::get_item_tooltip);
ClassDB::bind_method(D_METHOD("get_item_shortcut", "index"), &PopupMenu::get_item_shortcut);
+ ClassDB::bind_method(D_METHOD("set_current_index", "index"), &PopupMenu::set_current_index);
ClassDB::bind_method(D_METHOD("get_current_index"), &PopupMenu::get_current_index);
ClassDB::bind_method(D_METHOD("set_item_count", "count"), &PopupMenu::set_item_count);
ClassDB::bind_method(D_METHOD("get_item_count"), &PopupMenu::get_item_count);
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index e9d346f943..4865b9770e 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -205,6 +205,49 @@ String RichTextLabel::_letters(int p_num, bool p_capitalize) const {
return s;
}
+void RichTextLabel::_update_line_font(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size) {
+ ERR_FAIL_COND(p_frame == nullptr);
+ ERR_FAIL_COND(p_line < 0 || p_line >= p_frame->lines.size());
+
+ Line &l = p_frame->lines.write[p_line];
+
+ RID t = l.text_buf->get_rid();
+ int spans = TS->shaped_get_span_count(t);
+ for (int i = 0; i < spans; i++) {
+ ItemText *it = (ItemText *)(uint64_t)TS->shaped_get_span_meta(t, i);
+ if (it) {
+ Ref<Font> font = _find_font(it);
+ if (font.is_null()) {
+ font = p_base_font;
+ }
+ int font_size = _find_font_size(it);
+ if (font_size == -1) {
+ font_size = p_base_font_size;
+ }
+ Dictionary font_ftr = _find_font_features(it);
+ TS->shaped_set_span_update_font(t, i, font->get_rids(), font_size, font_ftr);
+ }
+ }
+
+ Item *it_to = (p_line + 1 < p_frame->lines.size()) ? p_frame->lines[p_line + 1].from : nullptr;
+ for (Item *it = l.from; it && it != it_to; it = _get_next_item(it)) {
+ switch (it->type) {
+ case ITEM_TABLE: {
+ ItemTable *table = static_cast<ItemTable *>(it);
+ for (Item *E : table->subitems) {
+ ERR_CONTINUE(E->type != ITEM_FRAME); // Children should all be frames.
+ ItemFrame *frame = static_cast<ItemFrame *>(E);
+ for (int i = 0; i < frame->lines.size(); i++) {
+ _update_line_font(frame, i, p_base_font, p_base_font_size);
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+ }
+}
+
void RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width) {
ERR_FAIL_COND(p_frame == nullptr);
ERR_FAIL_COND(p_line < 0 || p_line >= p_frame->lines.size());
@@ -238,7 +281,8 @@ void RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font>
ERR_CONTINUE(E->type != ITEM_FRAME); // Children should all be frames.
ItemFrame *frame = static_cast<ItemFrame *>(E);
for (int i = 0; i < frame->lines.size(); i++) {
- _resize_line(frame, i, p_base_font, p_base_font_size, 1);
+ int w = _find_margin(frame->lines[i].from, p_base_font, p_base_font_size) + 1;
+ _resize_line(frame, i, p_base_font, p_base_font_size, w);
}
idx++;
}
@@ -254,12 +298,7 @@ void RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font>
for (int i = 0; i < col_count; i++) {
remaining_width -= table->columns[i].min_width;
if (table->columns[i].max_width > table->columns[i].min_width) {
- // If the column can grow, allow it to grow.
table->columns.write[i].expand = true;
- } else {
- // Otherwise make it shrink as much as possible, so that other columns can grow if needs be.
- // We keep the max width as is to spread the remaining space between the columns later.
- table->columns.write[i].min_width = 0;
}
if (table->columns[i].expand) {
total_ratio += table->columns[i].expand_ratio;
@@ -382,9 +421,24 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
Line &l = p_frame->lines.write[p_line];
+ uint16_t autowrap_flags = TextServer::BREAK_MANDATORY;
+ switch (autowrap_mode) {
+ case AUTOWRAP_WORD_SMART:
+ autowrap_flags = TextServer::BREAK_WORD_BOUND_ADAPTIVE | TextServer::BREAK_MANDATORY;
+ break;
+ case AUTOWRAP_WORD:
+ autowrap_flags = TextServer::BREAK_WORD_BOUND | TextServer::BREAK_MANDATORY;
+ break;
+ case AUTOWRAP_ARBITRARY:
+ autowrap_flags = TextServer::BREAK_GRAPHEME_BOUND | TextServer::BREAK_MANDATORY;
+ break;
+ case AUTOWRAP_OFF:
+ break;
+ }
+
// Clear cache.
l.text_buf->clear();
- l.text_buf->set_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_TRIM_EDGE_SPACES);
+ l.text_buf->set_flags(autowrap_flags | TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_WORD_BOUND | TextServer::JUSTIFICATION_TRIM_EDGE_SPACES);
l.char_offset = *r_char_offset;
l.char_count = 0;
@@ -453,7 +507,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
}
remaining_characters -= tx.length();
- l.text_buf->add_string(tx, font, font_size, font_ftr, lang);
+ l.text_buf->add_string(tx, font, font_size, font_ftr, lang, (uint64_t)it);
text += tx;
l.char_count += tx.length();
} break;
@@ -487,7 +541,8 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
int column = idx % col_count;
for (int i = 0; i < frame->lines.size(); i++) {
int char_offset = l.char_offset + l.char_count;
- _shape_line(frame, i, p_base_font, p_base_font_size, 1, &char_offset);
+ int w = _find_margin(frame->lines[i].from, p_base_font, p_base_font_size) + 1;
+ _shape_line(frame, i, p_base_font, p_base_font_size, w, &char_offset);
int cell_ch = (char_offset - (l.char_offset + l.char_count));
l.char_count += cell_ch;
t_char_count += cell_ch;
@@ -507,12 +562,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font>
for (int i = 0; i < col_count; i++) {
remaining_width -= table->columns[i].min_width;
if (table->columns[i].max_width > table->columns[i].min_width) {
- // If the column can grow, allow it to grow.
table->columns.write[i].expand = true;
- } else {
- // Otherwise make it shrink as much as possible, so that other columns can grow if needs be.
- // We keep the max width as is to spread the remaining space between the columns later.
- table->columns.write[i].min_width = 0;
}
if (table->columns[i].expand) {
total_ratio += table->columns[i].expand_ratio;
@@ -1456,7 +1506,10 @@ void RichTextLabel::_notification(int p_what) {
update();
} break;
- case NOTIFICATION_THEME_CHANGED:
+ case NOTIFICATION_THEME_CHANGED: {
+ main->first_invalid_font_line = 0; //invalidate ALL
+ update();
+ } break;
case NOTIFICATION_ENTER_TREE: {
if (!text.is_empty()) {
set_text(text);
@@ -1553,6 +1606,10 @@ Control::CursorShape RichTextLabel::get_cursor_shape(const Point2 &p_pos) const
return get_default_cursor_shape(); //invalid
}
+ if (main->first_invalid_font_line < main->lines.size()) {
+ return get_default_cursor_shape(); //invalid
+ }
+
if (main->first_resized_line < main->lines.size()) {
return get_default_cursor_shape(); //invalid
}
@@ -1577,6 +1634,9 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
if (main->first_invalid_line < main->lines.size()) {
return;
}
+ if (main->first_invalid_font_line < main->lines.size()) {
+ return;
+ }
if (main->first_resized_line < main->lines.size()) {
return;
}
@@ -1740,6 +1800,9 @@ void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
if (main->first_invalid_line < main->lines.size()) {
return;
}
+ if (main->first_invalid_font_line < main->lines.size()) {
+ return;
+ }
if (main->first_resized_line < main->lines.size()) {
return;
}
@@ -2192,6 +2255,18 @@ bool RichTextLabel::_find_layout_subitem(Item *from, Item *to) {
void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) {
if (p_frame->first_invalid_line == p_frame->lines.size()) {
+ Ref<Font> base_font = get_theme_font(SNAME("normal_font"));
+ int base_font_size = get_theme_font_size(SNAME("normal_font_size"));
+
+ // Update fonts.
+ if (p_frame->first_invalid_font_line != p_frame->lines.size()) {
+ for (int i = p_frame->first_invalid_font_line; i < p_frame->lines.size(); i++) {
+ _update_line_font(p_frame, i, base_font, base_font_size);
+ }
+ p_frame->first_resized_line = p_frame->first_invalid_font_line;
+ p_frame->first_invalid_font_line = p_frame->lines.size();
+ }
+
if (p_frame->first_resized_line == p_frame->lines.size()) {
return;
}
@@ -2199,16 +2274,13 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) {
// Resize lines without reshaping.
Rect2 text_rect = _get_text_rect();
- Ref<Font> base_font = get_theme_font(SNAME("normal_font"));
- int base_font_size = get_theme_font_size(SNAME("normal_font_size"));
-
for (int i = p_frame->first_resized_line; i < p_frame->lines.size(); i++) {
_resize_line(p_frame, i, base_font, base_font_size, text_rect.get_size().width - scroll_w);
}
int total_height = 0;
if (p_frame->lines.size()) {
- total_height = p_frame->lines[p_frame->lines.size() - 1].offset.y + p_frame->lines[p_frame->lines.size() - 1].text_buf->get_size().y * p_frame->lines[p_frame->lines.size() - 1].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation"));
+ total_height = p_frame->lines[p_frame->lines.size() - 1].offset.y + p_frame->lines[p_frame->lines.size() - 1].text_buf->get_size().y + p_frame->lines[p_frame->lines.size() - 1].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation"));
}
p_frame->first_resized_line = p_frame->lines.size();
@@ -2245,6 +2317,7 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) {
p_frame->first_invalid_line = p_frame->lines.size();
p_frame->first_resized_line = p_frame->lines.size();
+ p_frame->first_invalid_font_line = p_frame->lines.size();
updating_scroll = true;
vscroll->set_max(total_height);
@@ -3154,7 +3227,7 @@ void RichTextLabel::append_text(const String &p_bbcode) {
indent_level++;
push_list(indent_level, LIST_NUMBERS, false);
pos = brk_end + 1;
- tag_stack.push_front(tag);
+ tag_stack.push_front("ol");
} else if (tag == "ol type=a") {
indent_level++;
push_list(indent_level, LIST_LETTERS, false);
@@ -4019,6 +4092,19 @@ String RichTextLabel::get_language() const {
return language;
}
+void RichTextLabel::set_autowrap_mode(RichTextLabel::AutowrapMode p_mode) {
+ if (autowrap_mode != p_mode) {
+ autowrap_mode = p_mode;
+ main->first_invalid_line = 0; //invalidate ALL
+ _validate_line_caches(main);
+ update();
+ }
+}
+
+RichTextLabel::AutowrapMode RichTextLabel::get_autowrap_mode() const {
+ return autowrap_mode;
+}
+
void RichTextLabel::set_percent_visible(float p_percent) {
if (percent_visible != p_percent) {
if (p_percent < 0 || p_percent >= 1) {
@@ -4066,7 +4152,7 @@ void RichTextLabel::install_effect(const Variant effect) {
int RichTextLabel::get_content_height() const {
int total_height = 0;
if (main->lines.size()) {
- total_height = main->lines[main->lines.size() - 1].offset.y + main->lines[main->lines.size() - 1].text_buf->get_size().y * main->lines[main->lines.size() - 1].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation"));
+ total_height = main->lines[main->lines.size() - 1].offset.y + main->lines[main->lines.size() - 1].text_buf->get_size().y + main->lines[main->lines.size() - 1].text_buf->get_line_count() * get_theme_constant(SNAME("line_separation"));
}
return total_height;
}
@@ -4130,6 +4216,9 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_language", "language"), &RichTextLabel::set_language);
ClassDB::bind_method(D_METHOD("get_language"), &RichTextLabel::get_language);
+ ClassDB::bind_method(D_METHOD("set_autowrap_mode", "autowrap_mode"), &RichTextLabel::set_autowrap_mode);
+ ClassDB::bind_method(D_METHOD("get_autowrap_mode"), &RichTextLabel::get_autowrap_mode);
+
ClassDB::bind_method(D_METHOD("set_meta_underline", "enable"), &RichTextLabel::set_meta_underline);
ClassDB::bind_method(D_METHOD("is_meta_underlined"), &RichTextLabel::is_meta_underlined);
@@ -4222,6 +4311,8 @@ void RichTextLabel::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "autowrap_mode", PROPERTY_HINT_ENUM, "Off,Arbitrary,Word,Word (Smart)"), "set_autowrap_mode", "get_autowrap_mode");
+
ADD_GROUP("Structured Text", "structured_text_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "structured_text_bidi_override", PROPERTY_HINT_ENUM, "Default,URI,File,Email,List,None,Custom"), "set_structured_text_bidi_override", "get_structured_text_bidi_override");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "structured_text_bidi_override_options"), "set_structured_text_bidi_override_options", "get_structured_text_bidi_override_options");
@@ -4230,6 +4321,11 @@ void RichTextLabel::_bind_methods() {
ADD_SIGNAL(MethodInfo("meta_hover_started", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
ADD_SIGNAL(MethodInfo("meta_hover_ended", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
+ BIND_ENUM_CONSTANT(AUTOWRAP_OFF);
+ BIND_ENUM_CONSTANT(AUTOWRAP_ARBITRARY);
+ BIND_ENUM_CONSTANT(AUTOWRAP_WORD);
+ BIND_ENUM_CONSTANT(AUTOWRAP_WORD_SMART);
+
BIND_ENUM_CONSTANT(LIST_NUMBERS);
BIND_ENUM_CONSTANT(LIST_LETTERS);
BIND_ENUM_CONSTANT(LIST_ROMAN);
@@ -4353,7 +4449,7 @@ Size2 RichTextLabel::get_minimum_size() const {
size.x += fixed_width;
}
- if (fixed_width != -1 || fit_content_height) {
+ if (fit_content_height) {
const_cast<RichTextLabel *>(this)->_validate_line_caches(main);
size.y += get_content_height();
}
@@ -4502,6 +4598,7 @@ RichTextLabel::RichTextLabel() {
main->lines.write[0].from = main;
main->first_invalid_line = 0;
main->first_resized_line = 0;
+ main->first_invalid_font_line = 0;
current_frame = main;
vscroll = memnew(VScrollBar);
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 70467e7e7c..e79244f2e4 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -39,6 +39,13 @@ class RichTextLabel : public Control {
GDCLASS(RichTextLabel, Control);
public:
+ enum AutowrapMode {
+ AUTOWRAP_OFF,
+ AUTOWRAP_ARBITRARY,
+ AUTOWRAP_WORD,
+ AUTOWRAP_WORD_SMART
+ };
+
enum ListType {
LIST_NUMBERS,
LIST_LETTERS,
@@ -129,6 +136,7 @@ private:
Vector<Line> lines;
int first_invalid_line = 0;
+ int first_invalid_font_line = 0;
int first_resized_line = 0;
ItemFrame *parent_frame = nullptr;
@@ -345,6 +353,8 @@ private:
VScrollBar *vscroll = nullptr;
+ AutowrapMode autowrap_mode = AUTOWRAP_WORD_SMART;
+
bool scroll_visible = false;
bool scroll_follow = false;
bool scroll_following = false;
@@ -414,6 +424,7 @@ private:
void _shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width, int *r_char_offset);
void _resize_line(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size, int p_width);
+ void _update_line_font(ItemFrame *p_frame, int p_line, const Ref<Font> &p_base_font, int p_base_font_size);
int _draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Color &p_base_color, int p_outline_size, const Color &p_outline_color, const Color &p_font_shadow_color, int p_shadow_outline_size, const Point2 &p_shadow_ofs, int &r_processed_glyphs);
float _find_click_in_line(ItemFrame *p_frame, int p_line, const Vector2 &p_ofs, int p_width, const Point2i &p_click, ItemFrame **r_click_frame = nullptr, int *r_click_line = nullptr, Item **r_click_item = nullptr, int *r_click_char = nullptr);
@@ -572,6 +583,9 @@ public:
void set_language(const String &p_language);
String get_language() const;
+ void set_autowrap_mode(AutowrapMode p_mode);
+ AutowrapMode get_autowrap_mode() const;
+
void set_structured_text_bidi_override(Control::StructuredTextParser p_parser);
Control::StructuredTextParser get_structured_text_bidi_override() const;
@@ -601,6 +615,7 @@ public:
~RichTextLabel();
};
+VARIANT_ENUM_CAST(RichTextLabel::AutowrapMode);
VARIANT_ENUM_CAST(RichTextLabel::ListType);
VARIANT_ENUM_CAST(RichTextLabel::ItemType);
VARIANT_ENUM_CAST(RichTextLabel::VisibleCharactersBehavior);
diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp
index 9da030f0a2..5a551ec5a5 100644
--- a/scene/gui/tab_bar.cpp
+++ b/scene/gui/tab_bar.cpp
@@ -38,48 +38,71 @@
#include "scene/gui/texture_rect.h"
Size2 TabBar::get_minimum_size() const {
+ Size2 ms;
+
+ if (tabs.is_empty()) {
+ return ms;
+ }
+
Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected"));
Ref<StyleBox> tab_selected = get_theme_stylebox(SNAME("tab_selected"));
Ref<StyleBox> tab_disabled = get_theme_stylebox(SNAME("tab_disabled"));
+ Ref<StyleBox> button_highlight = get_theme_stylebox(SNAME("button_highlight"));
+ Ref<Texture2D> close = get_theme_icon(SNAME("close"));
+ int hseparation = get_theme_constant(SNAME("hseparation"));
int y_margin = MAX(MAX(tab_unselected->get_minimum_size().height, tab_selected->get_minimum_size().height), tab_disabled->get_minimum_size().height);
- Size2 ms(0, 0);
-
for (int i = 0; i < tabs.size(); i++) {
- Ref<Texture2D> tex = tabs[i].icon;
- if (tex.is_valid()) {
- ms.height = MAX(ms.height, tex->get_size().height);
- if (!tabs[i].text.is_empty()) {
- ms.width += get_theme_constant(SNAME("hseparation"));
- }
+ if (tabs[i].hidden) {
+ continue;
}
- ms.width += Math::ceil(tabs[i].text_buf->get_size().x);
- ms.height = MAX(ms.height, tabs[i].text_buf->get_size().y + y_margin);
+ int ofs = ms.width;
+ Ref<StyleBox> style;
if (tabs[i].disabled) {
- ms.width += tab_disabled->get_minimum_size().width;
+ style = tab_disabled;
} else if (current == i) {
- ms.width += tab_selected->get_minimum_size().width;
+ style = tab_selected;
} else {
- ms.width += tab_unselected->get_minimum_size().width;
+ style = tab_unselected;
+ }
+ ms.width += style->get_minimum_size().width;
+
+ Ref<Texture2D> tex = tabs[i].icon;
+ if (tex.is_valid()) {
+ ms.height = MAX(ms.height, tex->get_size().height);
+ ms.width += tex->get_size().width + hseparation;
}
+ if (!tabs[i].text.is_empty()) {
+ ms.width += tabs[i].size_text + hseparation;
+ }
+ ms.height = MAX(ms.height, tabs[i].text_buf->get_size().y + y_margin);
+
+ bool close_visible = cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current);
+
if (tabs[i].right_button.is_valid()) {
Ref<Texture2D> rb = tabs[i].right_button;
- Size2 bms = rb->get_size();
- bms.width += get_theme_constant(SNAME("hseparation"));
- ms.width += bms.width;
- ms.height = MAX(bms.height + tab_unselected->get_minimum_size().height, ms.height);
+
+ if (close_visible) {
+ ms.width += button_highlight->get_minimum_size().width + rb->get_width();
+ } else {
+ ms.width += button_highlight->get_margin(SIDE_LEFT) + rb->get_width() + hseparation;
+ }
+
+ ms.height = MAX(rb->get_height() + style->get_minimum_size().height, ms.height);
+ }
+
+ if (close_visible) {
+ ms.width += button_highlight->get_margin(SIDE_LEFT) + close->get_width() + hseparation;
+
+ ms.height = MAX(close->get_height() + style->get_minimum_size().height, ms.height);
}
- if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) {
- Ref<Texture2D> cb = get_theme_icon(SNAME("close"));
- Size2 bms = cb->get_size();
- bms.width += get_theme_constant(SNAME("hseparation"));
- ms.width += bms.width;
- ms.height = MAX(bms.height + tab_unselected->get_minimum_size().height, ms.height);
+ if (ms.width - ofs > style->get_minimum_size().width) {
+ ms.width -= hseparation;
}
}
@@ -165,8 +188,7 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
if (rb_pressing && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
if (rb_hover != -1) {
- // Right mouse button clicked.
- emit_signal(SNAME("tab_rmb_clicked"), rb_hover);
+ emit_signal(SNAME("tab_button_pressed"), rb_hover);
}
rb_pressing = false;
@@ -175,7 +197,6 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
if (cb_pressing && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) {
if (cb_hover != -1) {
- // Close button pressed.
emit_signal(SNAME("tab_close_pressed"), cb_hover);
}
@@ -184,7 +205,6 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
}
if (mb->is_pressed() && (mb->get_button_index() == MouseButton::LEFT || (select_with_rmb && mb->get_button_index() == MouseButton::RIGHT))) {
- // Clicks.
Point2 pos = mb->get_position();
if (buttons_visible) {
@@ -234,6 +254,10 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
int found = -1;
for (int i = offset; i <= max_drawn_tab; i++) {
+ if (tabs[i].hidden) {
+ continue;
+ }
+
if (tabs[i].rb_rect.has_point(pos)) {
rb_pressing = true;
update();
@@ -256,6 +280,12 @@ void TabBar::gui_input(const Ref<InputEvent> &p_event) {
if (found != -1) {
set_current_tab(found);
+
+ if (mb->get_button_index() == MouseButton::RIGHT) {
+ // Right mouse button clicked.
+ emit_signal(SNAME("tab_rmb_clicked"), found);
+ }
+
emit_signal(SNAME("tab_clicked"), found);
}
}
@@ -275,13 +305,12 @@ void TabBar::_shape(int p_tab) {
tabs.write[p_tab].text_buf->set_direction((TextServer::Direction)tabs[p_tab].text_direction);
}
- tabs.write[p_tab].text_buf->add_string(tabs.write[p_tab].xl_text, font, font_size, tabs[p_tab].opentype_features, !tabs[p_tab].language.is_empty() ? tabs[p_tab].language : TranslationServer::get_singleton()->get_tool_locale());
+ tabs.write[p_tab].text_buf->add_string(tabs[p_tab].xl_text, font, font_size, tabs[p_tab].opentype_features, !tabs[p_tab].language.is_empty() ? tabs[p_tab].language : TranslationServer::get_singleton()->get_tool_locale());
}
void TabBar::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: {
- _update_cache();
update();
} break;
case NOTIFICATION_THEME_CHANGED:
@@ -289,14 +318,19 @@ void TabBar::_notification(int p_what) {
for (int i = 0; i < tabs.size(); ++i) {
_shape(i);
}
- _update_cache();
- update_minimum_size();
- update();
- } break;
+
+ [[fallthrough]];
+ }
case NOTIFICATION_RESIZED: {
+ int ofs_old = offset;
+ int max_old = max_drawn_tab;
+
_update_cache();
_ensure_no_over_offset();
- ensure_tab_visible(current);
+
+ if (scroll_to_selected && (offset != ofs_old || max_drawn_tab != max_old)) {
+ ensure_tab_visible(current);
+ }
} break;
case NOTIFICATION_DRAW: {
if (tabs.is_empty()) {
@@ -322,6 +356,10 @@ void TabBar::_notification(int p_what) {
// Draw unselected tabs in the back.
for (int i = offset; i <= max_drawn_tab; i++) {
+ if (tabs[i].hidden) {
+ continue;
+ }
+
if (i != current) {
Ref<StyleBox> sb;
Color col;
@@ -344,14 +382,14 @@ void TabBar::_notification(int p_what) {
}
// Draw selected tab in the front, but only if it's visible.
- if (current >= offset && current <= max_drawn_tab) {
+ if (current >= offset && current <= max_drawn_tab && !tabs[current].hidden) {
Ref<StyleBox> sb = tabs[current].disabled ? tab_disabled : tab_selected;
float x = rtl ? size.width - tabs[current].ofs_cache - tabs[current].size_cache : tabs[current].ofs_cache;
_draw_tab(sb, font_selected_color, current, x);
}
- if (offset > 0 || missing_right) {
+ if (buttons_visible) {
int vofs = (get_size().height - incr->get_size().height) / 2;
if (rtl) {
@@ -386,47 +424,52 @@ void TabBar::_notification(int p_what) {
void TabBar::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_index, float p_x) {
RID ci = get_canvas_item();
+ bool rtl = is_layout_rtl();
Color font_outline_color = get_theme_color(SNAME("font_outline_color"));
int outline_size = get_theme_constant(SNAME("outline_size"));
+ int hseparation = get_theme_constant(SNAME("hseparation"));
- Tab tab = tabs[p_index];
-
- Rect2 sb_rect = Rect2(p_x, 0, tab.size_cache, get_size().height);
+ Rect2 sb_rect = Rect2(p_x, 0, tabs[p_index].size_cache, get_size().height);
p_tab_style->draw(ci, sb_rect);
- p_x += p_tab_style->get_margin(SIDE_LEFT);
+ p_x += rtl ? tabs[p_index].size_cache - p_tab_style->get_margin(SIDE_LEFT) : p_tab_style->get_margin(SIDE_LEFT);
Size2i sb_ms = p_tab_style->get_minimum_size();
- Ref<Texture2D> icon = tab.icon;
+ // Draw the icon.
+ Ref<Texture2D> icon = tabs[p_index].icon;
if (icon.is_valid()) {
- icon->draw(ci, Point2i(p_x, p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2));
+ icon->draw(ci, Point2i(rtl ? p_x - icon->get_width() : p_x, p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2));
- if (!tab.text.is_empty()) {
- p_x += icon->get_width() + get_theme_constant(SNAME("hseparation"));
- }
+ p_x = rtl ? p_x - icon->get_width() - hseparation : p_x + icon->get_width() + hseparation;
}
- Vector2 text_pos = Point2i(p_x, p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tab.text_buf->get_size().y) / 2);
- if (outline_size > 0 && font_outline_color.a > 0) {
- tab.text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color);
- }
- tab.text_buf->draw(ci, text_pos, p_font_color);
+ // Draw the text.
+ if (!tabs[p_index].text.is_empty()) {
+ Point2i text_pos = Point2i(rtl ? p_x - tabs[p_index].size_text : p_x,
+ p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - tabs[p_index].text_buf->get_size().y) / 2);
- p_x += tab.size_text;
+ if (outline_size > 0 && font_outline_color.a > 0) {
+ tabs[p_index].text_buf->draw_outline(ci, text_pos, outline_size, font_outline_color);
+ }
+ tabs[p_index].text_buf->draw(ci, text_pos, p_font_color);
- if (tab.right_button.is_valid()) {
- Ref<StyleBox> style = get_theme_stylebox(SNAME("close_bg_highlight"));
- Ref<Texture2D> rb = tab.right_button;
+ p_x = rtl ? p_x - tabs[p_index].size_text - hseparation : p_x + tabs[p_index].size_text + hseparation;
+ }
- p_x += get_theme_constant(SNAME("hseparation"));
+ // Draw and calculate rect of the right button.
+ if (tabs[p_index].right_button.is_valid()) {
+ Ref<StyleBox> style = get_theme_stylebox(SNAME("button_highlight"));
+ Ref<Texture2D> rb = tabs[p_index].right_button;
Rect2 rb_rect;
rb_rect.size = style->get_minimum_size() + rb->get_size();
- rb_rect.position.x = p_x;
+ rb_rect.position.x = rtl ? p_x - rb_rect.size.width : p_x;
rb_rect.position.y = p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - (rb_rect.size.y)) / 2;
+ tabs.write[p_index].rb_rect = rb_rect;
+
if (rb_hover == p_index) {
if (rb_pressing) {
get_theme_stylebox(SNAME("button_pressed"))->draw(ci, rb_rect);
@@ -435,41 +478,61 @@ void TabBar::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, int p_in
}
}
- rb->draw(ci, Point2i(p_x + style->get_margin(SIDE_LEFT), rb_rect.position.y + style->get_margin(SIDE_TOP)));
- p_x += rb->get_width();
- tabs.write[p_index].rb_rect = rb_rect;
+ rb->draw(ci, Point2i(rb_rect.position.x + style->get_margin(SIDE_LEFT), rb_rect.position.y + style->get_margin(SIDE_TOP)));
+
+ p_x = rtl ? rb_rect.position.x : rb_rect.position.x + rb_rect.size.width;
}
+ // Draw and calculate rect of the close button.
if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && p_index == current)) {
- Ref<StyleBox> style = get_theme_stylebox(SNAME("close_bg_highlight"));
+ Ref<StyleBox> style = get_theme_stylebox(SNAME("button_highlight"));
Ref<Texture2D> cb = get_theme_icon(SNAME("close"));
- p_x += get_theme_constant(SNAME("hseparation"));
-
Rect2 cb_rect;
cb_rect.size = style->get_minimum_size() + cb->get_size();
- cb_rect.position.x = p_x;
+ cb_rect.position.x = rtl ? p_x - cb_rect.size.width : p_x;
cb_rect.position.y = p_tab_style->get_margin(SIDE_TOP) + ((sb_rect.size.y - sb_ms.y) - (cb_rect.size.y)) / 2;
- if (!tab.disabled && cb_hover == p_index) {
+ tabs.write[p_index].cb_rect = cb_rect;
+
+ if (!tabs[p_index].disabled && cb_hover == p_index) {
if (cb_pressing) {
- get_theme_stylebox(SNAME("close_bg_pressed"))->draw(ci, cb_rect);
+ get_theme_stylebox(SNAME("button_pressed"))->draw(ci, cb_rect);
} else {
style->draw(ci, cb_rect);
}
}
- cb->draw(ci, Point2i(p_x + style->get_margin(SIDE_LEFT), cb_rect.position.y + style->get_margin(SIDE_TOP)));
- p_x += cb->get_width();
- tabs.write[p_index].cb_rect = cb_rect;
+ cb->draw(ci, Point2i(cb_rect.position.x + style->get_margin(SIDE_LEFT), cb_rect.position.y + style->get_margin(SIDE_TOP)));
}
}
void TabBar::set_tab_count(int p_count) {
+ if (p_count == tabs.size()) {
+ return;
+ }
+
ERR_FAIL_COND(p_count < 0);
tabs.resize(p_count);
+
+ if (p_count == 0) {
+ offset = 0;
+ max_drawn_tab = 0;
+ current = 0;
+ previous = 0;
+ } else {
+ offset = MIN(offset, p_count - 1);
+ max_drawn_tab = MIN(max_drawn_tab, p_count - 1);
+ current = MIN(current, p_count - 1);
+ }
+
_update_cache();
+ _ensure_no_over_offset();
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
update();
+ update_minimum_size();
notify_property_list_changed();
}
@@ -478,15 +541,26 @@ int TabBar::get_tab_count() const {
}
void TabBar::set_current_tab(int p_current) {
- if (current == p_current) {
- return;
- }
ERR_FAIL_INDEX(p_current, get_tab_count());
previous = current;
current = p_current;
+ if (current == previous) {
+ emit_signal(SNAME("tab_selected"), current);
+ return;
+ }
+ // Triggered by dragging a tab from another TabBar to the selected index, to ensure that tab_changed is emitted.
+ if (previous == -1) {
+ previous = current;
+ }
+
+ emit_signal(SNAME("tab_selected"), current);
+
_update_cache();
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
update();
emit_signal(SNAME("tab_changed"), p_current);
@@ -515,8 +589,13 @@ bool TabBar::get_offset_buttons_visible() const {
void TabBar::set_tab_title(int p_tab, const String &p_title) {
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs.write[p_tab].text = p_title;
+
_shape(p_tab);
_update_cache();
+ _ensure_no_over_offset();
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
update();
update_minimum_size();
}
@@ -529,6 +608,7 @@ String TabBar::get_tab_title(int p_tab) const {
void TabBar::set_tab_text_direction(int p_tab, Control::TextDirection p_text_direction) {
ERR_FAIL_INDEX(p_tab, tabs.size());
ERR_FAIL_COND((int)p_text_direction < -1 || (int)p_text_direction > 3);
+
if (tabs[p_tab].text_direction != p_text_direction) {
tabs.write[p_tab].text_direction = p_text_direction;
_shape(p_tab);
@@ -544,24 +624,38 @@ Control::TextDirection TabBar::get_tab_text_direction(int p_tab) const {
void TabBar::clear_tab_opentype_features(int p_tab) {
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs.write[p_tab].opentype_features.clear();
+
_shape(p_tab);
_update_cache();
+ _ensure_no_over_offset();
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
update();
+ update_minimum_size();
}
void TabBar::set_tab_opentype_feature(int p_tab, const String &p_name, int p_value) {
ERR_FAIL_INDEX(p_tab, tabs.size());
+
int32_t tag = TS->name_to_tag(p_name);
if (!tabs[p_tab].opentype_features.has(tag) || (int)tabs[p_tab].opentype_features[tag] != p_value) {
tabs.write[p_tab].opentype_features[tag] = p_value;
+
_shape(p_tab);
_update_cache();
+ _ensure_no_over_offset();
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
update();
+ update_minimum_size();
}
}
int TabBar::get_tab_opentype_feature(int p_tab, const String &p_name) const {
ERR_FAIL_INDEX_V(p_tab, tabs.size(), -1);
+
int32_t tag = TS->name_to_tag(p_name);
if (!tabs[p_tab].opentype_features.has(tag)) {
return -1;
@@ -571,10 +665,17 @@ int TabBar::get_tab_opentype_feature(int p_tab, const String &p_name) const {
void TabBar::set_tab_language(int p_tab, const String &p_language) {
ERR_FAIL_INDEX(p_tab, tabs.size());
+
if (tabs[p_tab].language != p_language) {
tabs.write[p_tab].language = p_language;
_shape(p_tab);
+ _update_cache();
+ _ensure_no_over_offset();
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
update();
+ update_minimum_size();
}
}
@@ -586,7 +687,12 @@ String TabBar::get_tab_language(int p_tab) const {
void TabBar::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) {
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs.write[p_tab].icon = p_icon;
+
_update_cache();
+ _ensure_no_over_offset();
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
update();
update_minimum_size();
}
@@ -599,7 +705,14 @@ Ref<Texture2D> TabBar::get_tab_icon(int p_tab) const {
void TabBar::set_tab_disabled(int p_tab, bool p_disabled) {
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs.write[p_tab].disabled = p_disabled;
+
+ _update_cache();
+ _ensure_no_over_offset();
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
update();
+ update_minimum_size();
}
bool TabBar::is_tab_disabled(int p_tab) const {
@@ -607,15 +720,38 @@ bool TabBar::is_tab_disabled(int p_tab) const {
return tabs[p_tab].disabled;
}
-void TabBar::set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_button) {
+void TabBar::set_tab_hidden(int p_tab, bool p_hidden) {
+ ERR_FAIL_INDEX(p_tab, tabs.size());
+ tabs.write[p_tab].hidden = p_hidden;
+
+ _update_cache();
+ _ensure_no_over_offset();
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
+ update();
+ update_minimum_size();
+}
+
+bool TabBar::is_tab_hidden(int p_tab) const {
+ ERR_FAIL_INDEX_V(p_tab, tabs.size(), false);
+ return tabs[p_tab].hidden;
+}
+
+void TabBar::set_tab_button_icon(int p_tab, const Ref<Texture2D> &p_icon) {
ERR_FAIL_INDEX(p_tab, tabs.size());
- tabs.write[p_tab].right_button = p_right_button;
+ tabs.write[p_tab].right_button = p_icon;
+
_update_cache();
+ _ensure_no_over_offset();
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
update();
update_minimum_size();
}
-Ref<Texture2D> TabBar::get_tab_right_button(int p_tab) const {
+Ref<Texture2D> TabBar::get_tab_button_icon(int p_tab) const {
ERR_FAIL_INDEX_V(p_tab, tabs.size(), Ref<Texture2D>());
return tabs[p_tab].right_button;
}
@@ -626,34 +762,53 @@ void TabBar::_update_hover() {
}
const Point2 &pos = get_local_mouse_position();
- // test hovering to display right or close button.
+ // Test hovering to display right or close button.
int hover_now = -1;
int hover_buttons = -1;
- for (int i = offset; i < tabs.size(); i++) {
+ for (int i = offset; i <= max_drawn_tab; i++) {
+ if (tabs[i].hidden) {
+ continue;
+ }
+
Rect2 rect = get_tab_rect(i);
if (rect.has_point(pos)) {
hover_now = i;
}
+
if (tabs[i].rb_rect.has_point(pos)) {
rb_hover = i;
cb_hover = -1;
hover_buttons = i;
- break;
} else if (!tabs[i].disabled && tabs[i].cb_rect.has_point(pos)) {
cb_hover = i;
rb_hover = -1;
hover_buttons = i;
+ }
+
+ if (hover_buttons != -1) {
+ update();
break;
}
}
+
if (hover != hover_now) {
hover = hover_now;
- emit_signal(SNAME("tab_hovered"), hover);
+
+ if (hover != -1) {
+ emit_signal(SNAME("tab_hovered"), hover);
+ }
}
if (hover_buttons == -1) { // No hover.
+ int rb_hover_old = rb_hover;
+ int cb_hover_old = cb_hover;
+
rb_hover = hover_buttons;
cb_hover = hover_buttons;
+
+ if (rb_hover != rb_hover_old || cb_hover != cb_hover_old) {
+ update();
+ }
}
}
@@ -677,16 +832,20 @@ void TabBar::_update_cache() {
int count_resize = 0;
for (int i = 0; i < tabs.size(); i++) {
- tabs.write[i].ofs_cache = 0;
- tabs.write[i].size_cache = get_tab_width(i);
tabs.write[i].size_text = Math::ceil(tabs[i].text_buf->get_size().x);
tabs.write[i].text_buf->set_width(-1);
- mw += tabs[i].size_cache;
- if (tabs[i].size_cache <= min_width || i == current) {
- size_fixed += tabs[i].size_cache;
- } else {
- count_resize++;
+ tabs.write[i].ofs_cache = 0;
+ tabs.write[i].size_cache = get_tab_width(i);
+
+ if (!tabs[i].hidden) {
+ mw += tabs[i].size_cache;
+
+ if (tabs[i].size_cache <= min_width || i == current) {
+ size_fixed += tabs[i].size_cache;
+ } else {
+ count_resize++;
+ }
}
}
@@ -696,34 +855,20 @@ void TabBar::_update_cache() {
}
for (int i = offset; i < tabs.size(); i++) {
- Ref<StyleBox> sb;
- if (tabs[i].disabled) {
- sb = tab_disabled;
- } else if (i == current) {
- sb = tab_selected;
- } else {
- sb = tab_unselected;
+ if (tabs[i].hidden) {
+ tabs.write[i].ofs_cache = w;
+ max_drawn_tab = i;
+
+ continue;
}
int lsize = tabs[i].size_cache;
int slen = tabs[i].size_text;
- if (min_width > 0 && mw > limit_minus_buttons && i != current) {
- if (lsize > m_width) {
- slen = m_width - (sb->get_margin(SIDE_LEFT) + sb->get_margin(SIDE_RIGHT));
- if (tabs[i].icon.is_valid()) {
- slen -= tabs[i].icon->get_width();
- slen -= get_theme_constant(SNAME("hseparation"));
- }
- if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) {
- Ref<Texture2D> cb = get_theme_icon(SNAME("close"));
- slen -= cb->get_width();
- slen -= get_theme_constant(SNAME("hseparation"));
- }
-
- slen = MAX(slen, 1);
- lsize = m_width;
- }
+ // FIXME: This is completely broken.
+ if (min_width > 0 && (mw > limit || (offset > 0 && mw > limit_minus_buttons)) && i != current && lsize > m_width) {
+ slen = MAX(m_width - tabs[i].size_cache + tabs[i].size_text, 1);
+ lsize = m_width;
}
tabs.write[i].ofs_cache = w;
@@ -735,13 +880,22 @@ void TabBar::_update_cache() {
max_drawn_tab = i;
// Check if all tabs would fit inside the area.
- if (i > offset && (w > limit || (offset > 0 && w > limit_minus_buttons))) {
- w -= get_tab_width(i);
- max_drawn_tab -= 1;
+ if (clip_tabs && i > offset && (w > limit || (offset > 0 && w > limit_minus_buttons))) {
+ tabs.write[i].ofs_cache = 0;
+ tabs.write[i].text_buf->set_width(-1);
+
+ w -= tabs[i].size_cache;
+ max_drawn_tab--;
while (w > limit_minus_buttons && max_drawn_tab > offset) {
- w -= get_tab_width(max_drawn_tab);
- max_drawn_tab -= 1;
+ tabs.write[max_drawn_tab].ofs_cache = 0;
+
+ if (!tabs[max_drawn_tab].hidden) {
+ tabs.write[max_drawn_tab].text_buf->set_width(-1);
+ w -= tabs[max_drawn_tab].size_cache;
+ }
+
+ max_drawn_tab--;
}
break;
@@ -752,21 +906,25 @@ void TabBar::_update_cache() {
buttons_visible = offset > 0 || missing_right;
if (tab_alignment == ALIGNMENT_LEFT) {
+ _update_hover();
return;
- } else if (tab_alignment == ALIGNMENT_CENTER) {
+ }
+
+ if (tab_alignment == ALIGNMENT_CENTER) {
w = ((buttons_visible ? limit_minus_buttons : limit) - w) / 2;
} else if (tab_alignment == ALIGNMENT_RIGHT) {
w = (buttons_visible ? limit_minus_buttons : limit) - w;
}
- if (w < 0) {
- w = 0;
- }
-
for (int i = offset; i <= max_drawn_tab; i++) {
tabs.write[i].ofs_cache = w;
- w += tabs.write[i].size_cache;
+
+ if (!tabs[i].hidden) {
+ w += tabs[i].size_cache;
+ }
}
+
+ _update_hover();
}
void TabBar::_on_mouse_exited() {
@@ -784,20 +942,26 @@ void TabBar::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) {
t.text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR);
t.text_buf->add_string(t.xl_text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), Dictionary(), TranslationServer::get_singleton()->get_tool_locale());
t.icon = p_icon;
-
tabs.push_back(t);
+
_update_cache();
- call_deferred(SNAME("_update_hover"));
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
update();
update_minimum_size();
}
void TabBar::clear_tabs() {
tabs.clear();
+ offset = 0;
+ max_drawn_tab = 0;
current = 0;
previous = 0;
- call_deferred(SNAME("_update_hover"));
+
+ _update_cache();
update();
+ update_minimum_size();
notify_property_list_changed();
}
@@ -807,10 +971,6 @@ void TabBar::remove_tab(int p_idx) {
if (current >= p_idx) {
current--;
}
- _update_cache();
- call_deferred(SNAME("_update_hover"));
- update();
- update_minimum_size();
if (current < 0) {
current = 0;
@@ -820,7 +980,13 @@ void TabBar::remove_tab(int p_idx) {
current = tabs.size() - 1;
}
+ _update_cache();
_ensure_no_over_offset();
+ if (scroll_to_selected && !tabs.is_empty()) {
+ ensure_tab_visible(current);
+ }
+ update();
+ update_minimum_size();
notify_property_list_changed();
}
@@ -840,15 +1006,13 @@ Variant TabBar::get_drag_data(const Point2 &p_point) {
if (!tabs[tab_over].icon.is_null()) {
TextureRect *tf = memnew(TextureRect);
tf->set_texture(tabs[tab_over].icon);
+ tf->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
drag_preview->add_child(tf);
}
+
Label *label = memnew(Label(tabs[tab_over].xl_text));
drag_preview->add_child(label);
- if (!tabs[tab_over].right_button.is_null()) {
- TextureRect *tf = memnew(TextureRect);
- tf->set_texture(tabs[tab_over].right_button);
- drag_preview->add_child(tf);
- }
+
set_drag_preview(drag_preview);
Dictionary drag_data;
@@ -901,31 +1065,40 @@ void TabBar::drop_data(const Point2 &p_point, const Variant &p_data) {
int tab_from_id = d["tab_element"];
NodePath from_path = d["from_path"];
NodePath to_path = get_path();
+
if (from_path == to_path) {
if (hover_now < 0) {
hover_now = get_tab_count() - 1;
}
+
move_tab(tab_from_id, hover_now);
emit_signal(SNAME("active_tab_rearranged"), hover_now);
set_current_tab(hover_now);
} else if (get_tabs_rearrange_group() != -1) {
// Drag and drop between Tabs.
+
Node *from_node = get_node(from_path);
TabBar *from_tabs = Object::cast_to<TabBar>(from_node);
+
if (from_tabs && from_tabs->get_tabs_rearrange_group() == get_tabs_rearrange_group()) {
if (tab_from_id >= from_tabs->get_tab_count()) {
return;
}
+
Tab moving_tab = from_tabs->tabs[tab_from_id];
if (hover_now < 0) {
hover_now = get_tab_count();
}
+
+ // Workaround to ensure that tab_changed is emitted.
+ if (current == hover_now) {
+ current = -1;
+ }
+
tabs.insert(hover_now, moving_tab);
from_tabs->remove_tab(tab_from_id);
set_current_tab(hover_now);
- emit_signal(SNAME("tab_changed"), hover_now);
- _update_cache();
- update();
+ update_minimum_size();
}
}
}
@@ -946,6 +1119,7 @@ int TabBar::get_tab_idx_at_point(const Point2 &p_point) const {
void TabBar::set_tab_alignment(AlignmentMode p_alignment) {
ERR_FAIL_INDEX(p_alignment, ALIGNMENT_MAX);
tab_alignment = p_alignment;
+
_update_cache();
update();
}
@@ -959,7 +1133,16 @@ void TabBar::set_clip_tabs(bool p_clip_tabs) {
return;
}
clip_tabs = p_clip_tabs;
+
+ if (!clip_tabs) {
+ offset = 0;
+ max_drawn_tab = 0;
+ }
+
_update_cache();
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
update();
update_minimum_size();
}
@@ -981,6 +1164,10 @@ void TabBar::move_tab(int from, int to) {
tabs.insert(to, tab_from);
_update_cache();
+ _ensure_no_over_offset();
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
update();
notify_property_list_changed();
}
@@ -991,37 +1178,49 @@ int TabBar::get_tab_width(int p_idx) const {
Ref<StyleBox> tab_unselected = get_theme_stylebox(SNAME("tab_unselected"));
Ref<StyleBox> tab_selected = get_theme_stylebox(SNAME("tab_selected"));
Ref<StyleBox> tab_disabled = get_theme_stylebox(SNAME("tab_disabled"));
+ int hseparation = get_theme_constant(SNAME("hseparation"));
- int x = 0;
+ Ref<StyleBox> style;
+
+ if (tabs[p_idx].disabled) {
+ style = tab_disabled;
+ } else if (current == p_idx) {
+ style = tab_selected;
+ } else {
+ style = tab_unselected;
+ }
+ int x = style->get_minimum_size().width;
Ref<Texture2D> tex = tabs[p_idx].icon;
if (tex.is_valid()) {
- x += tex->get_width();
- if (!tabs[p_idx].text.is_empty()) {
- x += get_theme_constant(SNAME("hseparation"));
- }
+ x += tex->get_width() + hseparation;
}
- x += Math::ceil(tabs[p_idx].text_buf->get_size().x);
-
- if (tabs[p_idx].disabled) {
- x += tab_disabled->get_minimum_size().width;
- } else if (current == p_idx) {
- x += tab_selected->get_minimum_size().width;
- } else {
- x += tab_unselected->get_minimum_size().width;
+ if (!tabs[p_idx].text.is_empty()) {
+ x += tabs[p_idx].size_text + hseparation;
}
+ bool close_visible = cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && p_idx == current);
+
if (tabs[p_idx].right_button.is_valid()) {
+ Ref<StyleBox> btn_style = get_theme_stylebox(SNAME("button_highlight"));
Ref<Texture2D> rb = tabs[p_idx].right_button;
- x += rb->get_width();
- x += get_theme_constant(SNAME("hseparation"));
+
+ if (close_visible) {
+ x += btn_style->get_minimum_size().width + rb->get_width();
+ } else {
+ x += btn_style->get_margin(SIDE_LEFT) + rb->get_width() + hseparation;
+ }
}
- if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && p_idx == current)) {
+ if (close_visible) {
+ Ref<StyleBox> btn_style = get_theme_stylebox(SNAME("button_highlight"));
Ref<Texture2D> cb = get_theme_icon(SNAME("close"));
- x += cb->get_width();
- x += get_theme_constant(SNAME("hseparation"));
+ x += btn_style->get_margin(SIDE_LEFT) + cb->get_width() + hseparation;
+ }
+
+ if (x > style->get_minimum_size().width) {
+ x -= hseparation;
}
return x;
@@ -1039,8 +1238,12 @@ void TabBar::_ensure_no_over_offset() {
int prev_offset = offset;
int total_w = tabs[max_drawn_tab].ofs_cache + tabs[max_drawn_tab].size_cache - tabs[offset].ofs_cache;
- while (offset > 0) {
- total_w += tabs[offset - 1].size_cache;
+ for (int i = offset; i > 0; i--) {
+ if (tabs[i - 1].hidden) {
+ continue;
+ }
+
+ total_w += tabs[i - 1].size_cache;
if (total_w < limit_minus_buttons) {
offset--;
@@ -1061,7 +1264,7 @@ void TabBar::ensure_tab_visible(int p_idx) {
}
ERR_FAIL_INDEX(p_idx, tabs.size());
- if (p_idx >= offset && p_idx <= max_drawn_tab) {
+ if (tabs[p_idx].hidden || (p_idx >= offset && p_idx <= max_drawn_tab)) {
return;
}
@@ -1079,12 +1282,20 @@ void TabBar::ensure_tab_visible(int p_idx) {
int total_w = tabs[max_drawn_tab].ofs_cache - tabs[offset].ofs_cache;
for (int i = max_drawn_tab; i <= p_idx; i++) {
+ if (tabs[i].hidden) {
+ continue;
+ }
+
total_w += tabs[i].size_cache;
}
int prev_offset = offset;
for (int i = offset; i < p_idx; i++) {
+ if (tabs[i].hidden) {
+ continue;
+ }
+
if (total_w > limit_minus_buttons) {
total_w -= tabs[i].size_cache;
offset++;
@@ -1111,8 +1322,14 @@ Rect2 TabBar::get_tab_rect(int p_tab) const {
void TabBar::set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy) {
ERR_FAIL_INDEX(p_policy, CLOSE_BUTTON_MAX);
cb_displaypolicy = p_policy;
+
_update_cache();
+ _ensure_no_over_offset();
+ if (scroll_to_selected) {
+ ensure_tab_visible(current);
+ }
update();
+ update_minimum_size();
}
TabBar::CloseButtonDisplayPolicy TabBar::get_tab_close_display_policy() const {
@@ -1147,6 +1364,17 @@ int TabBar::get_tabs_rearrange_group() const {
return tabs_rearrange_group;
}
+void TabBar::set_scroll_to_selected(bool p_enabled) {
+ scroll_to_selected = p_enabled;
+ if (p_enabled) {
+ ensure_tab_visible(current);
+ }
+}
+
+bool TabBar::get_scroll_to_selected() const {
+ return scroll_to_selected;
+}
+
void TabBar::set_select_with_rmb(bool p_enabled) {
select_with_rmb = p_enabled;
}
@@ -1225,8 +1453,12 @@ void TabBar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tab_language", "tab_idx"), &TabBar::get_tab_language);
ClassDB::bind_method(D_METHOD("set_tab_icon", "tab_idx", "icon"), &TabBar::set_tab_icon);
ClassDB::bind_method(D_METHOD("get_tab_icon", "tab_idx"), &TabBar::get_tab_icon);
+ ClassDB::bind_method(D_METHOD("set_tab_button_icon", "tab_idx", "icon"), &TabBar::set_tab_button_icon);
+ ClassDB::bind_method(D_METHOD("get_tab_button_icon", "tab_idx"), &TabBar::get_tab_button_icon);
ClassDB::bind_method(D_METHOD("set_tab_disabled", "tab_idx", "disabled"), &TabBar::set_tab_disabled);
ClassDB::bind_method(D_METHOD("is_tab_disabled", "tab_idx"), &TabBar::is_tab_disabled);
+ ClassDB::bind_method(D_METHOD("set_tab_hidden", "tab_idx", "hidden"), &TabBar::set_tab_hidden);
+ ClassDB::bind_method(D_METHOD("is_tab_hidden", "tab_idx"), &TabBar::is_tab_hidden);
ClassDB::bind_method(D_METHOD("remove_tab", "tab_idx"), &TabBar::remove_tab);
ClassDB::bind_method(D_METHOD("add_tab", "title", "icon"), &TabBar::add_tab, DEFVAL(""), DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("set_tab_alignment", "alignment"), &TabBar::set_tab_alignment);
@@ -1246,16 +1478,19 @@ void TabBar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_drag_to_rearrange_enabled"), &TabBar::get_drag_to_rearrange_enabled);
ClassDB::bind_method(D_METHOD("set_tabs_rearrange_group", "group_id"), &TabBar::set_tabs_rearrange_group);
ClassDB::bind_method(D_METHOD("get_tabs_rearrange_group"), &TabBar::get_tabs_rearrange_group);
-
+ ClassDB::bind_method(D_METHOD("set_scroll_to_selected", "enabled"), &TabBar::set_scroll_to_selected);
+ ClassDB::bind_method(D_METHOD("get_scroll_to_selected"), &TabBar::get_scroll_to_selected);
ClassDB::bind_method(D_METHOD("set_select_with_rmb", "enabled"), &TabBar::set_select_with_rmb);
ClassDB::bind_method(D_METHOD("get_select_with_rmb"), &TabBar::get_select_with_rmb);
+ ADD_SIGNAL(MethodInfo("tab_selected", PropertyInfo(Variant::INT, "tab")));
ADD_SIGNAL(MethodInfo("tab_changed", PropertyInfo(Variant::INT, "tab")));
+ ADD_SIGNAL(MethodInfo("tab_clicked", PropertyInfo(Variant::INT, "tab")));
ADD_SIGNAL(MethodInfo("tab_rmb_clicked", PropertyInfo(Variant::INT, "tab")));
ADD_SIGNAL(MethodInfo("tab_close_pressed", PropertyInfo(Variant::INT, "tab")));
+ ADD_SIGNAL(MethodInfo("tab_button_pressed", PropertyInfo(Variant::INT, "tab")));
ADD_SIGNAL(MethodInfo("tab_hovered", PropertyInfo(Variant::INT, "tab")));
ADD_SIGNAL(MethodInfo("active_tab_rearranged", PropertyInfo(Variant::INT, "idx_to")));
- ADD_SIGNAL(MethodInfo("tab_clicked", PropertyInfo(Variant::INT, "tab")));
ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1", PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab");
ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_alignment", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_tab_alignment", "get_tab_alignment");
@@ -1263,6 +1498,8 @@ void TabBar::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_close_display_policy", PROPERTY_HINT_ENUM, "Show Never,Show Active Only,Show Always"), "set_tab_close_display_policy", "get_tab_close_display_policy");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scrolling_enabled"), "set_scrolling_enabled", "get_scrolling_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_to_selected"), "set_scroll_to_selected", "get_scroll_to_selected");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "select_with_rmb"), "set_select_with_rmb", "get_select_with_rmb");
ADD_ARRAY_COUNT("Tabs", "tab_count", "set_tab_count", "get_tab_count", "tab_");
@@ -1278,5 +1515,6 @@ void TabBar::_bind_methods() {
}
TabBar::TabBar() {
+ set_size(Size2(get_size().width, get_minimum_size().height));
connect("mouse_exited", callable_mp(this, &TabBar::_on_mouse_exited));
}
diff --git a/scene/gui/tab_bar.h b/scene/gui/tab_bar.h
index d0055ae4d2..b428538570 100644
--- a/scene/gui/tab_bar.h
+++ b/scene/gui/tab_bar.h
@@ -63,12 +63,11 @@ private:
Ref<TextLine> text_buf;
Ref<Texture2D> icon;
- int ofs_cache = 0;
bool disabled = false;
+ bool hidden = false;
+ int ofs_cache = 0;
int size_cache = 0;
int size_text = 0;
- int x_cache = 0;
- int x_size_cache = 0;
Ref<Texture2D> right_button;
Rect2 rb_rect;
@@ -102,6 +101,7 @@ private:
int min_width = 0;
bool scrolling_enabled = true;
bool drag_to_rearrange_enabled = false;
+ bool scroll_to_selected = true;
int tabs_rearrange_group = -1;
int get_tab_width(int p_idx) const;
@@ -150,8 +150,11 @@ public:
void set_tab_disabled(int p_tab, bool p_disabled);
bool is_tab_disabled(int p_tab) const;
- void set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_button);
- Ref<Texture2D> get_tab_right_button(int p_tab) const;
+ void set_tab_hidden(int p_tab, bool p_hidden);
+ bool is_tab_hidden(int p_tab) const;
+
+ void set_tab_button_icon(int p_tab, const Ref<Texture2D> &p_icon);
+ Ref<Texture2D> get_tab_button_icon(int p_tab) const;
void set_tab_alignment(AlignmentMode p_alignment);
AlignmentMode get_tab_alignment() const;
@@ -187,6 +190,9 @@ public:
void set_tabs_rearrange_group(int p_group_id);
int get_tabs_rearrange_group() const;
+ void set_scroll_to_selected(bool p_enabled);
+ bool get_scroll_to_selected() const;
+
void set_select_with_rmb(bool p_enabled);
bool get_select_with_rmb() const;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index fe1aaab557..0ee4a6af4e 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -187,29 +187,44 @@ void TextEdit::Text::_calculate_max_line_width() {
max_width = width;
}
-void TextEdit::Text::invalidate_cache(int p_line, int p_column, const String &p_ime_text, const Array &p_bidi_override) {
+void TextEdit::Text::invalidate_cache(int p_line, int p_column, bool p_text_changed, const String &p_ime_text, const Array &p_bidi_override) {
ERR_FAIL_INDEX(p_line, text.size());
if (font.is_null() || font_size <= 0) {
return; // Not in tree?
}
- text.write[p_line].data_buf->clear();
+ if (p_text_changed) {
+ text.write[p_line].data_buf->clear();
+ }
+
text.write[p_line].data_buf->set_width(width);
text.write[p_line].data_buf->set_direction((TextServer::Direction)direction);
text.write[p_line].data_buf->set_preserve_control(draw_control_chars);
if (p_ime_text.length() > 0) {
- text.write[p_line].data_buf->add_string(p_ime_text, font, font_size, opentype_features, language);
+ if (p_text_changed) {
+ text.write[p_line].data_buf->add_string(p_ime_text, font, font_size, opentype_features, language);
+ }
if (!p_bidi_override.is_empty()) {
TS->shaped_text_set_bidi_override(text.write[p_line].data_buf->get_rid(), p_bidi_override);
}
} else {
- text.write[p_line].data_buf->add_string(text[p_line].data, font, font_size, opentype_features, language);
+ if (p_text_changed) {
+ text.write[p_line].data_buf->add_string(text[p_line].data, font, font_size, opentype_features, language);
+ }
if (!text[p_line].bidi_override.is_empty()) {
TS->shaped_text_set_bidi_override(text.write[p_line].data_buf->get_rid(), text[p_line].bidi_override);
}
}
+ if (!p_text_changed) {
+ RID r = text.write[p_line].data_buf->get_rid();
+ int spans = TS->shaped_get_span_count(r);
+ for (int i = 0; i < spans; i++) {
+ TS->shaped_set_span_update_font(r, i, font->get_rids(), font_size, opentype_features);
+ }
+ }
+
// Apply tab align.
if (tab_size > 0) {
Vector<float> tabs;
@@ -266,6 +281,24 @@ void TextEdit::Text::invalidate_all_lines() {
}
}
+void TextEdit::Text::invalidate_font() {
+ if (!is_dirty) {
+ return;
+ }
+
+ max_width = -1;
+ line_height = -1;
+
+ if (!font.is_null() && font_size > 0) {
+ font_height = font->get_height(font_size);
+ }
+
+ for (int i = 0; i < text.size(); i++) {
+ invalidate_cache(i, -1, false);
+ }
+ is_dirty = false;
+}
+
void TextEdit::Text::invalidate_all() {
if (!is_dirty) {
return;
@@ -279,7 +312,7 @@ void TextEdit::Text::invalidate_all() {
}
for (int i = 0; i < text.size(); i++) {
- invalidate_cache(i);
+ invalidate_cache(i, -1, true);
}
is_dirty = false;
}
@@ -294,7 +327,7 @@ void TextEdit::Text::clear() {
line.gutters.resize(gutter_count);
line.data = "";
text.insert(0, line);
- invalidate_cache(0);
+ invalidate_cache(0, -1, true);
}
int TextEdit::Text::get_max_width() const {
@@ -306,7 +339,7 @@ void TextEdit::Text::set(int p_line, const String &p_text, const Array &p_bidi_o
text.write[p_line].data = p_text;
text.write[p_line].bidi_override = p_bidi_override;
- invalidate_cache(p_line);
+ invalidate_cache(p_line, -1, true);
}
void TextEdit::Text::insert(int p_at, const Vector<String> &p_text, const Vector<Array> &p_bidi_override) {
@@ -331,7 +364,7 @@ void TextEdit::Text::insert(int p_at, const Vector<String> &p_text, const Vector
line.data = p_text[i];
line.bidi_override = p_bidi_override[i];
text.write[p_at + i] = line;
- invalidate_cache(p_at + i);
+ invalidate_cache(p_at + i, -1, true);
}
}
@@ -650,7 +683,7 @@ void TextEdit::_notification(int p_what) {
}
}
- bool draw_placeholder = text[0].length() == 0;
+ bool draw_placeholder = text.size() == 1 && text[0].length() == 0;
// Get the highlighted words.
String highlighted_text = get_selected_text();
@@ -874,7 +907,7 @@ void TextEdit::_notification(int p_what) {
// Ensure we at least use the font color.
Color current_color = !editable ? font_readonly_color : font_color;
if (draw_placeholder) {
- current_color.a *= placeholder_alpha;
+ current_color = font_placeholder_color;
}
const Ref<TextParagraph> ldata = draw_placeholder ? placeholder_data_buf : text.get_line_data(line);
@@ -1446,9 +1479,11 @@ void TextEdit::_notification(int p_what) {
DisplayServer::get_singleton()->window_set_ime_position(Point2(), get_viewport()->get_window_id());
DisplayServer::get_singleton()->window_set_ime_active(false, get_viewport()->get_window_id());
}
- ime_text = "";
- ime_selection = Point2();
- text.invalidate_cache(caret.line, caret.column, ime_text);
+ if (!ime_text.is_empty()) {
+ ime_text = "";
+ ime_selection = Point2();
+ text.invalidate_cache(caret.line, caret.column, true, ime_text);
+ }
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
DisplayServer::get_singleton()->virtual_keyboard_hide();
@@ -1470,7 +1505,7 @@ void TextEdit::_notification(int p_what) {
t = ime_text;
}
- text.invalidate_cache(caret.line, caret.column, t, structured_text_parser(st_parser, st_args, t));
+ text.invalidate_cache(caret.line, caret.column, true, t, structured_text_parser(st_parser, st_args, t));
update();
}
} break;
@@ -2515,6 +2550,7 @@ void TextEdit::_update_caches() {
font_size = get_theme_font_size(SNAME("font_size"));
font_color = get_theme_color(SNAME("font_color"));
font_readonly_color = get_theme_color(SNAME("font_readonly_color"));
+ font_placeholder_color = get_theme_color(SNAME("font_placeholder_color"));
outline_size = get_theme_constant(SNAME("outline_size"));
outline_color = get_theme_color(SNAME("font_outline_color"));
@@ -2537,7 +2573,7 @@ void TextEdit::_update_caches() {
text.set_draw_control_chars(draw_control_chars);
text.set_font(font);
text.set_font_size(font_size);
- text.invalidate_all();
+ text.invalidate_font();
_update_placeholder();
/* Syntax highlighting. */
@@ -2717,7 +2753,7 @@ void TextEdit::set_text_direction(Control::TextDirection p_text_direction) {
dir = (TextServer::Direction)text_direction;
}
text.set_direction_and_language(dir, (!language.is_empty()) ? language : TranslationServer::get_singleton()->get_tool_locale());
- text.invalidate_all();
+ text.invalidate_font();
_update_placeholder();
if (menu_dir) {
@@ -2739,7 +2775,7 @@ void TextEdit::set_opentype_feature(const String &p_name, int p_value) {
if (!opentype_features.has(tag) || (int)opentype_features[tag] != p_value) {
opentype_features[tag] = p_value;
text.set_font_features(opentype_features);
- text.invalidate_all();
+ text.invalidate_font();
_update_placeholder();
update();
}
@@ -2756,7 +2792,7 @@ int TextEdit::get_opentype_feature(const String &p_name) const {
void TextEdit::clear_opentype_features() {
opentype_features.clear();
text.set_font_features(opentype_features);
- text.invalidate_all();
+ text.invalidate_font();
_update_placeholder();
update();
}
@@ -2947,15 +2983,6 @@ String TextEdit::get_placeholder() const {
return placeholder_text;
}
-void TextEdit::set_placeholder_alpha(float p_alpha) {
- placeholder_alpha = p_alpha;
- update();
-}
-
-float TextEdit::get_placeholder_alpha() const {
- return placeholder_alpha;
-}
-
void TextEdit::set_line(int p_line, const String &p_new_text) {
if (p_line < 0 || p_line >= text.size()) {
return;
@@ -4860,7 +4887,7 @@ void TextEdit::set_draw_control_chars(bool p_enabled) {
menu->set_item_checked(menu->get_item_index(MENU_DISPLAY_UCC), draw_control_chars);
}
text.set_draw_control_chars(draw_control_chars);
- text.invalidate_all();
+ text.invalidate_font();
_update_placeholder();
update();
}
@@ -4944,9 +4971,6 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_placeholder", "text"), &TextEdit::set_placeholder);
ClassDB::bind_method(D_METHOD("get_placeholder"), &TextEdit::get_placeholder);
- ClassDB::bind_method(D_METHOD("set_placeholder_alpha", "alpha"), &TextEdit::set_placeholder_alpha);
- ClassDB::bind_method(D_METHOD("get_placeholder_alpha"), &TextEdit::get_placeholder_alpha);
-
ClassDB::bind_method(D_METHOD("set_line", "line", "new_text"), &TextEdit::set_line);
ClassDB::bind_method(D_METHOD("get_line", "line"), &TextEdit::get_line);
@@ -5256,7 +5280,6 @@ void TextEdit::_bind_methods() {
/* Inspector */
ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "placeholder_text", PROPERTY_HINT_MULTILINE_TEXT), "set_placeholder", "get_placeholder");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "placeholder_alpha", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_placeholder_alpha", "get_placeholder_alpha");
ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "language", PROPERTY_HINT_LOCALE_ID, ""), "set_language", "get_language");
@@ -5331,7 +5354,7 @@ bool TextEdit::_set(const StringName &p_name, const Variant &p_value) {
if (opentype_features.has(tag)) {
opentype_features.erase(tag);
text.set_font_features(opentype_features);
- text.invalidate_all();
+ text.invalidate_font();
_update_placeholder();
update();
}
@@ -5339,7 +5362,7 @@ bool TextEdit::_set(const StringName &p_name, const Variant &p_value) {
if (!opentype_features.has(tag) || (int)opentype_features[tag] != value) {
opentype_features[tag] = value;
text.set_font_features(opentype_features);
- text.invalidate_all();
+ text.invalidate_font();
_update_placeholder();
update();
}
@@ -6020,7 +6043,7 @@ void TextEdit::_update_scrollbars() {
h_scroll->set_begin(Point2(0, size.height - hmin.height));
h_scroll->set_end(Point2(size.width - vmin.width, size.height));
- bool draw_placeholder = text[0].length() == 0;
+ bool draw_placeholder = text.size() == 1 && text[0].length() == 0;
int visible_rows = get_visible_line_count();
int total_rows = draw_placeholder ? placeholder_wraped_rows.size() - 1 : get_total_visible_line_count();
@@ -6101,7 +6124,7 @@ void TextEdit::_scroll_moved(double p_to_val) {
}
if (v_scroll->is_visible_in_tree()) {
// Set line ofs and wrap ofs.
- bool draw_placeholder = text[0].length() == 0;
+ bool draw_placeholder = text.size() == 1 && text[0].length() == 0;
int v_scroll_i = floor(get_v_scroll());
int sc = 0;
@@ -6116,7 +6139,7 @@ void TextEdit::_scroll_moved(double p_to_val) {
}
}
n_line = MIN(n_line, text.size() - 1);
- int line_wrap_amount = (text[0].length() == 0) ? placeholder_wraped_rows.size() - 1 : get_line_wrap_count(n_line);
+ int line_wrap_amount = draw_placeholder ? placeholder_wraped_rows.size() - 1 : get_line_wrap_count(n_line);
int wi = line_wrap_amount - (sc - v_scroll_i - 1);
wi = CLAMP(wi, 0, line_wrap_amount);
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index fdaa928598..83a63ae40a 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -210,7 +210,8 @@ private:
int size() const { return text.size(); }
void clear();
- void invalidate_cache(int p_line, int p_column = -1, const String &p_ime_text = String(), const Array &p_bidi_override = Array());
+ void invalidate_cache(int p_line, int p_column = -1, bool p_text_changed = false, const String &p_ime_text = String(), const Array &p_bidi_override = Array());
+ void invalidate_font();
void invalidate_all();
void invalidate_all_lines();
@@ -251,8 +252,6 @@ private:
Point2 ime_selection;
// Placeholder
- float placeholder_alpha = 0.6;
-
String placeholder_text = "";
Array placeholder_bidi_override;
Ref<TextParagraph> placeholder_data_buf;
@@ -525,6 +524,7 @@ private:
int font_size = 16;
Color font_color = Color(1, 1, 1);
Color font_readonly_color = Color(1, 1, 1);
+ Color font_placeholder_color = Color(1, 1, 1, 0.6);
int outline_size = 0;
Color outline_color = Color(1, 1, 1);
@@ -684,9 +684,6 @@ public:
void set_placeholder(const String &p_text);
String get_placeholder() const;
- void set_placeholder_alpha(float p_alpha);
- float get_placeholder_alpha() const;
-
void set_line(int p_line, const String &p_new_text);
String get_line(int p_line) const;
diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp
index da202c1c8f..89a17ae854 100644
--- a/scene/gui/texture_button.cpp
+++ b/scene/gui/texture_button.cpp
@@ -173,7 +173,8 @@ void TextureButton::_notification(int p_what) {
bool draw_focus = (has_focus() && focused.is_valid());
// If no other texture is valid, try using focused texture.
- if (!texdraw.is_valid() && draw_focus) {
+ bool draw_focus_only = draw_focus && !texdraw.is_valid();
+ if (draw_focus_only) {
texdraw = focused;
}
@@ -232,7 +233,7 @@ void TextureButton::_notification(int p_what) {
size.width *= hflip ? -1.0f : 1.0f;
size.height *= vflip ? -1.0f : 1.0f;
- if (texdraw == focused) {
+ if (draw_focus_only) {
// Do nothing, we only needed to calculate the rectangle.
} else if (_tile) {
draw_texture_rect(texdraw, Rect2(ofs, size), _tile);
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index e75d147134..1b32884880 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -555,8 +555,9 @@ void TreeItem::uncollapse_tree() {
void TreeItem::set_custom_minimum_height(int p_height) {
custom_min_height = p_height;
- for (Cell &c : cells)
+ for (Cell &c : cells) {
c.cached_minimum_size_dirty = true;
+ }
_changed_notify();
}
@@ -1092,8 +1093,9 @@ bool TreeItem::get_expand_right(int p_column) const {
void TreeItem::set_disable_folding(bool p_disable) {
disable_folding = p_disable;
- for (Cell &c : cells)
+ for (Cell &c : cells) {
c.cached_minimum_size_dirty = true;
+ }
_changed_notify(0);
}
@@ -1317,10 +1319,10 @@ void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_children"), &TreeItem::get_children);
ClassDB::bind_method(D_METHOD("get_index"), &TreeItem::get_index);
- ClassDB::bind_method(D_METHOD("move_before", "item"), &TreeItem::_move_before);
- ClassDB::bind_method(D_METHOD("move_after", "item"), &TreeItem::_move_after);
+ ClassDB::bind_method(D_METHOD("move_before", "item"), &TreeItem::move_before);
+ ClassDB::bind_method(D_METHOD("move_after", "item"), &TreeItem::move_after);
- ClassDB::bind_method(D_METHOD("remove_child", "child"), &TreeItem::_remove_child);
+ ClassDB::bind_method(D_METHOD("remove_child", "child"), &TreeItem::remove_child);
{
MethodInfo mi;
@@ -4813,7 +4815,7 @@ bool Tree::get_allow_reselect() const {
void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear"), &Tree::clear);
- ClassDB::bind_method(D_METHOD("create_item", "parent", "idx"), &Tree::_create_item, DEFVAL(Variant()), DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("create_item", "parent", "idx"), &Tree::create_item, DEFVAL(Variant()), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("get_root"), &Tree::get_root);
ClassDB::bind_method(D_METHOD("set_column_custom_minimum_width", "column", "min_width"), &Tree::set_column_custom_minimum_width);
@@ -4828,7 +4830,7 @@ void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_hide_root", "enable"), &Tree::set_hide_root);
ClassDB::bind_method(D_METHOD("is_root_hidden"), &Tree::is_root_hidden);
- ClassDB::bind_method(D_METHOD("get_next_selected", "from"), &Tree::_get_next_selected);
+ ClassDB::bind_method(D_METHOD("get_next_selected", "from"), &Tree::get_next_selected);
ClassDB::bind_method(D_METHOD("get_selected"), &Tree::get_selected);
ClassDB::bind_method(D_METHOD("get_selected_column"), &Tree::get_selected_column);
ClassDB::bind_method(D_METHOD("get_pressed_button"), &Tree::get_pressed_button);
@@ -4842,7 +4844,7 @@ void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_edited_column"), &Tree::get_edited_column);
ClassDB::bind_method(D_METHOD("edit_selected"), &Tree::edit_selected);
ClassDB::bind_method(D_METHOD("get_custom_popup_rect"), &Tree::get_custom_popup_rect);
- ClassDB::bind_method(D_METHOD("get_item_area_rect", "item", "column"), &Tree::_get_item_rect, DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("get_item_area_rect", "item", "column"), &Tree::get_item_rect, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("get_item_at_position", "position"), &Tree::get_item_at_position);
ClassDB::bind_method(D_METHOD("get_column_at_position", "position"), &Tree::get_column_at_position);
ClassDB::bind_method(D_METHOD("get_drop_section_at_position", "position"), &Tree::get_drop_section_at_position);
@@ -4866,7 +4868,7 @@ void Tree::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_column_title_language", "column"), &Tree::get_column_title_language);
ClassDB::bind_method(D_METHOD("get_scroll"), &Tree::get_scroll);
- ClassDB::bind_method(D_METHOD("scroll_to_item", "item"), &Tree::_scroll_to_item);
+ ClassDB::bind_method(D_METHOD("scroll_to_item", "item"), &Tree::scroll_to_item);
ClassDB::bind_method(D_METHOD("set_h_scroll_enabled", "h_scroll"), &Tree::set_h_scroll_enabled);
ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &Tree::is_h_scroll_enabled);
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 33170cad35..c24763a0e4 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -188,16 +188,6 @@ protected:
return d;
}
- void _remove_child(Object *p_child) {
- remove_child(Object::cast_to<TreeItem>(p_child));
- }
-
- void _move_before(Object *p_item) {
- move_before(Object::cast_to<TreeItem>(p_item));
- }
- void _move_after(Object *p_item) {
- move_after(Object::cast_to<TreeItem>(p_item));
- }
Variant _call_recursive_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
@@ -617,23 +607,6 @@ private:
protected:
static void _bind_methods();
- //bind helpers
- TreeItem *_create_item(Object *p_parent, int p_idx = -1) {
- return create_item(Object::cast_to<TreeItem>(p_parent), p_idx);
- }
-
- TreeItem *_get_next_selected(Object *p_item) {
- return get_next_selected(Object::cast_to<TreeItem>(p_item));
- }
-
- Rect2 _get_item_rect(Object *p_item, int p_column) const {
- return get_item_rect(Object::cast_to<TreeItem>(p_item), p_column);
- }
-
- void _scroll_to_item(Object *p_item) {
- scroll_to_item(Object::cast_to<TreeItem>(p_item));
- }
-
public:
virtual void gui_input(const Ref<InputEvent> &p_event) override;
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index 65d210983e..4e91548d14 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -46,7 +46,7 @@ Error HTTPRequest::_parse_url(const String &p_url) {
request_sent = false;
got_response = false;
body_len = -1;
- body.resize(0);
+ body.clear();
downloaded.set(0);
redirections = 0;
@@ -86,9 +86,9 @@ String HTTPRequest::get_header_value(const PackedStringArray &p_headers, const S
String lowwer_case_header_name = p_header_name.to_lower();
for (int i = 0; i < p_headers.size(); i++) {
- if (p_headers[i].find(":", 0) >= 0) {
+ if (p_headers[i].find(":") > 0) {
Vector<String> parts = p_headers[i].split(":", false, 1);
- if (parts[0].strip_edges().to_lower() == lowwer_case_header_name) {
+ if (parts.size() > 1 && parts[0].strip_edges().to_lower() == lowwer_case_header_name) {
value = parts[1].strip_edges();
break;
}
@@ -99,7 +99,7 @@ String HTTPRequest::get_header_value(const PackedStringArray &p_headers, const S
}
Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_headers, bool p_ssl_validate_domain, HTTPClient::Method p_method, const String &p_request_data) {
- // Copy the string into a raw buffer
+ // Copy the string into a raw buffer.
Vector<uint8_t> raw_data;
CharString charstr = p_request_data.utf8();
@@ -134,7 +134,7 @@ Error HTTPRequest::request_raw(const String &p_url, const Vector<String> &p_cust
headers = p_custom_headers;
if (accept_gzip) {
- // If the user has specified a different Accept-Encoding, don't overwrite it
+ // If the user has specified an Accept-Encoding header, don't overwrite it.
if (!has_header(headers, "Accept-Encoding")) {
headers.push_back("Accept-Encoding: gzip, deflate");
}
@@ -202,7 +202,7 @@ void HTTPRequest::cancel_request() {
file = nullptr;
}
client->close();
- body.resize(0);
+ body.clear();
got_response = false;
response_code = -1;
request_sent = false;
@@ -220,14 +220,14 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
response_code = client->get_response_code();
List<String> rheaders;
client->get_response_headers(&rheaders);
- response_headers.resize(0);
+ response_headers.clear();
downloaded.set(0);
for (const String &E : rheaders) {
response_headers.push_back(E);
}
if (response_code == 301 || response_code == 302) {
- // Handle redirect
+ // Handle redirect.
if (max_redirects >= 0 && redirections >= max_redirects) {
call_deferred(SNAME("_request_done"), RESULT_REDIRECT_LIMIT_REACHED, response_code, response_headers, PackedByteArray());
@@ -244,12 +244,12 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
}
if (!new_request.is_empty()) {
- // Process redirect
+ // Process redirect.
client->close();
- int new_redirs = redirections + 1; // Because _request() will clear it
+ int new_redirs = redirections + 1; // Because _request() will clear it.
Error err;
if (new_request.begins_with("http")) {
- // New url, request all again
+ // New url, new request.
_parse_url(new_request);
} else {
request_string = new_request;
@@ -260,7 +260,7 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
request_sent = false;
got_response = false;
body_len = -1;
- body.resize(0);
+ body.clear();
downloaded.set(0);
redirections = new_redirs;
*ret_value = false;
@@ -276,11 +276,11 @@ bool HTTPRequest::_update_connection() {
switch (client->get_status()) {
case HTTPClient::STATUS_DISCONNECTED: {
call_deferred(SNAME("_request_done"), RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray());
- return true; // End it, since it's doing something
+ return true; // End it, since it's disconnected.
} break;
case HTTPClient::STATUS_RESOLVING: {
client->poll();
- // Must wait
+ // Must wait.
return false;
} break;
case HTTPClient::STATUS_CANT_RESOLVE: {
@@ -290,9 +290,9 @@ bool HTTPRequest::_update_connection() {
} break;
case HTTPClient::STATUS_CONNECTING: {
client->poll();
- // Must wait
+ // Must wait.
return false;
- } break; // Connecting to IP
+ } break; // Connecting to IP.
case HTTPClient::STATUS_CANT_CONNECT: {
call_deferred(SNAME("_request_done"), RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray());
return true;
@@ -301,7 +301,7 @@ bool HTTPRequest::_update_connection() {
case HTTPClient::STATUS_CONNECTED: {
if (request_sent) {
if (!got_response) {
- // No body
+ // No body.
bool ret_value;
@@ -313,16 +313,16 @@ bool HTTPRequest::_update_connection() {
return true;
}
if (body_len < 0) {
- // Chunked transfer is done
+ // Chunked transfer is done.
call_deferred(SNAME("_request_done"), RESULT_SUCCESS, response_code, response_headers, body);
return true;
}
call_deferred(SNAME("_request_done"), RESULT_CHUNKED_BODY_SIZE_MISMATCH, response_code, response_headers, PackedByteArray());
return true;
- // Request might have been done
+ // Request might have been done.
} else {
- // Did not request yet, do request
+ // Did not request yet, do request.
int size = request_data.size();
Error err = client->request(method, request_string, headers, size > 0 ? request_data.ptr() : nullptr, size);
@@ -334,13 +334,13 @@ bool HTTPRequest::_update_connection() {
request_sent = true;
return false;
}
- } break; // Connected: break requests only accepted here
+ } break; // Connected: break requests only accepted here.
case HTTPClient::STATUS_REQUESTING: {
- // Must wait, still requesting
+ // Must wait, still requesting.
client->poll();
return false;
- } break; // Request in progress
+ } break; // Request in progress.
case HTTPClient::STATUS_BODY: {
if (!got_response) {
bool ret_value;
@@ -411,7 +411,7 @@ bool HTTPRequest::_update_connection() {
return false;
- } break; // Request resulted in body: break which must be read
+ } break; // Request resulted in body: break which must be read.
case HTTPClient::STATUS_CONNECTION_ERROR: {
call_deferred(SNAME("_request_done"), RESULT_CONNECTION_ERROR, 0, PackedStringArray(), PackedByteArray());
return true;
@@ -428,7 +428,7 @@ bool HTTPRequest::_update_connection() {
void HTTPRequest::_request_done(int p_status, int p_code, const PackedStringArray &p_headers, const PackedByteArray &p_data) {
cancel_request();
- // Determine if the request body is compressed
+ // Determine if the request body is compressed.
bool is_compressed;
String content_encoding = get_header_value(p_headers, "Content-Encoding").to_lower();
Compression::Mode mode;
@@ -452,11 +452,11 @@ void HTTPRequest::_request_done(int p_status, int p_code, const PackedStringArra
} else if (result == -5) {
WARN_PRINT("Decompressed size of HTTP response body exceeded body_size_limit");
p_status = RESULT_BODY_SIZE_LIMIT_EXCEEDED;
- // Just return the raw data if we failed to decompress it
+ // Just return the raw data if we failed to decompress it.
} else {
WARN_PRINT("Failed to decompress HTTP response body");
p_status = RESULT_BODY_DECOMPRESS_FAILED;
- // Just return the raw data if we failed to decompress it
+ // Just return the raw data if we failed to decompress it.
}
}
@@ -471,7 +471,6 @@ void HTTPRequest::_notification(int p_what) {
bool done = _update_connection();
if (done) {
set_process_internal(false);
- // cancel_request(); called from _request done now
}
}
@@ -619,7 +618,6 @@ void HTTPRequest::_bind_methods() {
ADD_SIGNAL(MethodInfo("request_completed", PropertyInfo(Variant::INT, "result"), PropertyInfo(Variant::INT, "response_code"), PropertyInfo(Variant::PACKED_STRING_ARRAY, "headers"), PropertyInfo(Variant::PACKED_BYTE_ARRAY, "body")));
BIND_ENUM_CONSTANT(RESULT_SUCCESS);
- //BIND_ENUM_CONSTANT( RESULT_NO_BODY );
BIND_ENUM_CONSTANT(RESULT_CHUNKED_BODY_SIZE_MISMATCH);
BIND_ENUM_CONSTANT(RESULT_CANT_CONNECT);
BIND_ENUM_CONSTANT(RESULT_CANT_RESOLVE);
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 0c92dcae11..45f04b28b9 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -130,7 +130,7 @@ SceneTree::Group *SceneTree::add_to_group(const StringName &p_group, Node *p_nod
E = group_map.insert(p_group, Group());
}
- ERR_FAIL_COND_V_MSG(E->get().nodes.find(p_node) != -1, &E->get(), "Already in group: " + p_group + ".");
+ ERR_FAIL_COND_V_MSG(E->get().nodes.has(p_node), &E->get(), "Already in group: " + p_group + ".");
E->get().nodes.push_back(p_node);
//E->get().last_tree_version=0;
E->get().changed = true;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 1244e0c028..09880ad6cf 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -492,20 +492,26 @@ void Viewport::_notification(int p_what) {
}
#endif // _3D_DISABLED
} break;
+ case NOTIFICATION_WM_MOUSE_ENTER: {
+ gui.mouse_in_window = true;
+ } break;
case NOTIFICATION_WM_MOUSE_EXIT: {
+ gui.mouse_in_window = false;
_drop_physics_mouseover();
-
- // Unlike on loss of focus (NOTIFICATION_WM_WINDOW_FOCUS_OUT), do not
- // drop the gui mouseover here, as a scrollbar may be dragged while the
- // mouse is outside the window (without the window having lost focus).
- // See bug #39634
+ _drop_mouse_over();
+ // When the mouse exits the window, we want to end mouse_over, but
+ // not mouse_focus, because, for example, we want to continue
+ // dragging a scrollbar even if the mouse has left the window.
} break;
case NOTIFICATION_WM_WINDOW_FOCUS_OUT: {
_drop_physics_mouseover();
-
if (gui.mouse_focus && !gui.forced_mouse_focus) {
_drop_mouse_focus();
}
+ // When the window focus changes, we want to end mouse_focus, but
+ // not the mouse_over. Note: The OS will trigger a separate mouse
+ // exit event if the change in focus results in the mouse exiting
+ // the window.
} break;
}
}
@@ -1447,8 +1453,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (mb.is_valid()) {
gui.key_event_accepted = false;
- Control *over = nullptr;
-
Point2 mpos = mb->get_position();
gui.last_mouse_pos = mpos;
if (mb->is_pressed()) {
@@ -1594,6 +1598,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
// it is different, rather than wait for it to be updated the next time the
// mouse is moved, notify the control so that it can e.g. drop the highlight.
// This code is duplicated from the mm.is_valid()-case further below.
+ Control *over = nullptr;
if (gui.mouse_focus) {
over = gui.mouse_focus;
} else {
@@ -1601,10 +1606,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
if (gui.mouse_focus_mask == MouseButton::NONE && over != gui.mouse_over) {
- if (gui.mouse_over) {
- _gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT);
- }
-
+ _drop_mouse_over();
_gui_cancel_tooltip();
if (over) {
@@ -1625,8 +1627,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.last_mouse_pos = mpos;
- Control *over = nullptr;
-
// Drag & drop.
if (!gui.drag_attempted && gui.mouse_focus && (mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) {
gui.drag_accum += mm->get_relative();
@@ -1674,29 +1674,23 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
}
- // These sections of code are reused in the mb.is_valid() case further up
- // for the purpose of notifying controls about potential changes in focus
- // when the mousebutton is released.
+ Control *over = nullptr;
if (gui.mouse_focus) {
over = gui.mouse_focus;
- } else {
+ } else if (gui.mouse_in_window) {
over = gui_find_control(mpos);
}
if (over != gui.mouse_over) {
- if (gui.mouse_over) {
- _gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT);
- }
-
+ _drop_mouse_over();
_gui_cancel_tooltip();
if (over) {
_gui_call_notification(over, Control::NOTIFICATION_MOUSE_ENTER);
+ gui.mouse_over = over;
}
}
- gui.mouse_over = over;
-
DisplayServer::CursorShape ds_cursor_shape = (DisplayServer::CursorShape)Input::get_singleton()->get_default_cursor_shape();
if (over) {
@@ -2098,7 +2092,7 @@ void Viewport::_gui_hide_control(Control *p_control) {
}
if (gui.key_focus == p_control) {
- _gui_remove_focus();
+ gui_release_focus();
}
if (gui.mouse_over == p_control) {
gui.mouse_over = nullptr;
@@ -2148,15 +2142,7 @@ Window *Viewport::get_base_window() const {
}
void Viewport::_gui_remove_focus_for_window(Node *p_window) {
if (get_base_window() == p_window) {
- _gui_remove_focus();
- }
-}
-
-void Viewport::_gui_remove_focus() {
- if (gui.key_focus) {
- Node *f = gui.key_focus;
- gui.key_focus = nullptr;
- f->notification(Control::NOTIFICATION_FOCUS_EXIT, true);
+ gui_release_focus();
}
}
@@ -2183,6 +2169,13 @@ void Viewport::_gui_accept_event() {
}
}
+void Viewport::_drop_mouse_over() {
+ if (gui.mouse_over) {
+ _gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT);
+ gui.mouse_over = nullptr;
+ }
+}
+
void Viewport::_drop_mouse_focus() {
Control *c = gui.mouse_focus;
MouseButton mask = gui.mouse_focus_mask;
@@ -2278,10 +2271,6 @@ void Viewport::_cleanup_mouseover_colliders(bool p_clean_all_frames, bool p_paus
}
}
-Control *Viewport::_gui_get_focus_owner() {
- return gui.key_focus;
-}
-
void Viewport::_gui_grab_click_focus(Control *p_control) {
gui.mouse_click_grabber = p_control;
call_deferred(SNAME("_post_gui_grab_click_focus"));
@@ -2797,6 +2786,19 @@ int Viewport::gui_get_canvas_sort_index() {
return gui.canvas_sort_index++;
}
+void Viewport::gui_release_focus() {
+ if (gui.key_focus) {
+ Control *f = gui.key_focus;
+ gui.key_focus = nullptr;
+ f->notification(Control::NOTIFICATION_FOCUS_EXIT, true);
+ f->update();
+ }
+}
+
+Control *Viewport::gui_get_focus_owner() {
+ return gui.key_focus;
+}
+
void Viewport::set_msaa(MSAA p_msaa) {
ERR_FAIL_INDEX(p_msaa, MSAA_MAX);
if (msaa == p_msaa) {
@@ -3590,6 +3592,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("gui_is_dragging"), &Viewport::gui_is_dragging);
ClassDB::bind_method(D_METHOD("gui_is_drag_successful"), &Viewport::gui_is_drag_successful);
+ ClassDB::bind_method(D_METHOD("gui_release_focus"), &Viewport::gui_release_focus);
+ ClassDB::bind_method(D_METHOD("gui_get_focus_owner"), &Viewport::gui_get_focus_owner);
+
ClassDB::bind_method(D_METHOD("set_disable_input", "disable"), &Viewport::set_disable_input);
ClassDB::bind_method(D_METHOD("is_input_disabled"), &Viewport::is_input_disabled);
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index a3127811f5..3a71745f44 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -335,6 +335,7 @@ private:
// info used when this is a window
bool forced_mouse_focus = false; //used for menu buttons
+ bool mouse_in_window = true;
bool key_event_accepted = false;
Control *mouse_focus = nullptr;
Control *last_mouse_focus = nullptr;
@@ -410,7 +411,6 @@ private:
Control *_gui_get_drag_preview();
void _gui_remove_focus_for_window(Node *p_window);
- void _gui_remove_focus();
void _gui_unfocus_control(Control *p_control);
bool _gui_control_has_focus(const Control *p_control);
void _gui_control_grab_focus(Control *p_control);
@@ -418,8 +418,6 @@ private:
void _post_gui_grab_click_focus();
void _gui_accept_event();
- Control *_gui_get_focus_owner();
-
bool _gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_check);
friend class AudioListener2D;
@@ -433,6 +431,7 @@ private:
void _canvas_layer_add(CanvasLayer *p_canvas_layer);
void _canvas_layer_remove(CanvasLayer *p_canvas_layer);
+ void _drop_mouse_over();
void _drop_mouse_focus();
void _drop_physics_mouseover(bool p_paused_only = false);
@@ -557,6 +556,9 @@ public:
void gui_reset_canvas_sort_index();
int gui_get_canvas_sort_index();
+ void gui_release_focus();
+ Control *gui_get_focus_owner();
+
TypedArray<String> get_configuration_warnings() const override;
void set_debug_draw(DebugDraw p_debug_draw);
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 69b06c1803..838cef824b 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -555,11 +555,13 @@ void register_scene_types() {
GDREGISTER_VIRTUAL_CLASS(VisualShaderNodeResizableBase);
GDREGISTER_VIRTUAL_CLASS(VisualShaderNodeGroupBase);
GDREGISTER_VIRTUAL_CLASS(VisualShaderNodeConstant);
+ GDREGISTER_VIRTUAL_CLASS(VisualShaderNodeVectorBase);
GDREGISTER_CLASS(VisualShaderNodeComment);
GDREGISTER_CLASS(VisualShaderNodeFloatConstant);
GDREGISTER_CLASS(VisualShaderNodeIntConstant);
GDREGISTER_CLASS(VisualShaderNodeBooleanConstant);
GDREGISTER_CLASS(VisualShaderNodeColorConstant);
+ GDREGISTER_CLASS(VisualShaderNodeVec2Constant);
GDREGISTER_CLASS(VisualShaderNodeVec3Constant);
GDREGISTER_CLASS(VisualShaderNodeTransformConstant);
GDREGISTER_CLASS(VisualShaderNodeFloatOp);
@@ -577,8 +579,7 @@ void register_scene_types() {
GDREGISTER_CLASS(VisualShaderNodeDotProduct);
GDREGISTER_CLASS(VisualShaderNodeVectorLen);
GDREGISTER_CLASS(VisualShaderNodeDeterminant);
- GDREGISTER_CLASS(VisualShaderNodeScalarDerivativeFunc);
- GDREGISTER_CLASS(VisualShaderNodeVectorDerivativeFunc);
+ GDREGISTER_CLASS(VisualShaderNodeDerivativeFunc);
GDREGISTER_CLASS(VisualShaderNodeClamp);
GDREGISTER_CLASS(VisualShaderNodeFaceForward);
GDREGISTER_CLASS(VisualShaderNodeOuterProduct);
@@ -604,6 +605,7 @@ void register_scene_types() {
GDREGISTER_CLASS(VisualShaderNodeIntUniform);
GDREGISTER_CLASS(VisualShaderNodeBooleanUniform);
GDREGISTER_CLASS(VisualShaderNodeColorUniform);
+ GDREGISTER_CLASS(VisualShaderNodeVec2Uniform);
GDREGISTER_CLASS(VisualShaderNodeVec3Uniform);
GDREGISTER_CLASS(VisualShaderNodeTransformUniform);
GDREGISTER_CLASS(VisualShaderNodeTextureUniform);
@@ -1024,6 +1026,8 @@ void register_scene_types() {
ClassDB::add_compatibility_class("VisualShaderNodeVectorScalarStep", "VisualShaderNodeStep");
ClassDB::add_compatibility_class("VisualShaderNodeScalarSwitch", "VisualShaderNodeSwitch");
ClassDB::add_compatibility_class("VisualShaderNodeScalarTransformMult", "VisualShaderNodeTransformOp");
+ ClassDB::add_compatibility_class("VisualShaderNodeScalarDerivativeFunc", "VisualShaderNodeDerivativeFunc");
+ ClassDB::add_compatibility_class("VisualShaderNodeVectorDerivativeFunc", "VisualShaderNodeDerivativeFunc");
ClassDB::add_compatibility_class("World", "World3D");
#endif /* DISABLE_DEPRECATED */
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 44d3e4af19..b6151bccf4 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -2474,34 +2474,38 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, double p_time, Interpol
real_t delta = (length - p_keys[next].time) - (length - p_keys[idx].time);
real_t from = (length - p_time) - (length - p_keys[idx].time);
- if (Math::is_zero_approx(delta))
+ if (Math::is_zero_approx(delta)) {
c = 0;
- else
+ } else {
c = from / delta;
+ }
} else {
next = len - 1;
real_t delta = p_keys[idx].time + (length - p_keys[next].time);
real_t from = (length - p_time) - (length - p_keys[idx].time);
- if (Math::is_zero_approx(delta))
+ if (Math::is_zero_approx(delta)) {
c = 0;
- else
+ } else {
c = from / delta;
+ }
}
} else {
// on loop, in front of last key
idx = 0;
next = len - 1;
real_t endtime = p_keys[idx].time;
- if (endtime > length) // may be keys past the end
+ if (endtime > length) { // may be keys past the end
endtime = length;
+ }
real_t delta = p_keys[next].time - endtime;
real_t from = p_time - endtime;
- if (Math::is_zero_approx(delta))
+ if (Math::is_zero_approx(delta)) {
c = 0;
- else
+ } else {
c = from / delta;
+ }
}
}
} else { // no loop
@@ -2609,7 +2613,7 @@ Variant Animation::value_track_interpolate(int p_track, double p_time) const {
void Animation::_value_track_get_key_indices_in_range(const ValueTrack *vt, double from_time, double to_time, List<int> *p_indices) const {
if (from_time != length && to_time == length) {
- to_time = length * 1.001; //include a little more if at the end
+ to_time = length + CMP_EPSILON; //include a little more if at the end
}
int to = _find(vt->values, to_time);
@@ -2730,7 +2734,7 @@ Animation::UpdateMode Animation::value_track_get_update_mode(int p_track) const
template <class T>
void Animation::_track_get_key_indices_in_range(const Vector<T> &p_array, double from_time, double to_time, List<int> *p_indices) const {
if (from_time != length && to_time == length) {
- to_time = length * 1.01; //include a little more if at the end
+ to_time = length + CMP_EPSILON; //include a little more if at the end
}
int to = _find(p_array, to_time);
@@ -3081,7 +3085,7 @@ void Animation::track_get_key_indices_in_range(int p_track, double p_time, doubl
void Animation::_method_track_get_key_indices_in_range(const MethodTrack *mt, double from_time, double to_time, List<int> *p_indices) const {
if (from_time != length && to_time == length) {
- to_time = length * 1.01; //include a little more if at the end
+ to_time = length + CMP_EPSILON; //include a little more if at the end
}
int to = _find(mt->methods, to_time);
diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp
index 25f169b6a2..c2988c2e8c 100644
--- a/scene/resources/bit_map.cpp
+++ b/scene/resources/bit_map.cpp
@@ -667,11 +667,13 @@ void BitMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_true_bit_count"), &BitMap::get_true_bit_count);
ClassDB::bind_method(D_METHOD("get_size"), &BitMap::get_size);
+ ClassDB::bind_method(D_METHOD("resize", "new_size"), &BitMap::resize);
ClassDB::bind_method(D_METHOD("_set_data"), &BitMap::_set_data);
ClassDB::bind_method(D_METHOD("_get_data"), &BitMap::_get_data);
ClassDB::bind_method(D_METHOD("grow_mask", "pixels", "rect"), &BitMap::grow_mask);
+ ClassDB::bind_method(D_METHOD("convert_to_image"), &BitMap::convert_to_image);
ClassDB::bind_method(D_METHOD("opaque_to_polygons", "rect", "epsilon"), &BitMap::_opaque_to_polygons_bind, DEFVAL(2.0));
ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
diff --git a/scene/resources/box_shape_3d.cpp b/scene/resources/box_shape_3d.cpp
index b97d378e02..a1ec9a2230 100644
--- a/scene/resources/box_shape_3d.cpp
+++ b/scene/resources/box_shape_3d.cpp
@@ -95,5 +95,5 @@ void BoxShape3D::_bind_methods() {
BoxShape3D::BoxShape3D() :
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_BOX)) {
- set_size(Vector3(2, 2, 2));
+ set_size(Vector3(1, 1, 1));
}
diff --git a/scene/resources/capsule_shape_3d.h b/scene/resources/capsule_shape_3d.h
index 967a413da4..4c039ab326 100644
--- a/scene/resources/capsule_shape_3d.h
+++ b/scene/resources/capsule_shape_3d.h
@@ -35,8 +35,8 @@
class CapsuleShape3D : public Shape3D {
GDCLASS(CapsuleShape3D, Shape3D);
- float radius = 1.0;
- float height = 3.0;
+ float radius = 0.5;
+ float height = 2.0;
protected:
static void _bind_methods();
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index d2cd76b796..6485c1ac77 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -661,8 +661,8 @@ void Curve2D::_bake() const {
baked_cache_dirty = false;
if (points.size() == 0) {
- baked_point_cache.resize(0);
- baked_dist_cache.resize(0);
+ baked_point_cache.clear();
+ baked_dist_cache.clear();
return;
}
@@ -1164,10 +1164,10 @@ void Curve3D::_bake() const {
baked_cache_dirty = false;
if (points.size() == 0) {
- baked_point_cache.resize(0);
- baked_tilt_cache.resize(0);
- baked_up_vector_cache.resize(0);
- baked_dist_cache.resize(0);
+ baked_point_cache.clear();
+ baked_tilt_cache.clear();
+ baked_up_vector_cache.clear();
+ baked_dist_cache.clear();
return;
}
@@ -1183,7 +1183,7 @@ void Curve3D::_bake() const {
baked_up_vector_cache.resize(1);
baked_up_vector_cache.set(0, Vector3(0, 1, 0));
} else {
- baked_up_vector_cache.resize(0);
+ baked_up_vector_cache.clear();
}
return;
diff --git a/scene/resources/cylinder_shape_3d.h b/scene/resources/cylinder_shape_3d.h
index 0211f2b08f..65427423c8 100644
--- a/scene/resources/cylinder_shape_3d.h
+++ b/scene/resources/cylinder_shape_3d.h
@@ -35,7 +35,7 @@
class CylinderShape3D : public Shape3D {
GDCLASS(CylinderShape3D, Shape3D);
- float radius = 1.0;
+ float radius = 0.5;
float height = 2.0;
protected:
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 12ea1683c8..670b141080 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -113,6 +113,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te
const Color control_font_hover_color = Color(0.95, 0.95, 0.95);
const Color control_font_focus_color = Color(0.95, 0.95, 0.95);
const Color control_font_disabled_color = control_font_color * Color(1, 1, 1, 0.5);
+ const Color control_font_placeholder_color = Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.6f);
const Color control_font_pressed_color = Color(1, 1, 1);
const Color control_selection_color = Color(0.5, 0.5, 0.5);
@@ -385,6 +386,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te
theme->set_color("font_color", "LineEdit", control_font_color);
theme->set_color("font_selected_color", "LineEdit", control_font_pressed_color);
theme->set_color("font_uneditable_color", "LineEdit", control_font_disabled_color);
+ theme->set_color("font_placeholder_color", "LineEdit", control_font_placeholder_color);
theme->set_color("font_outline_color", "LineEdit", Color(1, 1, 1));
theme->set_color("caret_color", "LineEdit", control_font_hover_color);
theme->set_color("selection_color", "LineEdit", control_selection_color);
@@ -427,6 +429,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te
theme->set_color("font_color", "TextEdit", control_font_color);
theme->set_color("font_selected_color", "TextEdit", control_font_pressed_color);
theme->set_color("font_readonly_color", "TextEdit", control_font_disabled_color);
+ theme->set_color("font_placeholder_color", "TextEdit", control_font_placeholder_color);
theme->set_color("font_outline_color", "TextEdit", Color(1, 1, 1));
theme->set_color("selection_color", "TextEdit", control_selection_color);
theme->set_color("current_line_color", "TextEdit", Color(0.25, 0.25, 0.26, 0.8));
@@ -468,6 +471,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te
theme->set_color("font_color", "CodeEdit", control_font_color);
theme->set_color("font_selected_color", "CodeEdit", Color(0, 0, 0));
theme->set_color("font_readonly_color", "CodeEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f));
+ theme->set_color("font_placeholder_color", "CodeEdit", control_font_placeholder_color);
theme->set_color("font_outline_color", "CodeEdit", Color(1, 1, 1));
theme->set_color("selection_color", "CodeEdit", control_selection_color);
theme->set_color("bookmark_color", "CodeEdit", Color(0.5, 0.64, 1, 0.8));
@@ -817,8 +821,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, Ref<Te
theme->set_stylebox("tab_selected", "TabBar", style_tab_selected);
theme->set_stylebox("tab_unselected", "TabBar", style_tab_unselected);
theme->set_stylebox("tab_disabled", "TabBar", style_tab_disabled);
- theme->set_stylebox("close_bg_pressed", "TabBar", button_pressed);
- theme->set_stylebox("close_bg_highlight", "TabBar", button_normal);
+ theme->set_stylebox("button_pressed", "TabBar", button_pressed);
+ theme->set_stylebox("button_highlight", "TabBar", button_normal);
theme->set_icon("increment", "TabBar", icons["scroll_button_right"]);
theme->set_icon("increment_highlight", "TabBar", icons["scroll_button_right_hl"]);
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 0afe040f33..b13ae9d016 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -728,6 +728,24 @@ float Environment::get_glow_hdr_luminance_cap() const {
return glow_hdr_luminance_cap;
}
+void Environment::set_glow_map_strength(float p_strength) {
+ glow_map_strength = p_strength;
+ _update_glow();
+}
+
+float Environment::get_glow_map_strength() const {
+ return glow_map_strength;
+}
+
+void Environment::set_glow_map(Ref<Texture> p_glow_map) {
+ glow_map = p_glow_map;
+ _update_glow();
+}
+
+Ref<Texture> Environment::get_glow_map() const {
+ return glow_map;
+}
+
void Environment::_update_glow() {
Vector<float> normalized_levels;
if (glow_normalize_levels) {
@@ -743,6 +761,15 @@ void Environment::_update_glow() {
normalized_levels = glow_levels;
}
+ float _glow_map_strength = 0.0f;
+ RID glow_map_rid;
+ if (glow_map.is_valid()) {
+ glow_map_rid = glow_map->get_rid();
+ _glow_map_strength = glow_map_strength;
+ } else {
+ glow_map_rid = RID();
+ }
+
RS::get_singleton()->environment_set_glow(
environment,
glow_enabled,
@@ -754,7 +781,9 @@ void Environment::_update_glow() {
RS::EnvironmentGlowBlendMode(glow_blend_mode),
glow_hdr_bleed_threshold,
glow_hdr_bleed_scale,
- glow_hdr_luminance_cap);
+ glow_hdr_luminance_cap,
+ _glow_map_strength,
+ glow_map_rid);
}
// Fog
@@ -1332,6 +1361,10 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_glow_hdr_bleed_scale"), &Environment::get_glow_hdr_bleed_scale);
ClassDB::bind_method(D_METHOD("set_glow_hdr_luminance_cap", "amount"), &Environment::set_glow_hdr_luminance_cap);
ClassDB::bind_method(D_METHOD("get_glow_hdr_luminance_cap"), &Environment::get_glow_hdr_luminance_cap);
+ ClassDB::bind_method(D_METHOD("set_glow_map_strength", "strength"), &Environment::set_glow_map_strength);
+ ClassDB::bind_method(D_METHOD("get_glow_map_strength"), &Environment::get_glow_map_strength);
+ ClassDB::bind_method(D_METHOD("set_glow_map", "mode"), &Environment::set_glow_map);
+ ClassDB::bind_method(D_METHOD("get_glow_map"), &Environment::get_glow_map);
ADD_GROUP("Glow", "glow_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "glow_enabled"), "set_glow_enabled", "is_glow_enabled");
@@ -1351,6 +1384,8 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_hdr_threshold", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_threshold", "get_glow_hdr_bleed_threshold");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_hdr_scale", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_scale", "get_glow_hdr_bleed_scale");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_hdr_luminance_cap", PROPERTY_HINT_RANGE, "0.0,256.0,0.01"), "set_glow_hdr_luminance_cap", "get_glow_hdr_luminance_cap");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_map_strength", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_glow_map_strength", "get_glow_map_strength");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "glow_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_glow_map", "get_glow_map");
// Fog
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index 3f05315013..b04723a221 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -170,6 +170,8 @@ private:
float glow_hdr_bleed_threshold = 1.0;
float glow_hdr_bleed_scale = 2.0;
float glow_hdr_luminance_cap = 12.0;
+ float glow_map_strength = 0.8f;
+ Ref<Texture> glow_map;
void _update_glow();
// Fog
@@ -360,6 +362,10 @@ public:
float get_glow_hdr_bleed_scale() const;
void set_glow_hdr_luminance_cap(float p_amount);
float get_glow_hdr_luminance_cap() const;
+ void set_glow_map_strength(float p_strength);
+ float get_glow_map_strength() const;
+ void set_glow_map(Ref<Texture> p_glow_map);
+ Ref<Texture> get_glow_map() const;
// Fog
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index f040041aa5..b512acdd8a 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -2344,8 +2344,9 @@ real_t Font::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char,
bool Font::has_char(char32_t p_char) const {
for (int i = 0; i < data.size(); i++) {
- if (data[i]->has_char(p_char))
+ if (data[i]->has_char(p_char)) {
return true;
+ }
}
return false;
}
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index d2d96b1f06..441e84eccc 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -1475,12 +1475,12 @@ void ArrayMesh::add_blend_shape(const StringName &p_name) {
StringName name = p_name;
- if (blend_shapes.find(name) != -1) {
+ if (blend_shapes.has(name)) {
int count = 2;
do {
name = String(p_name) + " " + itos(count);
count++;
- } while (blend_shapes.find(name) != -1);
+ } while (blend_shapes.has(name));
}
blend_shapes.push_back(name);
diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp
index 3db839a1d0..5168bf83eb 100644
--- a/scene/resources/mesh_library.cpp
+++ b/scene/resources/mesh_library.cpp
@@ -30,6 +30,8 @@
#include "mesh_library.h"
+#include "box_shape_3d.h"
+
bool MeshLibrary::_set(const StringName &p_name, const Variant &p_value) {
String name = p_name;
if (name.begins_with("item/")) {
@@ -255,12 +257,35 @@ int MeshLibrary::get_last_unused_item_id() const {
}
void MeshLibrary::_set_item_shapes(int p_item, const Array &p_shapes) {
- ERR_FAIL_COND(p_shapes.size() & 1);
+ Array arr_shapes = p_shapes;
+ int size = p_shapes.size();
+ if (size & 1) {
+ ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
+ int prev_size = item_map[p_item].shapes.size() * 2;
+
+ if (prev_size < size) {
+ // Check if last element is a shape.
+ Ref<Shape3D> shape = arr_shapes[size - 1];
+ if (shape.is_null()) {
+ Ref<BoxShape3D> box_shape;
+ box_shape.instantiate();
+ arr_shapes[size - 1] = box_shape;
+ }
+
+ // Make sure the added element is a Transform3D.
+ arr_shapes.push_back(Transform3D());
+ size++;
+ } else {
+ size--;
+ arr_shapes.resize(size);
+ }
+ }
+
Vector<ShapeData> shapes;
- for (int i = 0; i < p_shapes.size(); i += 2) {
+ for (int i = 0; i < size; i += 2) {
ShapeData sd;
- sd.shape = p_shapes[i + 0];
- sd.local_transform = p_shapes[i + 1];
+ sd.shape = arr_shapes[i + 0];
+ sd.local_transform = arr_shapes[i + 1];
if (sd.shape.is_valid()) {
shapes.push_back(sd);
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index aa9682bd80..3fc5fd4a16 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -106,8 +106,8 @@ class CapsuleMesh : public PrimitiveMesh {
GDCLASS(CapsuleMesh, PrimitiveMesh);
private:
- float radius = 1.0;
- float height = 3.0;
+ float radius = 0.5;
+ float height = 2.0;
int radial_segments = 64;
int rings = 8;
@@ -138,7 +138,7 @@ class BoxMesh : public PrimitiveMesh {
GDCLASS(BoxMesh, PrimitiveMesh);
private:
- Vector3 size = Vector3(2.0, 2.0, 2.0);
+ Vector3 size = Vector3(1, 1, 1);
int subdivide_w = 0;
int subdivide_h = 0;
int subdivide_d = 0;
@@ -171,8 +171,8 @@ class CylinderMesh : public PrimitiveMesh {
GDCLASS(CylinderMesh, PrimitiveMesh);
private:
- float top_radius = 1.0;
- float bottom_radius = 1.0;
+ float top_radius = 0.5;
+ float bottom_radius = 0.5;
float height = 2.0;
int radial_segments = 64;
int rings = 4;
diff --git a/scene/resources/skeleton_modification_3d.cpp b/scene/resources/skeleton_modification_3d.cpp
index b5b3fd5e9f..2c0f6e779e 100644
--- a/scene/resources/skeleton_modification_3d.cpp
+++ b/scene/resources/skeleton_modification_3d.cpp
@@ -34,8 +34,9 @@
void SkeletonModification3D::_execute(real_t p_delta) {
GDVIRTUAL_CALL(_execute, p_delta);
- if (!enabled)
+ if (!enabled) {
return;
+ }
}
void SkeletonModification3D::_setup_modification(SkeletonModificationStack3D *p_stack) {
diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp
index 6ec16f12df..c5d5ba2912 100644
--- a/scene/resources/sky_material.cpp
+++ b/scene/resources/sky_material.cpp
@@ -292,7 +292,6 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() {
}
ProceduralSkyMaterial::~ProceduralSkyMaterial() {
- RS::get_singleton()->material_set_shader(_get_material(), RID());
}
/////////////////////////////////////////
@@ -389,7 +388,6 @@ PanoramaSkyMaterial::PanoramaSkyMaterial() {
}
PanoramaSkyMaterial::~PanoramaSkyMaterial() {
- RS::get_singleton()->material_set_shader(_get_material(), RID());
}
//////////////////////////////////
diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp
index f3752053c0..c3b5bd3564 100644
--- a/scene/resources/text_line.cpp
+++ b/scene/resources/text_line.cpp
@@ -55,7 +55,7 @@ void TextLine::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bidi_override", "override"), &TextLine::set_bidi_override);
- ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language"), &TextLine::add_string, DEFVAL(Dictionary()), DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language", "meta"), &TextLine::add_string, DEFVAL(Dictionary()), DEFVAL(""), DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextLine::add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1));
ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextLine::resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER));
@@ -200,9 +200,9 @@ void TextLine::set_bidi_override(const Array &p_override) {
dirty = true;
}
-bool TextLine::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) {
+bool TextLine::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
ERR_FAIL_COND_V(p_fonts.is_null(), false);
- bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language);
+ bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language, p_meta);
spacing_top = p_fonts->get_spacing(TextServer::SPACING_TOP);
spacing_bottom = p_fonts->get_spacing(TextServer::SPACING_BOTTOM);
dirty = true;
diff --git a/scene/resources/text_line.h b/scene/resources/text_line.h
index e68049ee45..c5762db0f2 100644
--- a/scene/resources/text_line.h
+++ b/scene/resources/text_line.h
@@ -86,7 +86,7 @@ public:
void set_preserve_control(bool p_enabled);
bool get_preserve_control() const;
- bool add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "");
+ bool add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant());
bool add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1);
bool resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER);
diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp
index c3bdef7b01..4d75874199 100644
--- a/scene/resources/text_paragraph.cpp
+++ b/scene/resources/text_paragraph.cpp
@@ -63,7 +63,7 @@ void TextParagraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_dropcap", "text", "fonts", "size", "dropcap_margins", "opentype_features", "language"), &TextParagraph::set_dropcap, DEFVAL(Rect2()), DEFVAL(Dictionary()), DEFVAL(""));
ClassDB::bind_method(D_METHOD("clear_dropcap"), &TextParagraph::clear_dropcap);
- ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language"), &TextParagraph::add_string, DEFVAL(Dictionary()), DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("add_string", "text", "fonts", "size", "opentype_features", "language", "meta"), &TextParagraph::add_string, DEFVAL(Dictionary()), DEFVAL(""), DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("add_object", "key", "size", "inline_align", "length"), &TextParagraph::add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1));
ClassDB::bind_method(D_METHOD("resize_object", "key", "size", "inline_align"), &TextParagraph::resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER));
@@ -344,9 +344,9 @@ void TextParagraph::clear_dropcap() {
lines_dirty = true;
}
-bool TextParagraph::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) {
+bool TextParagraph::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
ERR_FAIL_COND_V(p_fonts.is_null(), false);
- bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language);
+ bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language, p_meta);
spacing_top = p_fonts->get_spacing(TextServer::SPACING_TOP);
spacing_bottom = p_fonts->get_spacing(TextServer::SPACING_BOTTOM);
lines_dirty = true;
diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h
index 773cc1a858..8a8a53943b 100644
--- a/scene/resources/text_paragraph.h
+++ b/scene/resources/text_paragraph.h
@@ -102,7 +102,7 @@ public:
bool set_dropcap(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Rect2 &p_dropcap_margins = Rect2(), const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "");
void clear_dropcap();
- bool add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "");
+ bool add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant());
bool add_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1);
bool resize_object(Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER);
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 331674d248..ee66a61da8 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -2103,8 +2103,8 @@ void GradientTexture2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update"), &GradientTexture2D::_update);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT), "set_gradient", "get_gradient");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_width", "get_width");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "height", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048"), "set_width", "get_width");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "height", PROPERTY_HINT_RANGE, "1,2048"), "set_height", "get_height");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hdr"), "set_use_hdr", "is_using_hdr");
ADD_GROUP("Fill", "fill_");
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index c3f29ad417..8075497c42 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -595,7 +595,7 @@ public:
private:
mutable RID _texture;
Ref<Curve> _curve;
- int _width = 2048;
+ int _width = 256;
int _current_width = 0;
TextureMode texture_mode = TEXTURE_MODE_RGB;
TextureMode _current_texture_mode = TEXTURE_MODE_RGB;
@@ -637,7 +637,7 @@ private:
Ref<Curve> _curve_x;
Ref<Curve> _curve_y;
Ref<Curve> _curve_z;
- int _width = 2048;
+ int _width = 256;
int _current_width = 0;
void _update();
@@ -685,7 +685,7 @@ private:
Ref<Gradient> gradient;
bool update_pending = false;
RID texture;
- int width = 2048;
+ int width = 256;
bool use_hdr = false;
void _queue_update();
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index ddb9cc7440..2854cbe30d 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -207,9 +207,6 @@ void TileMapPattern::_get_property_list(List<PropertyInfo> *p_list) const {
}
void TileMapPattern::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_set_tile_data", "data"), &TileMapPattern::_set_tile_data);
- ClassDB::bind_method(D_METHOD("_get_tile_data"), &TileMapPattern::_get_tile_data);
-
ClassDB::bind_method(D_METHOD("set_cell", "coords", "source_id", "atlas_coords", "alternative_tile"), &TileMapPattern::set_cell, DEFVAL(TileSet::INVALID_SOURCE), DEFVAL(TileSetSource::INVALID_ATLAS_COORDS), DEFVAL(TileSetSource::INVALID_TILE_ALTERNATIVE));
ClassDB::bind_method(D_METHOD("has_cell", "coords"), &TileMapPattern::has_cell);
ClassDB::bind_method(D_METHOD("remove_cell", "coords", "update_size"), &TileMapPattern::remove_cell);
@@ -403,7 +400,7 @@ void TileSet::_update_terrains_cache() {
int alternative_id = source->get_alternative_tile_id(tile_id, alternative_index);
// Executed for each tile_data.
- TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(tile_id, alternative_id));
+ TileData *tile_data = atlas_source->get_tile_data(tile_id, alternative_id);
int terrain_set = tile_data->get_terrain_set();
if (terrain_set >= 0) {
TileMapCell cell;
@@ -1377,7 +1374,7 @@ TileMapCell TileSet::get_random_tile_from_terrains_pattern(int p_terrain_set, Ti
Ref<TileSetSource> source = sources[E->get().source_id];
Ref<TileSetAtlasSource> atlas_source = source;
if (atlas_source.is_valid()) {
- TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(E->get().get_atlas_coords(), E->get().alternative_tile));
+ TileData *tile_data = atlas_source->get_tile_data(E->get().get_atlas_coords(), E->get().alternative_tile);
sum += tile_data->get_probability();
} else {
sum += 1.0;
@@ -1398,7 +1395,7 @@ TileMapCell TileSet::get_random_tile_from_terrains_pattern(int p_terrain_set, Ti
Ref<TileSetAtlasSource> atlas_source = source;
if (atlas_source.is_valid()) {
- TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(E->get().get_atlas_coords(), E->get().alternative_tile));
+ TileData *tile_data = atlas_source->get_tile_data(E->get().get_atlas_coords(), E->get().alternative_tile);
count += tile_data->get_probability();
} else {
count += 1.0;
@@ -1663,7 +1660,7 @@ Vector<Vector<Ref<Texture2D>>> TileSet::generate_terrains_icons(Size2i p_size) {
for (int alternative_index = 0; alternative_index < source->get_alternative_tiles_count(tile_id); alternative_index++) {
int alternative_id = source->get_alternative_tile_id(tile_id, alternative_index);
- TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(tile_id, alternative_id));
+ TileData *tile_data = atlas_source->get_tile_data(tile_id, alternative_id);
int terrain_set = tile_data->get_terrain_set();
if (terrain_set >= 0) {
ERR_FAIL_INDEX_V(terrain_set, get_terrain_sets_count(), Vector<Vector<Ref<Texture2D>>>());
@@ -2399,7 +2396,7 @@ void TileSet::_compatibility_conversion() {
compatibility_tilemap_mapping[E.key][key_array] = value_array;
compatibility_tilemap_mapping_tile_modes[E.key] = COMPATIBILITY_TILE_MODE_SINGLE_TILE;
- TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(coords, alternative_tile));
+ TileData *tile_data = atlas_source->get_tile_data(coords, alternative_tile);
tile_data->set_flip_h(flip_h);
tile_data->set_flip_v(flip_v);
@@ -2491,7 +2488,7 @@ void TileSet::_compatibility_conversion() {
compatibility_tilemap_mapping[E.key][key_array] = value_array;
compatibility_tilemap_mapping_tile_modes[E.key] = COMPATIBILITY_TILE_MODE_ATLAS_TILE;
- TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(coords, alternative_tile));
+ TileData *tile_data = atlas_source->get_tile_data(coords, alternative_tile);
tile_data->set_flip_h(flip_h);
tile_data->set_flip_v(flip_v);
@@ -4123,7 +4120,7 @@ Vector2i TileSetAtlasSource::get_tile_effective_texture_offset(Vector2i p_atlas_
Vector2 margin = (get_tile_texture_region(p_atlas_coords).size - tile_set->get_tile_size()) / 2;
margin = Vector2i(MAX(0, margin.x), MAX(0, margin.y));
- Vector2i effective_texture_offset = Object::cast_to<TileData>(get_tile_data(p_atlas_coords, p_alternative_tile))->get_texture_offset();
+ Vector2i effective_texture_offset = get_tile_data(p_atlas_coords, p_alternative_tile)->get_texture_offset();
if (ABS(effective_texture_offset.x) > margin.x || ABS(effective_texture_offset.y) > margin.y) {
effective_texture_offset = effective_texture_offset.clamp(-margin, margin);
}
@@ -4262,7 +4259,7 @@ int TileSetAtlasSource::get_alternative_tile_id(const Vector2i p_atlas_coords, i
return tiles[p_atlas_coords].alternatives_ids[p_index];
}
-Object *TileSetAtlasSource::get_tile_data(const Vector2i p_atlas_coords, int p_alternative_tile) const {
+TileData *TileSetAtlasSource::get_tile_data(const Vector2i p_atlas_coords, int p_alternative_tile) const {
ERR_FAIL_COND_V_MSG(!tiles.has(p_atlas_coords), nullptr, vformat("The TileSetAtlasSource atlas has no tile at %s.", String(p_atlas_coords)));
ERR_FAIL_COND_V_MSG(!tiles[p_atlas_coords].alternatives.has(p_alternative_tile), nullptr, vformat("TileSetAtlasSource has no alternative with id %d for tile coords %s.", p_alternative_tile, String(p_atlas_coords)));
@@ -5092,7 +5089,7 @@ int TileData::get_collision_polygon_shapes_count(int p_layer_id, int p_polygon_i
}
Ref<ConvexPolygonShape2D> TileData::get_collision_polygon_shape(int p_layer_id, int p_polygon_index, int shape_index) const {
- ERR_FAIL_INDEX_V(p_layer_id, physics.size(), 0);
+ ERR_FAIL_INDEX_V(p_layer_id, physics.size(), Ref<ConvexPolygonShape2D>());
ERR_FAIL_INDEX_V(p_polygon_index, physics[p_layer_id].polygons.size(), Ref<ConvexPolygonShape2D>());
ERR_FAIL_INDEX_V(shape_index, (int)physics[p_layer_id].polygons[p_polygon_index].shapes.size(), Ref<ConvexPolygonShape2D>());
return physics[p_layer_id].polygons[p_polygon_index].shapes[shape_index];
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index 2673ca1cb6..95de46c9ab 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -693,7 +693,7 @@ public:
virtual int get_alternative_tile_id(const Vector2i p_atlas_coords, int p_index) const override;
// Get data associated to a tile.
- Object *get_tile_data(const Vector2i p_atlas_coords, int p_alternative_tile) const;
+ TileData *get_tile_data(const Vector2i p_atlas_coords, int p_alternative_tile) const;
// Helpers.
Vector2i get_atlas_grid_size() const;
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 4bc62e7617..f41058d59c 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -53,8 +53,98 @@ int VisualShaderNode::get_output_port_for_preview() const {
return port_preview;
}
-void VisualShaderNode::set_input_port_default_value(int p_port, const Variant &p_value) {
- default_input_values[p_port] = p_value;
+void VisualShaderNode::set_input_port_default_value(int p_port, const Variant &p_value, const Variant &p_prev_value) {
+ Variant value = p_value;
+
+ if (p_prev_value.get_type() != Variant::NIL) {
+ switch (p_value.get_type()) {
+ case Variant::FLOAT: {
+ switch (p_prev_value.get_type()) {
+ case Variant::INT: {
+ value = (float)p_prev_value;
+ } break;
+ case Variant::FLOAT: {
+ value = p_prev_value;
+ } break;
+ case Variant::VECTOR2: {
+ Vector2 pv = p_prev_value;
+ value = pv.x;
+ } break;
+ case Variant::VECTOR3: {
+ Vector3 pv = p_prev_value;
+ value = pv.x;
+ } break;
+ default:
+ break;
+ }
+ } break;
+ case Variant::INT: {
+ switch (p_prev_value.get_type()) {
+ case Variant::INT: {
+ value = p_prev_value;
+ } break;
+ case Variant::FLOAT: {
+ value = (int)p_prev_value;
+ } break;
+ case Variant::VECTOR2: {
+ Vector2 pv = p_prev_value;
+ value = (int)pv.x;
+ } break;
+ case Variant::VECTOR3: {
+ Vector3 pv = p_prev_value;
+ value = (int)pv.x;
+ } break;
+ default:
+ break;
+ }
+ } break;
+ case Variant::VECTOR2: {
+ switch (p_prev_value.get_type()) {
+ case Variant::INT: {
+ float pv = (float)(int)p_prev_value;
+ value = Vector2(pv, pv);
+ } break;
+ case Variant::FLOAT: {
+ float pv = p_prev_value;
+ value = Vector2(pv, pv);
+ } break;
+ case Variant::VECTOR2: {
+ value = p_prev_value;
+ } break;
+ case Variant::VECTOR3: {
+ Vector3 pv = p_prev_value;
+ value = Vector2(pv.x, pv.y);
+ } break;
+ default:
+ break;
+ }
+ } break;
+ case Variant::VECTOR3: {
+ switch (p_prev_value.get_type()) {
+ case Variant::INT: {
+ float pv = (float)(int)p_prev_value;
+ value = Vector3(pv, pv, pv);
+ } break;
+ case Variant::FLOAT: {
+ float pv = p_prev_value;
+ value = Vector3(pv, pv, pv);
+ } break;
+ case Variant::VECTOR2: {
+ Vector2 pv = p_prev_value;
+ value = Vector3(pv.x, pv.y, 0.0);
+ } break;
+ case Variant::VECTOR3: {
+ value = p_prev_value;
+ } break;
+ default:
+ break;
+ }
+ } break;
+ default:
+ break;
+ }
+ }
+ default_input_values[p_port] = value;
emit_changed();
}
@@ -156,8 +246,15 @@ int VisualShaderNode::get_expanded_output_port_count() const {
int count2 = count;
for (int i = 0; i < count; i++) {
if (is_output_port_expandable(i) && _is_output_port_expanded(i)) {
- if (get_output_port_type(i) == PORT_TYPE_VECTOR) {
- count2 += 3;
+ switch (get_output_port_type(i)) {
+ case PORT_TYPE_VECTOR_2D: {
+ count2 += 2;
+ } break;
+ case PORT_TYPE_VECTOR: {
+ count2 += 3;
+ } break;
+ default:
+ break;
}
}
}
@@ -245,7 +342,7 @@ void VisualShaderNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_output_ports_expanded", "values"), &VisualShaderNode::_set_output_ports_expanded);
ClassDB::bind_method(D_METHOD("_get_output_ports_expanded"), &VisualShaderNode::_get_output_ports_expanded);
- ClassDB::bind_method(D_METHOD("set_input_port_default_value", "port", "value"), &VisualShaderNode::set_input_port_default_value);
+ ClassDB::bind_method(D_METHOD("set_input_port_default_value", "port", "value", "prev_value"), &VisualShaderNode::set_input_port_default_value, DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("get_input_port_default_value", "port"), &VisualShaderNode::get_input_port_default_value);
ClassDB::bind_method(D_METHOD("remove_input_port_default_value", "port"), &VisualShaderNode::remove_input_port_default_value);
@@ -261,6 +358,7 @@ void VisualShaderNode::_bind_methods() {
BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR);
BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR_INT);
+ BIND_ENUM_CONSTANT(PORT_TYPE_VECTOR_2D);
BIND_ENUM_CONSTANT(PORT_TYPE_VECTOR);
BIND_ENUM_CONSTANT(PORT_TYPE_BOOLEAN);
BIND_ENUM_CONSTANT(PORT_TYPE_TRANSFORM);
@@ -385,9 +483,9 @@ String VisualShaderNodeCustom::generate_global_per_node(Shader::Mode p_mode, Vis
return "";
}
-void VisualShaderNodeCustom::set_input_port_default_value(int p_port, const Variant &p_value) {
+void VisualShaderNodeCustom::set_input_port_default_value(int p_port, const Variant &p_value, const Variant &p_prev_value) {
if (!is_initialized) {
- VisualShaderNode::set_input_port_default_value(p_port, p_value);
+ VisualShaderNode::set_input_port_default_value(p_port, p_value, p_prev_value);
}
}
@@ -484,24 +582,48 @@ void VisualShader::update_engine_version(const Dictionary &p_new_version) {
if (expression.is_valid()) {
for (int j = 0; j < expression->get_input_port_count(); j++) {
int type = expression->get_input_port_type(j);
- if (type > 0) { // + PORT_TYPE_SCALAR_INT
- type += 1;
+ if (type > 0) { // + PORT_TYPE_SCALAR_INT + PORT_TYPE_VECTOR_2D
+ type += 2;
}
expression->set_input_port_type(j, type);
}
for (int j = 0; j < expression->get_output_port_count(); j++) {
int type = expression->get_output_port_type(j);
- if (type > 0) { // + PORT_TYPE_SCALAR_INT
- type += 1;
+ if (type > 0) { // + PORT_TYPE_SCALAR_INT + PORT_TYPE_VECTOR_2D
+ type += 2;
}
expression->set_output_port_type(j, type);
}
}
+ Ref<VisualShaderNodeStep> step = Object::cast_to<VisualShaderNodeStep>(E.value.node.ptr());
+ if (step.is_valid()) {
+ int op_type = int(step->get_op_type());
+ if (int(op_type) > 0) { // + OP_TYPE_VECTOR_2D + OP_TYPE_VECTOR_2D_SCALAR
+ op_type += 2;
+ }
+ step->set_op_type(VisualShaderNodeStep::OpType(op_type));
+ }
+ Ref<VisualShaderNodeSmoothStep> sstep = Object::cast_to<VisualShaderNodeSmoothStep>(E.value.node.ptr());
+ if (sstep.is_valid()) {
+ int op_type = int(sstep->get_op_type());
+ if (int(op_type) > 0) { // + OP_TYPE_VECTOR_2D + OP_TYPE_VECTOR_2D_SCALAR
+ op_type += 2;
+ }
+ sstep->set_op_type(VisualShaderNodeSmoothStep::OpType(op_type));
+ }
+ Ref<VisualShaderNodeMix> mix = Object::cast_to<VisualShaderNodeMix>(E.value.node.ptr());
+ if (mix.is_valid()) {
+ int op_type = int(mix->get_op_type());
+ if (int(op_type) > 0) { // + OP_TYPE_VECTOR_2D + OP_TYPE_VECTOR_2D_SCALAR
+ op_type += 2;
+ }
+ mix->set_op_type(VisualShaderNodeMix::OpType(op_type));
+ }
Ref<VisualShaderNodeCompare> compare = Object::cast_to<VisualShaderNodeCompare>(E.value.node.ptr());
if (compare.is_valid()) {
int ctype = int(compare->get_comparison_type());
- if (int(ctype) > 0) { // + PORT_TYPE_SCALAR_INT
- ctype += 1;
+ if (int(ctype) > 0) { // + CTYPE_SCALAR_INT + CTYPE_VECTOR_2D
+ ctype += 2;
}
compare->set_comparison_type(VisualShaderNodeCompare::ComparisonType(ctype));
}
@@ -719,7 +841,7 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po
}
bool VisualShader::is_port_types_compatible(int p_a, int p_b) const {
- return MAX(0, p_a - 3) == (MAX(0, p_b - 3));
+ return MAX(0, p_a - 4) == (MAX(0, p_b - 4));
}
void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
@@ -953,15 +1075,27 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port
Error err = _write_node(p_type, global_code, global_code_per_node, global_code_per_func, code, default_tex_params, input_connections, output_connections, p_node, processed, true, classes);
ERR_FAIL_COND_V(err != OK, String());
- if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR) {
- code += " COLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " );\n";
- } else if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR_INT) {
- code += " COLOR.rgb = vec3(float(n_out" + itos(p_node) + "p" + itos(p_port) + "));\n";
- } else if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_BOOLEAN) {
- code += " COLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " ? 1.0 : 0.0);\n";
- } else {
- code += " COLOR.rgb = n_out" + itos(p_node) + "p" + itos(p_port) + ";\n";
+ switch (node->get_output_port_type(p_port)) {
+ case VisualShaderNode::PORT_TYPE_SCALAR: {
+ code += " COLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + ");\n";
+ } break;
+ case VisualShaderNode::PORT_TYPE_SCALAR_INT: {
+ code += " COLOR.rgb = vec3(float(n_out" + itos(p_node) + "p" + itos(p_port) + "));\n";
+ } break;
+ case VisualShaderNode::PORT_TYPE_BOOLEAN: {
+ code += " COLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " ? 1.0 : 0.0);\n";
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ code += " COLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + ", 0.0);\n";
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR: {
+ code += " COLOR.rgb = n_out" + itos(p_node) + "p" + itos(p_port) + ";\n";
+ } break;
+ default: {
+ code += " COLOR.rgb = vec3(0.0);\n";
+ } break;
}
+
code += "}\n";
//set code secretly
@@ -1406,30 +1540,102 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
}
} else if (in_type == out_type) {
inputs[i] = src_var;
- } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_VECTOR) {
- inputs[i] = "dot(" + src_var + ", vec3(0.333333, 0.333333, 0.333333))";
- } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_VECTOR) {
- inputs[i] = "dot(float(" + src_var + "), vec3(0.333333, 0.333333, 0.333333))";
- } else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_SCALAR) {
- inputs[i] = "vec3(" + src_var + ")";
- } else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) {
- inputs[i] = "vec3(float(" + src_var + "))";
- } else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_VECTOR) {
- inputs[i] = "all(bvec3(" + src_var + "))";
- } else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_SCALAR) {
- inputs[i] = src_var + " > 0.0 ? true : false";
- } else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) {
- inputs[i] = src_var + " > 0 ? true : false";
- } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) {
- inputs[i] = "(" + src_var + " ? 1.0 : 0.0)";
- } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) {
- inputs[i] = "(" + src_var + " ? 1 : 0)";
- } else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) {
- inputs[i] = "vec3(" + src_var + " ? 1.0 : 0.0)";
- } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) {
- inputs[i] = "float(" + src_var + ")";
- } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_SCALAR) {
- inputs[i] = "int(" + src_var + ")";
+ } else {
+ switch (in_type) {
+ case VisualShaderNode::PORT_TYPE_SCALAR: {
+ switch (out_type) {
+ case VisualShaderNode::PORT_TYPE_SCALAR_INT: {
+ inputs[i] = "float(" + src_var + ")";
+ } break;
+ case VisualShaderNode::PORT_TYPE_BOOLEAN: {
+ inputs[i] = "(" + src_var + " ? 1.0 : 0.0)";
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ inputs[i] = "dot(" + src_var + ", vec2(0.333333, 0.333333))";
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR: {
+ inputs[i] = "dot(" + src_var + ", vec3(0.333333, 0.333333, 0.333333))";
+ } break;
+ default:
+ break;
+ }
+ } break;
+ case VisualShaderNode::PORT_TYPE_SCALAR_INT: {
+ switch (out_type) {
+ case VisualShaderNode::PORT_TYPE_SCALAR: {
+ inputs[i] = "int(" + src_var + ")";
+ } break;
+ case VisualShaderNode::PORT_TYPE_BOOLEAN: {
+ inputs[i] = "(" + src_var + " ? 1 : 0)";
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ inputs[i] = "dot(float(" + src_var + "), vec2(0.333333, 0.333333))";
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR: {
+ inputs[i] = "dot(float(" + src_var + "), vec3(0.333333, 0.333333, 0.333333))";
+ } break;
+ default:
+ break;
+ }
+ } break;
+ case VisualShaderNode::PORT_TYPE_BOOLEAN: {
+ switch (out_type) {
+ case VisualShaderNode::PORT_TYPE_SCALAR: {
+ inputs[i] = src_var + " > 0.0 ? true : false";
+ } break;
+ case VisualShaderNode::PORT_TYPE_SCALAR_INT: {
+ inputs[i] = src_var + " > 0 ? true : false";
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ inputs[i] = "all(bvec2(" + src_var + "))";
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR: {
+ inputs[i] = "all(bvec3(" + src_var + "))";
+ } break;
+ default:
+ break;
+ }
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ switch (out_type) {
+ case VisualShaderNode::PORT_TYPE_SCALAR: {
+ inputs[i] = "vec2(" + src_var + ")";
+ } break;
+ case VisualShaderNode::PORT_TYPE_SCALAR_INT: {
+ inputs[i] = "vec2(float(" + src_var + "))";
+ } break;
+ case VisualShaderNode::PORT_TYPE_BOOLEAN: {
+ inputs[i] = "vec2(" + src_var + " ? 1.0 : 0.0)";
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR: {
+ inputs[i] = "vec2(" + src_var + ".xy)";
+ } break;
+ default:
+ break;
+ }
+ } break;
+
+ case VisualShaderNode::PORT_TYPE_VECTOR: {
+ switch (out_type) {
+ case VisualShaderNode::PORT_TYPE_SCALAR: {
+ inputs[i] = "vec3(" + src_var + ")";
+ } break;
+ case VisualShaderNode::PORT_TYPE_SCALAR_INT: {
+ inputs[i] = "vec3(float(" + src_var + "))";
+ } break;
+ case VisualShaderNode::PORT_TYPE_BOOLEAN: {
+ inputs[i] = "vec3(" + src_var + " ? 1.0 : 0.0)";
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ inputs[i] = "vec3(" + src_var + ", 0.0)";
+ } break;
+ default:
+ break;
+ }
+ } break;
+ default:
+ break;
+ }
}
} else {
if (!vsnode->is_generate_input_var(i)) {
@@ -1449,6 +1655,10 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
bool val = defval;
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
node_code += " bool " + inputs[i] + " = " + (val ? "true" : "false") + ";\n";
+ } else if (defval.get_type() == Variant::VECTOR2) {
+ Vector2 val = defval;
+ inputs[i] = "n_in" + itos(node) + "p" + itos(i);
+ node_code += " vec2 " + inputs[i] + " = " + vformat("vec2(%.5f, %.5f);\n", val.x, val.y);
} else if (defval.get_type() == Variant::VECTOR3) {
Vector3 val = defval;
inputs[i] = "n_in" + itos(node) + "p" + itos(i);
@@ -1485,8 +1695,15 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
if (vsnode->is_output_port_expandable(i) && vsnode->_is_output_port_expanded(i)) {
expanded = true;
- if (vsnode->get_output_port_type(i) == VisualShaderNode::PORT_TYPE_VECTOR) {
- output_count += 3;
+ switch (vsnode->get_output_port_type(i)) {
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ output_count += 2;
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR: {
+ output_count += 3;
+ } break;
+ default:
+ break;
}
}
expanded_output_ports.insert(i, expanded);
@@ -1506,6 +1723,9 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
case VisualShaderNode::PORT_TYPE_SCALAR_INT:
outputs[i] = "int " + var_name;
break;
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D:
+ outputs[i] = "vec2 " + var_name;
+ break;
case VisualShaderNode::PORT_TYPE_VECTOR:
outputs[i] = "vec3 " + var_name;
break;
@@ -1515,12 +1735,19 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
case VisualShaderNode::PORT_TYPE_TRANSFORM:
outputs[i] = "mat4 " + var_name;
break;
- default: {
- }
+ default:
+ break;
}
if (expanded_output_ports[i]) {
- if (vsnode->get_output_port_type(i) == VisualShaderNode::PORT_TYPE_VECTOR) {
- j += 3;
+ switch (vsnode->get_output_port_type(i)) {
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ j += 2;
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR: {
+ j += 3;
+ } break;
+ default:
+ break;
}
}
}
@@ -1535,6 +1762,9 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
case VisualShaderNode::PORT_TYPE_SCALAR_INT:
code += " int " + outputs[i] + ";\n";
break;
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D:
+ code += " vec2 " + outputs[i] + ";\n";
+ break;
case VisualShaderNode::PORT_TYPE_VECTOR:
code += " vec3 " + outputs[i] + ";\n";
break;
@@ -1544,12 +1774,19 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
case VisualShaderNode::PORT_TYPE_TRANSFORM:
code += " mat4 " + outputs[i] + ";\n";
break;
- default: {
- }
+ default:
+ break;
}
if (expanded_output_ports[i]) {
- if (vsnode->get_output_port_type(i) == VisualShaderNode::PORT_TYPE_VECTOR) {
- j += 3;
+ switch (vsnode->get_output_port_type(i)) {
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ j += 2;
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR: {
+ j += 3;
+ } break;
+ default:
+ break;
}
}
}
@@ -1565,38 +1802,65 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
for (int i = 0; i < output_count; i++) {
bool new_line_inserted = false;
if (expanded_output_ports[i]) {
- if (vsnode->get_output_port_type(i) == VisualShaderNode::PORT_TYPE_VECTOR) {
- if (vsnode->is_output_port_connected(i + 1) || (for_preview && vsnode->get_output_port_for_preview() == (i + 1))) { // red-component
- if (!new_line_inserted) {
- code += "\n";
- new_line_inserted = true;
+ switch (vsnode->get_output_port_type(i)) {
+ case VisualShaderNode::PORT_TYPE_VECTOR_2D: {
+ if (vsnode->is_output_port_connected(i + 1) || (for_preview && vsnode->get_output_port_for_preview() == (i + 1))) { // red-component
+ if (!new_line_inserted) {
+ code += "\n";
+ new_line_inserted = true;
+ }
+ String r = "n_out" + itos(node) + "p" + itos(i + 1);
+ code += " float " + r + " = n_out" + itos(node) + "p" + itos(i) + ".r;\n";
+ outputs[i + 1] = r;
}
- String r = "n_out" + itos(node) + "p" + itos(i + 1);
- code += " float " + r + " = n_out" + itos(node) + "p" + itos(i) + ".r;\n";
- outputs[i + 1] = r;
- }
- if (vsnode->is_output_port_connected(i + 2) || (for_preview && vsnode->get_output_port_for_preview() == (i + 2))) { // green-component
- if (!new_line_inserted) {
- code += "\n";
- new_line_inserted = true;
+ if (vsnode->is_output_port_connected(i + 2) || (for_preview && vsnode->get_output_port_for_preview() == (i + 2))) { // green-component
+ if (!new_line_inserted) {
+ code += "\n";
+ new_line_inserted = true;
+ }
+ String g = "n_out" + itos(node) + "p" + itos(i + 2);
+ code += " float " + g + " = n_out" + itos(node) + "p" + itos(i) + ".g;\n";
+ outputs[i + 2] = g;
+ }
+
+ i += 2;
+ } break;
+ case VisualShaderNode::PORT_TYPE_VECTOR: {
+ if (vsnode->is_output_port_connected(i + 1) || (for_preview && vsnode->get_output_port_for_preview() == (i + 1))) { // red-component
+ if (!new_line_inserted) {
+ code += "\n";
+ new_line_inserted = true;
+ }
+ String r = "n_out" + itos(node) + "p" + itos(i + 1);
+ code += " float " + r + " = n_out" + itos(node) + "p" + itos(i) + ".r;\n";
+ outputs[i + 1] = r;
}
- String g = "n_out" + itos(node) + "p" + itos(i + 2);
- code += " float " + g + " = n_out" + itos(node) + "p" + itos(i) + ".g;\n";
- outputs[i + 2] = g;
- }
- if (vsnode->is_output_port_connected(i + 3) || (for_preview && vsnode->get_output_port_for_preview() == (i + 3))) { // blue-component
- if (!new_line_inserted) {
- code += "\n";
- new_line_inserted = true;
+ if (vsnode->is_output_port_connected(i + 2) || (for_preview && vsnode->get_output_port_for_preview() == (i + 2))) { // green-component
+ if (!new_line_inserted) {
+ code += "\n";
+ new_line_inserted = true;
+ }
+ String g = "n_out" + itos(node) + "p" + itos(i + 2);
+ code += " float " + g + " = n_out" + itos(node) + "p" + itos(i) + ".g;\n";
+ outputs[i + 2] = g;
}
- String b = "n_out" + itos(node) + "p" + itos(i + 3);
- code += " float " + b + " = n_out" + itos(node) + "p" + itos(i) + ".b;\n";
- outputs[i + 3] = b;
- }
- i += 3;
+ if (vsnode->is_output_port_connected(i + 3) || (for_preview && vsnode->get_output_port_for_preview() == (i + 3))) { // blue-component
+ if (!new_line_inserted) {
+ code += "\n";
+ new_line_inserted = true;
+ }
+ String b = "n_out" + itos(node) + "p" + itos(i + 3);
+ code += " float " + b + " = n_out" + itos(node) + "p" + itos(i) + ".b;\n";
+ outputs[i + 3] = b;
+ }
+
+ i += 3;
+ } break;
+ default:
+ break;
}
}
}
@@ -2066,8 +2330,8 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "TANGENT" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "BINORMAL" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV2, 0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv", "UV" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv2", "UV2" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "point_size", "POINT_SIZE" },
@@ -2082,7 +2346,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "viewport_size", "VIEWPORT_SIZE" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" },
// Node3D, Fragment
@@ -2092,19 +2356,19 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "TANGENT" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "BINORMAL" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "view", "VIEW" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV2, 0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv", "UV" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv2", "UV2" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD, 0.0)" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "point_coord", "POINT_COORD" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "screen_uv", "SCREEN_UV" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_camera", "INV_CAMERA_MATRIX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "camera", "CAMERA_MATRIX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "viewport_size", "VIEWPORT_SIZE" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "front_facing", "FRONT_FACING" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "screen_texture", "SCREEN_TEXTURE" },
@@ -2114,8 +2378,8 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
// Node3D, Light
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV2, 0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv", "UV" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv2", "UV2" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "view", "VIEW" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light", "LIGHT" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_color", "LIGHT_COLOR" },
@@ -2132,18 +2396,18 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "viewport_size", "VIEWPORT_SIZE" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" },
// Canvas Item
// Canvas Item, Vertex
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX, 0.0)" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "vertex", "VERTEX" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv", "UV" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "point_size", "POINT_SIZE" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "texture_pixel_size", "TEXTURE_PIXEL_SIZE" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "canvas", "CANVAS_MATRIX" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "screen", "SCREEN_MATRIX" },
@@ -2154,13 +2418,13 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
// Canvas Item, Fragment
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv", "UV" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_pixel_size", "vec3(SCREEN_PIXEL_SIZE, 1.0)" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD, 0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "screen_uv", "SCREEN_UV" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "texture_pixel_size", "TEXTURE_PIXEL_SIZE" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "screen_pixel_size", "SCREEN_PIXEL_SIZE" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "point_coord", "POINT_COORD" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_light_pass", "AT_LIGHT_PASS" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "texture", "TEXTURE" },
@@ -2169,11 +2433,11 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "specular_shininess", "SPECULAR_SHININESS.rgb" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "specular_shininess_alpha", "SPECULAR_SHININESS.a" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "specular_shininess_texture", "SPECULAR_SHININESS_TEXTURE" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX, 0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "vertex", "VERTEX" },
// Canvas Item, Light
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv", "UV" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
@@ -2185,9 +2449,9 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_vertex", "LIGHT_VERTEX" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "shadow", "SHADOW_MODULATE.rgb" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "shadow_alpha", "SHADOW_MODULATE.a" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD, 0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "screen_uv", "SCREEN_UV" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "texture_pixel_size", "TEXTURE_PIXEL_SIZE" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "point_coord", "POINT_COORD" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SAMPLER, "texture", "TEXTURE" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "specular_shininess", "SPECULAR_SHININESS.rgb" },
@@ -2302,8 +2566,8 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_VECTOR, "quarter_res_color", "QUARTER_RES_COLOR.rgb" },
{ Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_SCALAR, "quarter_res_alpha", "QUARTER_RES_COLOR.a" },
{ Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_SAMPLER, "radiance", "RADIANCE" },
- { Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" },
- { Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_VECTOR, "sky_coords", "vec3(SKY_COORDS, 0.0)" },
+ { Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_VECTOR_2D, "screen_uv", "SCREEN_UV" },
+ { Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_VECTOR_2D, "sky_coords", "SKY_COORDS" },
{ Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Fog, Fog
@@ -2324,11 +2588,11 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0, 0.0, 1.0)" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "vec3(0.0, 1.0, 0.0)" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "vec3(1.0, 0.0, 0.0)" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV, 0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv", "UV" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv2", "UV" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(1.0, 1.0, 0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "viewport_size", "vec2(1.0)" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Spatial, Fragment
@@ -2337,27 +2601,27 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0, 0.0, 1.0)" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "vec3(0.0, 1.0, 0.0)" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "vec3(1.0, 0.0, 0.0)" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV, 0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv", "UV" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv2", "UV" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(1.0, 1.0, 0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "screen_uv", "SCREEN_UV" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "viewport_size", "vec2(1.0)" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Spatial, Light
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.rgb" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0, 0.0, 1.0)" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "vec3(UV, 0.0)" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(1.0, 1.0, 0.0)" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv", "UV" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv2", "UV" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "viewport_size", "vec2(1.0)" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Canvas Item, Vertex
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX, 0.0)" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "vertex", "VERTEX" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv", "UV" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
@@ -2365,20 +2629,20 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = {
// Canvas Item, Fragment
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.rgb" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv", "UV" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "screen_uv", "SCREEN_UV" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Canvas Item, Light
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.rgb" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv", "UV" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0, 0.0, 1.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "vec3(1.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "1.0" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "screen_uv", "SCREEN_UV" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Particles
@@ -2391,7 +2655,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = {
// Sky
- { Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" },
+ { Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_VECTOR_2D, "screen_uv", "SCREEN_UV" },
{ Shader::MODE_SKY, VisualShader::TYPE_SKY, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" },
// Fog
@@ -2455,6 +2719,9 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T
case PORT_TYPE_SCALAR_INT: {
code = " " + p_output_vars[0] + " = 0;\n";
} break;
+ case PORT_TYPE_VECTOR_2D: {
+ code = " " + p_output_vars[0] + " = vec2(0.0);\n";
+ } break;
case PORT_TYPE_VECTOR: {
code = " " + p_output_vars[0] + " = vec3(0.0);\n";
} break;
@@ -2670,7 +2937,9 @@ int VisualShaderNodeUniformRef::get_output_port_count() const {
return 1;
case UniformType::UNIFORM_TYPE_BOOLEAN:
return 1;
- case UniformType::UNIFORM_TYPE_VECTOR:
+ case UniformType::UNIFORM_TYPE_VECTOR2:
+ return 1;
+ case UniformType::UNIFORM_TYPE_VECTOR3:
return 1;
case UniformType::UNIFORM_TYPE_TRANSFORM:
return 1;
@@ -2692,7 +2961,9 @@ VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_output_port
return PortType::PORT_TYPE_SCALAR_INT;
case UniformType::UNIFORM_TYPE_BOOLEAN:
return PortType::PORT_TYPE_BOOLEAN;
- case UniformType::UNIFORM_TYPE_VECTOR:
+ case UniformType::UNIFORM_TYPE_VECTOR2:
+ return PortType::PORT_TYPE_VECTOR_2D;
+ case UniformType::UNIFORM_TYPE_VECTOR3:
return PortType::PORT_TYPE_VECTOR;
case UniformType::UNIFORM_TYPE_TRANSFORM:
return PortType::PORT_TYPE_TRANSFORM;
@@ -2719,7 +2990,9 @@ String VisualShaderNodeUniformRef::get_output_port_name(int p_port) const {
return "";
case UniformType::UNIFORM_TYPE_BOOLEAN:
return "";
- case UniformType::UNIFORM_TYPE_VECTOR:
+ case UniformType::UNIFORM_TYPE_VECTOR2:
+ return "";
+ case UniformType::UNIFORM_TYPE_VECTOR3:
return "";
case UniformType::UNIFORM_TYPE_TRANSFORM:
return "";
@@ -2789,7 +3062,9 @@ VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_port_type_b
return PORT_TYPE_SCALAR_INT;
case UniformType::UNIFORM_TYPE_SAMPLER:
return PORT_TYPE_SAMPLER;
- case UniformType::UNIFORM_TYPE_VECTOR:
+ case UniformType::UNIFORM_TYPE_VECTOR2:
+ return PORT_TYPE_VECTOR_2D;
+ case UniformType::UNIFORM_TYPE_VECTOR3:
return PORT_TYPE_VECTOR;
case UniformType::UNIFORM_TYPE_TRANSFORM:
return PORT_TYPE_TRANSFORM;
@@ -2808,26 +3083,19 @@ String VisualShaderNodeUniformRef::generate_code(Shader::Mode p_mode, VisualShad
if (uniform_name == "[None]") {
return " " + p_output_vars[0] + " = 0.0;\n";
}
- return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
- case UniformType::UNIFORM_TYPE_INT:
- return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
- case UniformType::UNIFORM_TYPE_BOOLEAN:
- return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
- case UniformType::UNIFORM_TYPE_VECTOR:
- return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
- case UniformType::UNIFORM_TYPE_TRANSFORM:
- return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
+ break;
case UniformType::UNIFORM_TYPE_COLOR: {
String code = " " + p_output_vars[0] + " = " + get_uniform_name() + ".rgb;\n";
code += " " + p_output_vars[1] + " = " + get_uniform_name() + ".a;\n";
return code;
} break;
case UniformType::UNIFORM_TYPE_SAMPLER:
- break;
+ return String();
default:
break;
}
- return "";
+
+ return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
}
void VisualShaderNodeUniformRef::_set_uniform_type(int p_uniform_type) {
@@ -2871,8 +3139,8 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "tangent", "TANGENT" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "binormal", "BINORMAL" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "UV:xy" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv2", "UV2:xy" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv", "UV" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv2", "UV2" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "roughness", "ROUGHNESS" },
@@ -2897,7 +3165,7 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = {
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "clearcoat", "CLEARCOAT" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "clearcoat_gloss", "CLEARCOAT_GLOSS" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "anisotropy", "ANISOTROPY" },
- { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "anisotropy_flow", "ANISOTROPY_FLOW:xy" },
+ { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "anisotropy_flow", "ANISOTROPY_FLOW" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "subsurf_scatter", "SSS_STRENGTH" },
{ Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "backlight", "BACKLIGHT" },
@@ -2915,8 +3183,8 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = {
////////////////////////////////////////////////////////////////////////
// Canvas Item, Vertex.
////////////////////////////////////////////////////////////////////////
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "VERTEX:xy" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "UV:xy" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "vertex", "VERTEX" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv", "UV" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "point_size", "POINT_SIZE" },
@@ -2929,7 +3197,7 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = {
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal_map", "NORMAL_MAP" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "normal_map_depth", "NORMAL_MAP_DEPTH" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "light_vertex", "LIGHT_VERTEX" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "shadow_vertex", "SHADOW_VERTEX:xy" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "shadow_vertex", "SHADOW_VERTEX" },
////////////////////////////////////////////////////////////////////////
// Canvas Item, Light.
////////////////////////////////////////////////////////////////////////
@@ -3880,6 +4148,9 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad
case PORT_TYPE_SCALAR_INT:
tk = "0";
break;
+ case PORT_TYPE_VECTOR_2D:
+ tk = "vec2(0.0, 0.0)";
+ break;
case PORT_TYPE_VECTOR:
tk = "vec3(0.0, 0.0, 0.0)";
break;
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index acb33efd30..9f877e08a5 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -214,6 +214,7 @@ public:
enum PortType {
PORT_TYPE_SCALAR,
PORT_TYPE_SCALAR_INT,
+ PORT_TYPE_VECTOR_2D,
PORT_TYPE_VECTOR,
PORT_TYPE_BOOLEAN,
PORT_TYPE_TRANSFORM,
@@ -229,7 +230,7 @@ public:
virtual PortType get_input_port_type(int p_port) const = 0;
virtual String get_input_port_name(int p_port) const = 0;
- virtual void set_input_port_default_value(int p_port, const Variant &p_value);
+ virtual void set_input_port_default_value(int p_port, const Variant &p_value, const Variant &p_prev_value = Variant());
Variant get_input_port_default_value(int p_port) const; // if NIL (default if node does not set anything) is returned, it means no default value is wanted if disconnected, thus no input var must be supplied (empty string will be supplied)
Array get_default_input_values() const;
virtual void set_default_input_values(const Array &p_values);
@@ -311,7 +312,7 @@ protected:
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
- virtual void set_input_port_default_value(int p_port, const Variant &p_value) override;
+ virtual void set_input_port_default_value(int p_port, const Variant &p_value, const Variant &p_prev_value = Variant()) override;
virtual void set_default_input_values(const Array &p_values) override;
virtual void remove_input_port_default_value(int p_port) override;
virtual void clear_default_input_values() override;
@@ -492,7 +493,8 @@ public:
UNIFORM_TYPE_FLOAT,
UNIFORM_TYPE_INT,
UNIFORM_TYPE_BOOLEAN,
- UNIFORM_TYPE_VECTOR,
+ UNIFORM_TYPE_VECTOR2,
+ UNIFORM_TYPE_VECTOR3,
UNIFORM_TYPE_TRANSFORM,
UNIFORM_TYPE_COLOR,
UNIFORM_TYPE_SAMPLER,
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 0cfa9f31f7..9a714fd3dd 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -30,6 +30,65 @@
#include "visual_shader_nodes.h"
+////////////// Vector Base
+
+VisualShaderNodeVectorBase::PortType VisualShaderNodeVectorBase::get_input_port_type(int p_port) const {
+ switch (op_type) {
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_3D:
+ return PORT_TYPE_VECTOR;
+ default:
+ break;
+ }
+ return PORT_TYPE_SCALAR;
+}
+
+VisualShaderNodeVectorBase::PortType VisualShaderNodeVectorBase::get_output_port_type(int p_port) const {
+ switch (op_type) {
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_3D:
+ return PORT_TYPE_VECTOR;
+ default:
+ break;
+ }
+ return PORT_TYPE_SCALAR;
+}
+
+void VisualShaderNodeVectorBase::set_op_type(OpType p_op_type) {
+ ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
+ if (op_type == p_op_type) {
+ return;
+ }
+ op_type = p_op_type;
+ emit_changed();
+}
+
+VisualShaderNodeVectorBase::OpType VisualShaderNodeVectorBase::get_op_type() const {
+ return op_type;
+}
+
+void VisualShaderNodeVectorBase::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeVectorBase::set_op_type);
+ ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeVectorBase::get_op_type);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Vector2,Vector3"), "set_op_type", "get_op_type");
+
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
+ BIND_ENUM_CONSTANT(OP_TYPE_MAX);
+}
+
+Vector<StringName> VisualShaderNodeVectorBase::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("op_type");
+ return props;
+}
+
+VisualShaderNodeVectorBase::VisualShaderNodeVectorBase() {
+}
+
////////////// Constants Base
VisualShaderNodeConstant::VisualShaderNodeConstant() {
@@ -294,10 +353,72 @@ void VisualShaderNodeColorConstant::_bind_methods() {
VisualShaderNodeColorConstant::VisualShaderNodeColorConstant() {
}
-////////////// Vector
+////////////// Vector2
+
+String VisualShaderNodeVec2Constant::get_caption() const {
+ return "Vector2Constant";
+}
+
+int VisualShaderNodeVec2Constant::get_input_port_count() const {
+ return 0;
+}
+
+VisualShaderNodeVec2Constant::PortType VisualShaderNodeVec2Constant::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR_2D;
+}
+
+String VisualShaderNodeVec2Constant::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeVec2Constant::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeVec2Constant::PortType VisualShaderNodeVec2Constant::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR_2D;
+}
+
+String VisualShaderNodeVec2Constant::get_output_port_name(int p_port) const {
+ return ""; //no output port means the editor will be used as port
+}
+
+String VisualShaderNodeVec2Constant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return " " + p_output_vars[0] + " = " + vformat("vec2(%.6f, %.6f)", constant.x, constant.y) + ";\n";
+}
+
+void VisualShaderNodeVec2Constant::set_constant(const Vector2 &p_constant) {
+ if (constant.is_equal_approx(p_constant)) {
+ return;
+ }
+ constant = p_constant;
+ emit_changed();
+}
+
+Vector2 VisualShaderNodeVec2Constant::get_constant() const {
+ return constant;
+}
+
+Vector<StringName> VisualShaderNodeVec2Constant::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("constant");
+ return props;
+}
+
+void VisualShaderNodeVec2Constant::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_constant", "constant"), &VisualShaderNodeVec2Constant::set_constant);
+ ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeVec2Constant::get_constant);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "constant"), "set_constant", "get_constant");
+}
+
+VisualShaderNodeVec2Constant::VisualShaderNodeVec2Constant() {
+}
+
+////////////// Vector3
String VisualShaderNodeVec3Constant::get_caption() const {
- return "VectorConstant";
+ return "Vector3Constant";
}
int VisualShaderNodeVec3Constant::get_input_port_count() const {
@@ -439,7 +560,7 @@ int VisualShaderNodeTexture::get_input_port_count() const {
VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_input_port_type(int p_port) const {
switch (p_port) {
case 0:
- return PORT_TYPE_VECTOR;
+ return PORT_TYPE_VECTOR_2D;
case 1:
return PORT_TYPE_SCALAR;
case 2:
@@ -529,7 +650,7 @@ String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShade
String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String default_uv;
if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
- default_uv = "UV.xy";
+ default_uv = "UV";
} else {
default_uv = "vec2(0.0)";
}
@@ -547,9 +668,9 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
} else if (p_input_vars[1].is_empty()) {
//no lod
- code += " vec4 " + id + "_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n";
+ code += " vec4 " + id + "_read = texture(" + id + ", " + p_input_vars[0] + ");\n";
} else {
- code += " vec4 " + id + "_read = textureLod(" + id + ", " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n";
+ code += " vec4 " + id + "_read = textureLod(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
}
code += " " + p_output_vars[0] + " = " + id + "_read.rgb;\n";
@@ -575,9 +696,9 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
} else if (p_input_vars[1].is_empty()) {
//no lod
- code += " vec4 " + id + "_tex_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n";
+ code += " vec4 " + id + "_tex_read = texture(" + id + ", " + p_input_vars[0] + ");\n";
} else {
- code += " vec4 " + id + "_tex_read = textureLod(" + id + ", " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n";
+ code += " vec4 " + id + "_tex_read = textureLod(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
}
code += " " + p_output_vars[0] + " = " + id + "_tex_read.rgb;\n";
@@ -599,9 +720,9 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
} else if (p_input_vars[1].is_empty()) {
//no lod
- code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + p_input_vars[0] + ".xy, 0.0);\n";
+ code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + p_input_vars[0] + ", 0.0);\n";
} else {
- code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n";
+ code += " vec4 _tex_read = textureLod(SCREEN_TEXTURE, " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
}
code += " " + p_output_vars[0] + " = _tex_read.rgb;\n";
@@ -622,9 +743,9 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
} else if (p_input_vars[1].is_empty()) {
//no lod
- code += " vec4 _tex_read = texture(TEXTURE, " + p_input_vars[0] + ".xy);\n";
+ code += " vec4 _tex_read = texture(TEXTURE, " + p_input_vars[0] + ");\n";
} else {
- code += " vec4 _tex_read = textureLod(TEXTURE, " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n";
+ code += " vec4 _tex_read = textureLod(TEXTURE, " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
}
code += " " + p_output_vars[0] + " = _tex_read.rgb;\n";
@@ -1730,10 +1851,6 @@ int VisualShaderNodeVectorOp::get_input_port_count() const {
return 2;
}
-VisualShaderNodeVectorOp::PortType VisualShaderNodeVectorOp::get_input_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
String VisualShaderNodeVectorOp::get_input_port_name(int p_port) const {
return p_port == 0 ? "a" : "b";
}
@@ -1742,12 +1859,8 @@ int VisualShaderNodeVectorOp::get_output_port_count() const {
return 1;
}
-VisualShaderNodeVectorOp::PortType VisualShaderNodeVectorOp::get_output_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
String VisualShaderNodeVectorOp::get_output_port_name(int p_port) const {
- return "op"; //no output port means the editor will be used as port
+ return "op";
}
String VisualShaderNodeVectorOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
@@ -1778,13 +1891,21 @@ String VisualShaderNodeVectorOp::generate_code(Shader::Mode p_mode, VisualShader
code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
break;
case OP_CROSS:
- code += "cross(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ if (op_type == OP_TYPE_VECTOR_2D) { // not supported
+ code += "vec2(0.0);\n";
+ } else {
+ code += "cross(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ }
break;
case OP_ATAN2:
code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
break;
case OP_REFLECT:
- code += "reflect(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ if (op_type == OP_TYPE_VECTOR_2D) { // not supported
+ code += "vec2(0.0);\n";
+ } else {
+ code += "reflect(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ }
break;
case OP_STEP:
code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
@@ -1796,6 +1917,27 @@ String VisualShaderNodeVectorOp::generate_code(Shader::Mode p_mode, VisualShader
return code;
}
+void VisualShaderNodeVectorOp::set_op_type(OpType p_op_type) {
+ ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
+ if (op_type == p_op_type) {
+ return;
+ }
+ switch (p_op_type) {
+ case OP_TYPE_VECTOR_2D: {
+ set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
+ set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
+ set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
+ } break;
+ default:
+ break;
+ }
+ op_type = p_op_type;
+ emit_changed();
+}
+
void VisualShaderNodeVectorOp::set_operator(Operator p_op) {
ERR_FAIL_INDEX(int(p_op), int(OP_ENUM_SIZE));
if (op == p_op) {
@@ -1810,11 +1952,27 @@ VisualShaderNodeVectorOp::Operator VisualShaderNodeVectorOp::get_operator() cons
}
Vector<StringName> VisualShaderNodeVectorOp::get_editable_properties() const {
- Vector<StringName> props;
+ Vector<StringName> props = VisualShaderNodeVectorBase::get_editable_properties();
props.push_back("operator");
return props;
}
+String VisualShaderNodeVectorOp::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
+ bool invalid_type = false;
+
+ if (op_type == OP_TYPE_VECTOR_2D) {
+ if (op == OP_CROSS || op == OP_REFLECT) {
+ invalid_type = true;
+ }
+ }
+
+ if (invalid_type) {
+ return TTR("Invalid operator for that type.");
+ }
+
+ return String();
+}
+
void VisualShaderNodeVectorOp::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeVectorOp::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeVectorOp::get_operator);
@@ -1837,8 +1995,18 @@ void VisualShaderNodeVectorOp::_bind_methods() {
}
VisualShaderNodeVectorOp::VisualShaderNodeVectorOp() {
- set_input_port_default_value(0, Vector3());
- set_input_port_default_value(1, Vector3());
+ switch (op_type) {
+ case OP_TYPE_VECTOR_2D: {
+ set_input_port_default_value(0, Vector2());
+ set_input_port_default_value(1, Vector2());
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ set_input_port_default_value(0, Vector3());
+ set_input_port_default_value(1, Vector3());
+ } break;
+ default:
+ break;
+ }
}
////////////// Color Op
@@ -2412,10 +2580,6 @@ int VisualShaderNodeVectorFunc::get_input_port_count() const {
return 1;
}
-VisualShaderNodeVectorFunc::PortType VisualShaderNodeVectorFunc::get_input_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
String VisualShaderNodeVectorFunc::get_input_port_name(int p_port) const {
return "";
}
@@ -2424,22 +2588,18 @@ int VisualShaderNodeVectorFunc::get_output_port_count() const {
return 1;
}
-VisualShaderNodeVectorFunc::PortType VisualShaderNodeVectorFunc::get_output_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
String VisualShaderNodeVectorFunc::get_output_port_name(int p_port) const {
- return ""; //no output port means the editor will be used as port
+ return "result";
}
String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- static const char *vec_func_id[FUNC_MAX] = {
+ static const char *funcs[FUNC_MAX] = {
"normalize($)",
- "max(min($, vec3(1.0)), vec3(0.0))",
+ "", // FUNC_SATURATE
"-($)",
"1.0 / ($)",
- "",
- "",
+ "", // FUNC_RGB2HSV
+ "", // FUNC_HSV2RGB
"abs($)",
"acos($)",
"acosh($)",
@@ -2468,12 +2628,37 @@ String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShad
"tan($)",
"tanh($)",
"trunc($)",
- "vec3(1.0, 1.0, 1.0) - $"
+ "" // FUNC_ONEMINUS
};
+ if (func == FUNC_SATURATE) {
+ String code;
+
+ if (op_type == OP_TYPE_VECTOR_2D) {
+ code = "max(min($, vec2(1.0)), vec2(0.0))";
+ } else {
+ code = "max(min($, vec3(1.0)), vec3(0.0))";
+ }
+ return " " + p_output_vars[0] + " = " + code.replace("$", p_input_vars[0]) + ";\n";
+ }
+
+ if (func == FUNC_ONEMINUS) {
+ String code;
+
+ if (op_type == OP_TYPE_VECTOR_2D) {
+ code = "vec2(1.0, 1.0) - $";
+ } else {
+ code = "vec3(1.0, 1.0, 1.0) - $";
+ }
+ return " " + p_output_vars[0] + " = " + code.replace("$", p_input_vars[0]) + ";\n";
+ }
+
String code;
if (func == FUNC_RGB2HSV) {
+ if (op_type == OP_TYPE_VECTOR_2D) { // not supported
+ return " " + p_output_vars[0] + " = vec2(0.0);\n";
+ }
code += " {\n";
code += " vec3 c = " + p_input_vars[0] + ";\n";
code += " vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n";
@@ -2484,6 +2669,9 @@ String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShad
code += " " + p_output_vars[0] + " = vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);\n";
code += " }\n";
} else if (func == FUNC_HSV2RGB) {
+ if (op_type == OP_TYPE_VECTOR_2D) { // not supported
+ return " " + p_output_vars[0] + " = vec2(0.0);\n";
+ }
code += " {\n";
code += " vec3 c = " + p_input_vars[0] + ";\n";
code += " vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n";
@@ -2492,12 +2680,31 @@ String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShad
code += " }\n";
} else {
- code += " " + p_output_vars[0] + " = " + String(vec_func_id[func]).replace("$", p_input_vars[0]) + ";\n";
+ code += " " + p_output_vars[0] + " = " + String(funcs[func]).replace("$", p_input_vars[0]) + ";\n";
}
return code;
}
+void VisualShaderNodeVectorFunc::set_op_type(OpType p_op_type) {
+ ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
+ if (op_type == p_op_type) {
+ return;
+ }
+ switch (p_op_type) {
+ case OP_TYPE_VECTOR_2D: {
+ set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
+ } break;
+ default:
+ break;
+ }
+ op_type = p_op_type;
+ emit_changed();
+}
+
void VisualShaderNodeVectorFunc::set_function(Function p_func) {
ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX));
if (func == p_func) {
@@ -2519,11 +2726,27 @@ VisualShaderNodeVectorFunc::Function VisualShaderNodeVectorFunc::get_function()
}
Vector<StringName> VisualShaderNodeVectorFunc::get_editable_properties() const {
- Vector<StringName> props;
+ Vector<StringName> props = VisualShaderNodeVectorBase::get_editable_properties();
props.push_back("function");
return props;
}
+String VisualShaderNodeVectorFunc::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
+ bool invalid_type = false;
+
+ if (op_type == OP_TYPE_VECTOR_2D) {
+ if (func == FUNC_RGB2HSV || func == FUNC_HSV2RGB) {
+ invalid_type = true;
+ }
+ }
+
+ if (invalid_type) {
+ return TTR("Invalid function for that type.");
+ }
+
+ return String();
+}
+
void VisualShaderNodeVectorFunc::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeVectorFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeVectorFunc::get_function);
@@ -2569,7 +2792,16 @@ void VisualShaderNodeVectorFunc::_bind_methods() {
}
VisualShaderNodeVectorFunc::VisualShaderNodeVectorFunc() {
- set_input_port_default_value(0, Vector3());
+ switch (op_type) {
+ case OP_TYPE_VECTOR_2D: {
+ set_input_port_default_value(0, Vector2());
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ set_input_port_default_value(0, Vector3());
+ } break;
+ default:
+ break;
+ }
}
////////////// ColorFunc
@@ -2754,11 +2986,11 @@ int VisualShaderNodeUVFunc::get_input_port_count() const {
VisualShaderNodeUVFunc::PortType VisualShaderNodeUVFunc::get_input_port_type(int p_port) const {
switch (p_port) {
case 0:
- [[fallthrough]]; // uv
+ return PORT_TYPE_VECTOR_2D; // uv
case 1:
- return PORT_TYPE_VECTOR; // scale
+ return PORT_TYPE_VECTOR_2D; // scale
case 2:
- return PORT_TYPE_VECTOR; // offset & pivot
+ return PORT_TYPE_VECTOR_2D; // offset & pivot
default:
break;
}
@@ -2801,7 +3033,7 @@ int VisualShaderNodeUVFunc::get_output_port_count() const {
}
VisualShaderNodeUVFunc::PortType VisualShaderNodeUVFunc::get_output_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
+ return PORT_TYPE_VECTOR_2D;
}
String VisualShaderNodeUVFunc::get_output_port_name(int p_port) const {
@@ -2818,9 +3050,9 @@ String VisualShaderNodeUVFunc::generate_code(Shader::Mode p_mode, VisualShader::
String uv;
if (p_input_vars[0].is_empty()) {
if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
- uv = "vec3(UV.xy, 0.0)";
+ uv = "UV";
} else {
- uv = "vec3(0.0)";
+ uv = "vec2(0.0)";
}
} else {
uv = vformat("%s", p_input_vars[0]);
@@ -2847,9 +3079,9 @@ void VisualShaderNodeUVFunc::set_function(VisualShaderNodeUVFunc::Function p_fun
return;
}
if (p_func == FUNC_PANNING) {
- set_input_port_default_value(2, Vector3()); // offset
+ set_input_port_default_value(2, Vector2()); // offset
} else { // FUNC_SCALING
- set_input_port_default_value(2, Vector3(0.5, 0.5, 0.0)); // pivot
+ set_input_port_default_value(2, Vector2(0.5, 0.5)); // pivot
}
func = p_func;
emit_changed();
@@ -2877,8 +3109,8 @@ void VisualShaderNodeUVFunc::_bind_methods() {
}
VisualShaderNodeUVFunc::VisualShaderNodeUVFunc() {
- set_input_port_default_value(1, Vector3(1.0, 1.0, 0.0)); // scale
- set_input_port_default_value(2, Vector3()); // offset
+ set_input_port_default_value(1, Vector2(1.0, 1.0)); // scale
+ set_input_port_default_value(2, Vector2()); // offset
}
////////////// Dot Product
@@ -2930,10 +3162,6 @@ int VisualShaderNodeVectorLen::get_input_port_count() const {
return 1;
}
-VisualShaderNodeVectorLen::PortType VisualShaderNodeVectorLen::get_input_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
String VisualShaderNodeVectorLen::get_input_port_name(int p_port) const {
return "";
}
@@ -2950,12 +3178,31 @@ String VisualShaderNodeVectorLen::get_output_port_name(int p_port) const {
return "length";
}
+void VisualShaderNodeVectorLen::set_op_type(OpType p_op_type) {
+ ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
+ if (op_type == p_op_type) {
+ return;
+ }
+ switch (p_op_type) {
+ case OP_TYPE_VECTOR_2D: {
+ set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
+ } break;
+ default:
+ break;
+ }
+ op_type = p_op_type;
+ emit_changed();
+}
+
String VisualShaderNodeVectorLen::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return " " + p_output_vars[0] + " = length(" + p_input_vars[0] + ");\n";
}
VisualShaderNodeVectorLen::VisualShaderNodeVectorLen() {
- set_input_port_default_value(0, Vector3());
+ set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
}
////////////// Determinant
@@ -2996,37 +3243,53 @@ VisualShaderNodeDeterminant::VisualShaderNodeDeterminant() {
set_input_port_default_value(0, Transform3D());
}
-////////////// Scalar Derivative Function
+////////////// Derivative Function
-String VisualShaderNodeScalarDerivativeFunc::get_caption() const {
- return "ScalarDerivativeFunc";
+String VisualShaderNodeDerivativeFunc::get_caption() const {
+ return "DerivativeFunc";
}
-int VisualShaderNodeScalarDerivativeFunc::get_input_port_count() const {
+int VisualShaderNodeDerivativeFunc::get_input_port_count() const {
return 1;
}
-VisualShaderNodeScalarDerivativeFunc::PortType VisualShaderNodeScalarDerivativeFunc::get_input_port_type(int p_port) const {
+VisualShaderNodeDerivativeFunc::PortType VisualShaderNodeDerivativeFunc::get_input_port_type(int p_port) const {
+ switch (op_type) {
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_3D:
+ return PORT_TYPE_VECTOR;
+ default:
+ break;
+ }
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeScalarDerivativeFunc::get_input_port_name(int p_port) const {
- return "";
+String VisualShaderNodeDerivativeFunc::get_input_port_name(int p_port) const {
+ return "p";
}
-int VisualShaderNodeScalarDerivativeFunc::get_output_port_count() const {
+int VisualShaderNodeDerivativeFunc::get_output_port_count() const {
return 1;
}
-VisualShaderNodeScalarDerivativeFunc::PortType VisualShaderNodeScalarDerivativeFunc::get_output_port_type(int p_port) const {
+VisualShaderNodeDerivativeFunc::PortType VisualShaderNodeDerivativeFunc::get_output_port_type(int p_port) const {
+ switch (op_type) {
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_3D:
+ return PORT_TYPE_VECTOR;
+ default:
+ break;
+ }
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeScalarDerivativeFunc::get_output_port_name(int p_port) const {
- return "";
+String VisualShaderNodeDerivativeFunc::get_output_port_name(int p_port) const {
+ return "result";
}
-String VisualShaderNodeScalarDerivativeFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+String VisualShaderNodeDerivativeFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
static const char *functions[FUNC_MAX] = {
"fwidth($)",
"dFdx($)",
@@ -3038,84 +3301,33 @@ String VisualShaderNodeScalarDerivativeFunc::generate_code(Shader::Mode p_mode,
return code;
}
-void VisualShaderNodeScalarDerivativeFunc::set_function(Function p_func) {
- ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX));
- if (func == p_func) {
+void VisualShaderNodeDerivativeFunc::set_op_type(OpType p_op_type) {
+ ERR_FAIL_INDEX((int)p_op_type, int(OP_TYPE_MAX));
+ if (op_type == p_op_type) {
return;
}
- func = p_func;
+ switch (p_op_type) {
+ case OP_TYPE_SCALAR: {
+ set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
+ } break;
+ case OP_TYPE_VECTOR_2D: {
+ set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
+ } break;
+ default:
+ break;
+ }
+ op_type = p_op_type;
emit_changed();
}
-VisualShaderNodeScalarDerivativeFunc::Function VisualShaderNodeScalarDerivativeFunc::get_function() const {
- return func;
-}
-
-Vector<StringName> VisualShaderNodeScalarDerivativeFunc::get_editable_properties() const {
- Vector<StringName> props;
- props.push_back("function");
- return props;
-}
-
-void VisualShaderNodeScalarDerivativeFunc::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeScalarDerivativeFunc::set_function);
- ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeScalarDerivativeFunc::get_function);
-
- ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sum,X,Y"), "set_function", "get_function");
-
- BIND_ENUM_CONSTANT(FUNC_SUM);
- BIND_ENUM_CONSTANT(FUNC_X);
- BIND_ENUM_CONSTANT(FUNC_Y);
- BIND_ENUM_CONSTANT(FUNC_MAX);
-}
-
-VisualShaderNodeScalarDerivativeFunc::VisualShaderNodeScalarDerivativeFunc() {
- set_input_port_default_value(0, 0.0);
-}
-
-////////////// Vector Derivative Function
-
-String VisualShaderNodeVectorDerivativeFunc::get_caption() const {
- return "VectorDerivativeFunc";
-}
-
-int VisualShaderNodeVectorDerivativeFunc::get_input_port_count() const {
- return 1;
-}
-
-VisualShaderNodeVectorDerivativeFunc::PortType VisualShaderNodeVectorDerivativeFunc::get_input_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
-String VisualShaderNodeVectorDerivativeFunc::get_input_port_name(int p_port) const {
- return "";
-}
-
-int VisualShaderNodeVectorDerivativeFunc::get_output_port_count() const {
- return 1;
-}
-
-VisualShaderNodeVectorDerivativeFunc::PortType VisualShaderNodeVectorDerivativeFunc::get_output_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
-String VisualShaderNodeVectorDerivativeFunc::get_output_port_name(int p_port) const {
- return "";
-}
-
-String VisualShaderNodeVectorDerivativeFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- static const char *functions[FUNC_MAX] = {
- "fwidth($)",
- "dFdx($)",
- "dFdy($)"
- };
-
- String code;
- code += " " + p_output_vars[0] + " = " + String(functions[func]).replace("$", p_input_vars[0]) + ";\n";
- return code;
+VisualShaderNodeDerivativeFunc::OpType VisualShaderNodeDerivativeFunc::get_op_type() const {
+ return op_type;
}
-void VisualShaderNodeVectorDerivativeFunc::set_function(Function p_func) {
+void VisualShaderNodeDerivativeFunc::set_function(Function p_func) {
ERR_FAIL_INDEX(int(p_func), int(FUNC_MAX));
if (func == p_func) {
return;
@@ -3124,30 +3336,40 @@ void VisualShaderNodeVectorDerivativeFunc::set_function(Function p_func) {
emit_changed();
}
-VisualShaderNodeVectorDerivativeFunc::Function VisualShaderNodeVectorDerivativeFunc::get_function() const {
+VisualShaderNodeDerivativeFunc::Function VisualShaderNodeDerivativeFunc::get_function() const {
return func;
}
-Vector<StringName> VisualShaderNodeVectorDerivativeFunc::get_editable_properties() const {
+Vector<StringName> VisualShaderNodeDerivativeFunc::get_editable_properties() const {
Vector<StringName> props;
+ props.push_back("op_type");
props.push_back("function");
return props;
}
-void VisualShaderNodeVectorDerivativeFunc::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeVectorDerivativeFunc::set_function);
- ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeVectorDerivativeFunc::get_function);
+void VisualShaderNodeDerivativeFunc::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeDerivativeFunc::set_op_type);
+ ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeDerivativeFunc::get_op_type);
+
+ ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeDerivativeFunc::set_function);
+ ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeDerivativeFunc::get_function);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector3"), "set_op_type", "get_op_type");
ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sum,X,Y"), "set_function", "get_function");
+ BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
+ BIND_ENUM_CONSTANT(OP_TYPE_MAX);
+
BIND_ENUM_CONSTANT(FUNC_SUM);
BIND_ENUM_CONSTANT(FUNC_X);
BIND_ENUM_CONSTANT(FUNC_Y);
BIND_ENUM_CONSTANT(FUNC_MAX);
}
-VisualShaderNodeVectorDerivativeFunc::VisualShaderNodeVectorDerivativeFunc() {
- set_input_port_default_value(0, Vector3());
+VisualShaderNodeDerivativeFunc::VisualShaderNodeDerivativeFunc() {
+ set_input_port_default_value(0, 0.0);
}
////////////// Clamp
@@ -3164,7 +3386,9 @@ VisualShaderNodeClamp::PortType VisualShaderNodeClamp::get_input_port_type(int p
switch (op_type) {
case OP_TYPE_INT:
return PORT_TYPE_SCALAR_INT;
- case OP_TYPE_VECTOR:
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_3D:
return PORT_TYPE_VECTOR;
default:
break;
@@ -3191,7 +3415,9 @@ VisualShaderNodeClamp::PortType VisualShaderNodeClamp::get_output_port_type(int
switch (op_type) {
case OP_TYPE_INT:
return PORT_TYPE_SCALAR_INT;
- case OP_TYPE_VECTOR:
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_3D:
return PORT_TYPE_VECTOR;
default:
break;
@@ -3214,19 +3440,24 @@ void VisualShaderNodeClamp::set_op_type(OpType p_op_type) {
}
switch (p_op_type) {
case OP_TYPE_FLOAT:
- set_input_port_default_value(0, 0.0);
- set_input_port_default_value(1, 0.0);
- set_input_port_default_value(2, 0.0);
+ set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
+ set_input_port_default_value(1, 0.0, get_input_port_default_value(1));
+ set_input_port_default_value(2, 0.0, get_input_port_default_value(2));
break;
case OP_TYPE_INT:
- set_input_port_default_value(0, 0);
- set_input_port_default_value(1, 0);
- set_input_port_default_value(2, 0);
+ set_input_port_default_value(0, 0, get_input_port_default_value(0));
+ set_input_port_default_value(1, 0, get_input_port_default_value(1));
+ set_input_port_default_value(2, 0, get_input_port_default_value(2));
break;
- case OP_TYPE_VECTOR:
- set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
- set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
- set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
+ case OP_TYPE_VECTOR_2D:
+ set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
+ set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
+ set_input_port_default_value(2, Vector2(), get_input_port_default_value(2));
+ break;
+ case OP_TYPE_VECTOR_3D:
+ set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
+ set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
+ set_input_port_default_value(2, Vector3(), get_input_port_default_value(2));
break;
default:
break;
@@ -3249,11 +3480,12 @@ void VisualShaderNodeClamp::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_op_type", "op_type"), &VisualShaderNodeClamp::set_op_type);
ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeClamp::get_op_type);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,Vector"), "set_op_type", "get_op_type");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,Vector2,Vector3"), "set_op_type", "get_op_type");
BIND_ENUM_CONSTANT(OP_TYPE_FLOAT);
BIND_ENUM_CONSTANT(OP_TYPE_INT);
- BIND_ENUM_CONSTANT(OP_TYPE_VECTOR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
BIND_ENUM_CONSTANT(OP_TYPE_MAX);
}
@@ -3273,10 +3505,6 @@ int VisualShaderNodeFaceForward::get_input_port_count() const {
return 3;
}
-VisualShaderNodeFaceForward::PortType VisualShaderNodeFaceForward::get_input_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
String VisualShaderNodeFaceForward::get_input_port_name(int p_port) const {
switch (p_port) {
case 0:
@@ -3294,14 +3522,33 @@ int VisualShaderNodeFaceForward::get_output_port_count() const {
return 1;
}
-VisualShaderNodeFaceForward::PortType VisualShaderNodeFaceForward::get_output_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
String VisualShaderNodeFaceForward::get_output_port_name(int p_port) const {
return "";
}
+void VisualShaderNodeFaceForward::set_op_type(OpType p_op_type) {
+ ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
+ if (op_type == p_op_type) {
+ return;
+ }
+ switch (p_op_type) {
+ case OP_TYPE_VECTOR_2D: {
+ set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
+ set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
+ set_input_port_default_value(2, Vector2(), get_input_port_default_value(2));
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
+ set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
+ set_input_port_default_value(2, Vector3(), get_input_port_default_value(2));
+ } break;
+ default:
+ break;
+ }
+ op_type = p_op_type;
+ emit_changed();
+}
+
String VisualShaderNodeFaceForward::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return " " + p_output_vars[0] + " = faceforward(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
}
@@ -3370,9 +3617,16 @@ int VisualShaderNodeStep::get_input_port_count() const {
VisualShaderNodeStep::PortType VisualShaderNodeStep::get_input_port_type(int p_port) const {
switch (op_type) {
- case OP_TYPE_VECTOR:
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_2D_SCALAR:
+ if (p_port == 1) {
+ return PORT_TYPE_VECTOR_2D;
+ }
+ break;
+ case OP_TYPE_VECTOR_3D:
return PORT_TYPE_VECTOR;
- case OP_TYPE_VECTOR_SCALAR:
+ case OP_TYPE_VECTOR_3D_SCALAR:
if (p_port == 1) {
return PORT_TYPE_VECTOR;
}
@@ -3384,12 +3638,13 @@ VisualShaderNodeStep::PortType VisualShaderNodeStep::get_input_port_type(int p_p
}
String VisualShaderNodeStep::get_input_port_name(int p_port) const {
- if (p_port == 0) {
- return "edge";
- } else if (p_port == 1) {
- return "x";
+ switch (p_port) {
+ case 0:
+ return "edge";
+ case 1:
+ return "x";
}
- return "";
+ return String();
}
int VisualShaderNodeStep::get_output_port_count() const {
@@ -3398,9 +3653,13 @@ int VisualShaderNodeStep::get_output_port_count() const {
VisualShaderNodeStep::PortType VisualShaderNodeStep::get_output_port_type(int p_port) const {
switch (op_type) {
- case OP_TYPE_VECTOR:
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_2D_SCALAR:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_3D:
return PORT_TYPE_VECTOR;
- case OP_TYPE_VECTOR_SCALAR:
+ case OP_TYPE_VECTOR_3D_SCALAR:
return PORT_TYPE_VECTOR;
default:
break;
@@ -3418,30 +3677,26 @@ void VisualShaderNodeStep::set_op_type(OpType p_op_type) {
return;
}
switch (p_op_type) {
- case OP_TYPE_SCALAR:
- if (op_type == OP_TYPE_VECTOR) {
- set_input_port_default_value(0, 0.0); // edge
- }
- if (op_type == OP_TYPE_VECTOR || op_type == OP_TYPE_VECTOR_SCALAR) {
- set_input_port_default_value(1, 0.0); // x
- }
- break;
- case OP_TYPE_VECTOR:
- if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) {
- set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // edge
- }
- if (op_type == OP_TYPE_SCALAR) {
- set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // x
- }
- break;
- case OP_TYPE_VECTOR_SCALAR:
- if (op_type == OP_TYPE_VECTOR) {
- set_input_port_default_value(0, 0.0); // edge
- }
- if (op_type == OP_TYPE_SCALAR) {
- set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // x
- }
- break;
+ case OP_TYPE_SCALAR: {
+ set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
+ set_input_port_default_value(1, 0.0, get_input_port_default_value(1));
+ } break;
+ case OP_TYPE_VECTOR_2D: {
+ set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
+ set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
+ } break;
+ case OP_TYPE_VECTOR_2D_SCALAR: {
+ set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
+ set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
+ set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
+ } break;
+ case OP_TYPE_VECTOR_3D_SCALAR: {
+ set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
+ set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
+ } break;
default:
break;
}
@@ -3467,11 +3722,13 @@ void VisualShaderNodeStep::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_op_type", "op_type"), &VisualShaderNodeStep::set_op_type);
ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeStep::get_op_type);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector2Scalar,Vector3,Vector3Scalar"), "set_op_type", "get_op_type");
BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
- BIND_ENUM_CONSTANT(OP_TYPE_VECTOR);
- BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D_SCALAR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D_SCALAR);
BIND_ENUM_CONSTANT(OP_TYPE_MAX);
}
@@ -3492,9 +3749,16 @@ int VisualShaderNodeSmoothStep::get_input_port_count() const {
VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_input_port_type(int p_port) const {
switch (op_type) {
- case OP_TYPE_VECTOR:
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_2D_SCALAR:
+ if (p_port == 2) {
+ return PORT_TYPE_VECTOR_2D; // x
+ }
+ break;
+ case OP_TYPE_VECTOR_3D:
return PORT_TYPE_VECTOR;
- case OP_TYPE_VECTOR_SCALAR:
+ case OP_TYPE_VECTOR_3D_SCALAR:
if (p_port == 2) {
return PORT_TYPE_VECTOR; // x
}
@@ -3506,14 +3770,15 @@ VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_input_port_
}
String VisualShaderNodeSmoothStep::get_input_port_name(int p_port) const {
- if (p_port == 0) {
- return "edge0";
- } else if (p_port == 1) {
- return "edge1";
- } else if (p_port == 2) {
- return "x";
+ switch (p_port) {
+ case 0:
+ return "edge0";
+ case 1:
+ return "edge1";
+ case 2:
+ return "x";
}
- return "";
+ return String();
}
int VisualShaderNodeSmoothStep::get_output_port_count() const {
@@ -3522,9 +3787,13 @@ int VisualShaderNodeSmoothStep::get_output_port_count() const {
VisualShaderNodeSmoothStep::PortType VisualShaderNodeSmoothStep::get_output_port_type(int p_port) const {
switch (op_type) {
- case OP_TYPE_VECTOR:
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_2D_SCALAR:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_3D:
return PORT_TYPE_VECTOR;
- case OP_TYPE_VECTOR_SCALAR:
+ case OP_TYPE_VECTOR_3D_SCALAR:
return PORT_TYPE_VECTOR;
default:
break;
@@ -3543,31 +3812,29 @@ void VisualShaderNodeSmoothStep::set_op_type(OpType p_op_type) {
}
switch (p_op_type) {
case OP_TYPE_SCALAR:
- if (op_type == OP_TYPE_VECTOR) {
- set_input_port_default_value(0, 0.0); // edge0
- set_input_port_default_value(1, 0.0); // edge1
- }
- if (op_type == OP_TYPE_VECTOR || op_type == OP_TYPE_VECTOR_SCALAR) {
- set_input_port_default_value(2, 0.0); // x
- }
- break;
- case OP_TYPE_VECTOR:
- if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) {
- set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // edge0
- set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // edge1
- }
- if (op_type == OP_TYPE_SCALAR) {
- set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); // x
- }
- break;
- case OP_TYPE_VECTOR_SCALAR:
- if (op_type == OP_TYPE_VECTOR) {
- set_input_port_default_value(0, 0.0); // edge0
- set_input_port_default_value(1, 0.0); // edge1
- }
- if (op_type == OP_TYPE_SCALAR) {
- set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); // x
- }
+ set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); // edge0
+ set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); // edge1
+ set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); // x
+ break;
+ case OP_TYPE_VECTOR_2D:
+ set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); // edge0
+ set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); // edge1
+ set_input_port_default_value(2, Vector2(), get_input_port_default_value(2)); // x
+ break;
+ case OP_TYPE_VECTOR_2D_SCALAR:
+ set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); // edge0
+ set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); // edge1
+ set_input_port_default_value(2, Vector2(), get_input_port_default_value(2)); // x
+ break;
+ case OP_TYPE_VECTOR_3D:
+ set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); // edge0
+ set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); // edge1
+ set_input_port_default_value(2, Vector3(), get_input_port_default_value(2)); // x
+ break;
+ case OP_TYPE_VECTOR_3D_SCALAR:
+ set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); // edge0
+ set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); // edge1
+ set_input_port_default_value(2, Vector3(), get_input_port_default_value(2)); // x
break;
default:
break;
@@ -3594,18 +3861,20 @@ void VisualShaderNodeSmoothStep::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_op_type", "op_type"), &VisualShaderNodeSmoothStep::set_op_type);
ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeSmoothStep::get_op_type);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector2Scalar,Vector3,Vector3Scalar"), "set_op_type", "get_op_type");
BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
- BIND_ENUM_CONSTANT(OP_TYPE_VECTOR);
- BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D_SCALAR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D_SCALAR);
BIND_ENUM_CONSTANT(OP_TYPE_MAX);
}
VisualShaderNodeSmoothStep::VisualShaderNodeSmoothStep() {
- set_input_port_default_value(0, 0.0);
- set_input_port_default_value(1, 0.0);
- set_input_port_default_value(2, 0.0);
+ set_input_port_default_value(0, 0.0); // edge0
+ set_input_port_default_value(1, 1.0); // edge1
+ set_input_port_default_value(2, 0.5); // x
}
////////////// Distance
@@ -3618,17 +3887,14 @@ int VisualShaderNodeVectorDistance::get_input_port_count() const {
return 2;
}
-VisualShaderNodeVectorDistance::PortType VisualShaderNodeVectorDistance::get_input_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
String VisualShaderNodeVectorDistance::get_input_port_name(int p_port) const {
- if (p_port == 0) {
- return "p0";
- } else if (p_port == 1) {
- return "p1";
+ switch (p_port) {
+ case 0:
+ return "a";
+ case 1:
+ return "b";
}
- return "";
+ return String();
}
int VisualShaderNodeVectorDistance::get_output_port_count() const {
@@ -3643,13 +3909,34 @@ String VisualShaderNodeVectorDistance::get_output_port_name(int p_port) const {
return "";
}
+void VisualShaderNodeVectorDistance::set_op_type(OpType p_op_type) {
+ ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
+ if (op_type == p_op_type) {
+ return;
+ }
+ switch (p_op_type) {
+ case OP_TYPE_VECTOR_2D: {
+ set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); // a
+ set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); // b
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); // a
+ set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); // b
+ } break;
+ default:
+ break;
+ }
+ op_type = p_op_type;
+ emit_changed();
+}
+
String VisualShaderNodeVectorDistance::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return " " + p_output_vars[0] + " = distance(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
}
VisualShaderNodeVectorDistance::VisualShaderNodeVectorDistance() {
- set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
- set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // a
+ set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); // b
}
////////////// Refract Vector
@@ -3671,14 +3958,15 @@ VisualShaderNodeVectorRefract::PortType VisualShaderNodeVectorRefract::get_input
}
String VisualShaderNodeVectorRefract::get_input_port_name(int p_port) const {
- if (p_port == 0) {
- return "I";
- } else if (p_port == 1) {
- return "N";
- } else if (p_port == 2) {
- return "eta";
+ switch (p_port) {
+ case 0:
+ return "I";
+ case 1:
+ return "N";
+ case 2:
+ return "eta";
}
- return "";
+ return String();
}
int VisualShaderNodeVectorRefract::get_output_port_count() const {
@@ -3715,9 +4003,16 @@ int VisualShaderNodeMix::get_input_port_count() const {
VisualShaderNodeMix::PortType VisualShaderNodeMix::get_input_port_type(int p_port) const {
switch (op_type) {
- case OP_TYPE_VECTOR:
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_2D_SCALAR:
+ if (p_port == 2) {
+ break;
+ }
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_3D:
return PORT_TYPE_VECTOR;
- case OP_TYPE_VECTOR_SCALAR:
+ case OP_TYPE_VECTOR_3D_SCALAR:
if (p_port == 2) {
break;
}
@@ -3744,9 +4039,13 @@ int VisualShaderNodeMix::get_output_port_count() const {
VisualShaderNodeMix::PortType VisualShaderNodeMix::get_output_port_type(int p_port) const {
switch (op_type) {
- case OP_TYPE_VECTOR:
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_2D_SCALAR:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_3D:
return PORT_TYPE_VECTOR;
- case OP_TYPE_VECTOR_SCALAR:
+ case OP_TYPE_VECTOR_3D_SCALAR:
return PORT_TYPE_VECTOR;
default:
break;
@@ -3764,27 +4063,31 @@ void VisualShaderNodeMix::set_op_type(OpType p_op_type) {
return;
}
switch (p_op_type) {
- case OP_TYPE_SCALAR:
- set_input_port_default_value(0, 0.0); // a
- set_input_port_default_value(1, 1.0); // b
- if (op_type == OP_TYPE_VECTOR) {
- set_input_port_default_value(2, 0.5); // weight
- }
- break;
- case OP_TYPE_VECTOR:
- set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // a
- set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); // b
- if (op_type == OP_TYPE_SCALAR || op_type == OP_TYPE_VECTOR_SCALAR) {
- set_input_port_default_value(2, Vector3(0.5, 0.5, 0.5)); // weight
- }
- break;
- case OP_TYPE_VECTOR_SCALAR:
- set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); // a
- set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); // b
- if (op_type == OP_TYPE_VECTOR) {
- set_input_port_default_value(2, 0.5); // weight
- }
- break;
+ case OP_TYPE_SCALAR: {
+ set_input_port_default_value(0, 0.0, get_input_port_default_value(0)); // a
+ set_input_port_default_value(1, 0.0, get_input_port_default_value(1)); // b
+ set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); // weight
+ } break;
+ case OP_TYPE_VECTOR_2D: {
+ set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); // a
+ set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); // b
+ set_input_port_default_value(2, Vector2(), get_input_port_default_value(2)); // weight
+ } break;
+ case OP_TYPE_VECTOR_2D_SCALAR: {
+ set_input_port_default_value(0, Vector2(), get_input_port_default_value(0)); // a
+ set_input_port_default_value(1, Vector2(), get_input_port_default_value(1)); // b
+ set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); // weight
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); // a
+ set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); // b
+ set_input_port_default_value(2, Vector3(), get_input_port_default_value(2)); // weight
+ } break;
+ case OP_TYPE_VECTOR_3D_SCALAR: {
+ set_input_port_default_value(0, Vector3(), get_input_port_default_value(0)); // a
+ set_input_port_default_value(1, Vector3(), get_input_port_default_value(1)); // b
+ set_input_port_default_value(2, 0.0, get_input_port_default_value(2)); // weight
+ } break;
default:
break;
}
@@ -3810,11 +4113,13 @@ void VisualShaderNodeMix::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_op_type", "op_type"), &VisualShaderNodeMix::set_op_type);
ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeMix::get_op_type);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector,VectorScalar"), "set_op_type", "get_op_type");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector2Scalar,Vector3,Vector3Scalar"), "set_op_type", "get_op_type");
BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
- BIND_ENUM_CONSTANT(OP_TYPE_VECTOR);
- BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_SCALAR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D_SCALAR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D_SCALAR);
BIND_ENUM_CONSTANT(OP_TYPE_MAX);
}
@@ -3831,7 +4136,15 @@ String VisualShaderNodeVectorCompose::get_caption() const {
}
int VisualShaderNodeVectorCompose::get_input_port_count() const {
- return 3;
+ switch (op_type) {
+ case OP_TYPE_VECTOR_2D:
+ return 2;
+ case OP_TYPE_VECTOR_3D:
+ return 3;
+ default:
+ break;
+ }
+ return 0;
}
VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_input_port_type(int p_port) const {
@@ -3839,29 +4152,80 @@ VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_input
}
String VisualShaderNodeVectorCompose::get_input_port_name(int p_port) const {
- if (p_port == 0) {
- return "x";
- } else if (p_port == 1) {
- return "y";
- } else {
- return "z";
+ switch (op_type) {
+ case OP_TYPE_VECTOR_2D: {
+ switch (p_port) {
+ case 0:
+ return "x";
+ case 1:
+ return "y";
+ }
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ switch (p_port) {
+ case 0:
+ return "x";
+ case 1:
+ return "y";
+ case 2:
+ return "z";
+ }
+ } break;
+ default:
+ break;
}
+ return String();
}
int VisualShaderNodeVectorCompose::get_output_port_count() const {
return 1;
}
-VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_output_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
String VisualShaderNodeVectorCompose::get_output_port_name(int p_port) const {
return "vec";
}
+void VisualShaderNodeVectorCompose::set_op_type(OpType p_op_type) {
+ ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
+ if (op_type == p_op_type) {
+ return;
+ }
+ switch (p_op_type) {
+ case OP_TYPE_VECTOR_2D: {
+ float p1 = get_input_port_default_value(0);
+ float p2 = get_input_port_default_value(1);
+
+ set_input_port_default_value(0, p1);
+ set_input_port_default_value(1, p2);
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ float p1 = get_input_port_default_value(0);
+ float p2 = get_input_port_default_value(1);
+
+ set_input_port_default_value(0, p1);
+ set_input_port_default_value(1, p2);
+ set_input_port_default_value(2, 0.0);
+ } break;
+ default:
+ break;
+ }
+ op_type = p_op_type;
+ emit_changed();
+}
+
String VisualShaderNodeVectorCompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return " " + p_output_vars[0] + " = vec3(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
+ String code;
+ switch (op_type) {
+ case OP_TYPE_VECTOR_2D: {
+ code += " " + p_output_vars[0] + " = vec2(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ code += " " + p_output_vars[0] + " = vec3(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n";
+ } break;
+ default:
+ break;
+ }
+ return code;
}
VisualShaderNodeVectorCompose::VisualShaderNodeVectorCompose() {
@@ -3928,16 +4292,20 @@ int VisualShaderNodeVectorDecompose::get_input_port_count() const {
return 1;
}
-VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_input_port_type(int p_port) const {
- return PORT_TYPE_VECTOR;
-}
-
String VisualShaderNodeVectorDecompose::get_input_port_name(int p_port) const {
return "vec";
}
int VisualShaderNodeVectorDecompose::get_output_port_count() const {
- return 3;
+ switch (op_type) {
+ case OP_TYPE_VECTOR_2D:
+ return 2;
+ case OP_TYPE_VECTOR_3D:
+ return 3;
+ default:
+ break;
+ }
+ return 0;
}
VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_output_port_type(int p_port) const {
@@ -3945,25 +4313,70 @@ VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_o
}
String VisualShaderNodeVectorDecompose::get_output_port_name(int p_port) const {
- if (p_port == 0) {
- return "x";
- } else if (p_port == 1) {
- return "y";
- } else {
- return "z";
+ switch (op_type) {
+ case OP_TYPE_VECTOR_2D: {
+ switch (p_port) {
+ case 0:
+ return "x";
+ case 1:
+ return "y";
+ }
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ switch (p_port) {
+ case 0:
+ return "x";
+ case 1:
+ return "y";
+ case 2:
+ return "z";
+ }
+ } break;
+ default:
+ break;
}
+ return String();
+}
+
+void VisualShaderNodeVectorDecompose::set_op_type(OpType p_op_type) {
+ ERR_FAIL_INDEX(int(p_op_type), int(OP_TYPE_MAX));
+ if (op_type == p_op_type) {
+ return;
+ }
+ switch (p_op_type) {
+ case OP_TYPE_VECTOR_2D: {
+ set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
+ } break;
+ default:
+ break;
+ }
+ op_type = p_op_type;
+ emit_changed();
}
String VisualShaderNodeVectorDecompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String code;
- code += " " + p_output_vars[0] + " = " + p_input_vars[0] + ".x;\n";
- code += " " + p_output_vars[1] + " = " + p_input_vars[0] + ".y;\n";
- code += " " + p_output_vars[2] + " = " + p_input_vars[0] + ".z;\n";
+ switch (op_type) {
+ case OP_TYPE_VECTOR_2D: {
+ code += " " + p_output_vars[0] + " = " + p_input_vars[0] + ".x;\n";
+ code += " " + p_output_vars[1] + " = " + p_input_vars[0] + ".y;\n";
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ code += " " + p_output_vars[0] + " = " + p_input_vars[0] + ".x;\n";
+ code += " " + p_output_vars[1] + " = " + p_input_vars[0] + ".y;\n";
+ code += " " + p_output_vars[2] + " = " + p_input_vars[0] + ".z;\n";
+ } break;
+ default:
+ break;
+ }
return code;
}
VisualShaderNodeVectorDecompose::VisualShaderNodeVectorDecompose() {
- set_input_port_default_value(0, Vector3());
+ set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
}
////////////// Transform Decompose
@@ -4613,10 +5026,110 @@ Vector<StringName> VisualShaderNodeColorUniform::get_editable_properties() const
VisualShaderNodeColorUniform::VisualShaderNodeColorUniform() {
}
-////////////// Vector Uniform
+////////////// Vector2 Uniform
+
+String VisualShaderNodeVec2Uniform::get_caption() const {
+ return "Vector2Uniform";
+}
+
+int VisualShaderNodeVec2Uniform::get_input_port_count() const {
+ return 0;
+}
+
+VisualShaderNodeVec2Uniform::PortType VisualShaderNodeVec2Uniform::get_input_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR_2D;
+}
+
+String VisualShaderNodeVec2Uniform::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeVec2Uniform::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeVec2Uniform::PortType VisualShaderNodeVec2Uniform::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR_2D;
+}
+
+String VisualShaderNodeVec2Uniform::get_output_port_name(int p_port) const {
+ return String();
+}
+
+void VisualShaderNodeVec2Uniform::set_default_value_enabled(bool p_enabled) {
+ default_value_enabled = p_enabled;
+ emit_changed();
+}
+
+bool VisualShaderNodeVec2Uniform::is_default_value_enabled() const {
+ return default_value_enabled;
+}
+
+void VisualShaderNodeVec2Uniform::set_default_value(const Vector2 &p_value) {
+ default_value = p_value;
+ emit_changed();
+}
+
+Vector2 VisualShaderNodeVec2Uniform::get_default_value() const {
+ return default_value;
+}
+
+String VisualShaderNodeVec2Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
+ String code = _get_qual_str() + "uniform vec2 " + get_uniform_name();
+ if (default_value_enabled) {
+ code += vformat(" = vec2(%.6f, %.6f)", default_value.x, default_value.y);
+ }
+ code += ";\n";
+ return code;
+}
+
+String VisualShaderNodeVec2Uniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return " " + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
+}
+
+void VisualShaderNodeVec2Uniform::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec2Uniform::set_default_value_enabled);
+ ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec2Uniform::is_default_value_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec2Uniform::set_default_value);
+ ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec2Uniform::get_default_value);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "default_value"), "set_default_value", "get_default_value");
+}
+
+bool VisualShaderNodeVec2Uniform::is_show_prop_names() const {
+ return true;
+}
+
+bool VisualShaderNodeVec2Uniform::is_use_prop_slots() const {
+ return true;
+}
+
+bool VisualShaderNodeVec2Uniform::is_qualifier_supported(Qualifier p_qual) const {
+ return true; // all qualifiers are supported
+}
+
+bool VisualShaderNodeVec2Uniform::is_convertible_to_constant() const {
+ return true; // conversion is allowed
+}
+
+Vector<StringName> VisualShaderNodeVec2Uniform::get_editable_properties() const {
+ Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
+ props.push_back("default_value_enabled");
+ if (default_value_enabled) {
+ props.push_back("default_value");
+ }
+ return props;
+}
+
+VisualShaderNodeVec2Uniform::VisualShaderNodeVec2Uniform() {
+}
+
+////////////// Vector3 Uniform
String VisualShaderNodeVec3Uniform::get_caption() const {
- return "VectorUniform";
+ return "Vector3Uniform";
}
int VisualShaderNodeVec3Uniform::get_input_port_count() const {
@@ -4831,7 +5344,7 @@ int VisualShaderNodeTextureUniform::get_input_port_count() const {
}
VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_input_port_type(int p_port) const {
- return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
+ return p_port == 0 ? PORT_TYPE_VECTOR_2D : PORT_TYPE_SCALAR;
}
String VisualShaderNodeTextureUniform::get_input_port_name(int p_port) const {
@@ -4979,7 +5492,7 @@ bool VisualShaderNodeTextureUniform::is_code_generated() const {
String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
String default_uv;
if (p_mode == Shader::MODE_CANVAS_ITEM || p_mode == Shader::MODE_SPATIAL) {
- default_uv = "UV.xy";
+ default_uv = "UV";
} else {
default_uv = "vec2(0.0)";
}
@@ -4994,9 +5507,9 @@ String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, Visual
}
} else if (p_input_vars[1].is_empty()) {
//no lod
- code += " vec4 n_tex_read = texture(" + id + ", " + p_input_vars[0] + ".xy);\n";
+ code += " vec4 n_tex_read = texture(" + id + ", " + p_input_vars[0] + ");\n";
} else {
- code += " vec4 n_tex_read = textureLod(" + id + ", " + p_input_vars[0] + ".xy, " + p_input_vars[1] + ");\n";
+ code += " vec4 n_tex_read = textureLod(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
}
code += " " + p_output_vars[0] + " = n_tex_read.rgb;\n";
@@ -5562,7 +6075,9 @@ VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_input_port_type(int
switch (op_type) {
case OP_TYPE_INT:
return PORT_TYPE_SCALAR_INT;
- case OP_TYPE_VECTOR:
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_3D:
return PORT_TYPE_VECTOR;
case OP_TYPE_BOOLEAN:
return PORT_TYPE_BOOLEAN;
@@ -5596,7 +6111,9 @@ VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_output_port_type(in
switch (op_type) {
case OP_TYPE_INT:
return PORT_TYPE_SCALAR_INT;
- case OP_TYPE_VECTOR:
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_3D:
return PORT_TYPE_VECTOR;
case OP_TYPE_BOOLEAN:
return PORT_TYPE_BOOLEAN;
@@ -5619,16 +6136,20 @@ void VisualShaderNodeSwitch::set_op_type(OpType p_op_type) {
}
switch (p_op_type) {
case OP_TYPE_FLOAT:
- set_input_port_default_value(1, 1.0);
- set_input_port_default_value(2, 0.0);
+ set_input_port_default_value(1, 1.0, get_input_port_default_value(1));
+ set_input_port_default_value(2, 0.0, get_input_port_default_value(2));
break;
case OP_TYPE_INT:
- set_input_port_default_value(1, 1);
- set_input_port_default_value(2, 0);
+ set_input_port_default_value(1, 1, get_input_port_default_value(1));
+ set_input_port_default_value(2, 0, get_input_port_default_value(2));
+ break;
+ case OP_TYPE_VECTOR_2D:
+ set_input_port_default_value(1, Vector2(1.0, 1.0), get_input_port_default_value(1));
+ set_input_port_default_value(2, Vector2(0.0, 0.0), get_input_port_default_value(2));
break;
- case OP_TYPE_VECTOR:
- set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0));
- set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
+ case OP_TYPE_VECTOR_3D:
+ set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0), get_input_port_default_value(1));
+ set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0), get_input_port_default_value(2));
break;
case OP_TYPE_BOOLEAN:
set_input_port_default_value(1, true);
@@ -5659,11 +6180,12 @@ void VisualShaderNodeSwitch::_bind_methods() { // static
ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeSwitch::set_op_type);
ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeSwitch::get_op_type);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,Vector,Boolean,Transform"), "set_op_type", "get_op_type");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Float,Int,Vector2,Vector3,Boolean,Transform"), "set_op_type", "get_op_type");
BIND_ENUM_CONSTANT(OP_TYPE_FLOAT);
BIND_ENUM_CONSTANT(OP_TYPE_INT);
- BIND_ENUM_CONSTANT(OP_TYPE_VECTOR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
BIND_ENUM_CONSTANT(OP_TYPE_BOOLEAN);
BIND_ENUM_CONSTANT(OP_TYPE_TRANSFORM);
BIND_ENUM_CONSTANT(OP_TYPE_MAX);
@@ -5893,7 +6415,9 @@ VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(i
return PORT_TYPE_SCALAR;
case CTYPE_SCALAR_INT:
return PORT_TYPE_SCALAR_INT;
- case CTYPE_VECTOR:
+ case CTYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case CTYPE_VECTOR_3D:
return PORT_TYPE_VECTOR;
case CTYPE_BOOLEAN:
return PORT_TYPE_BOOLEAN;
@@ -5965,7 +6489,7 @@ String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader:
String code;
switch (comparison_type) {
- case CTYPE_SCALAR:
+ case CTYPE_SCALAR: {
if (func == FUNC_EQUAL) {
code += " " + p_output_vars[0] + " = (abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ") < " + p_input_vars[2] + ");";
} else if (func == FUNC_NOT_EQUAL) {
@@ -5973,33 +6497,34 @@ String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader:
} else {
code += " " + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", operators[func]) + ";\n";
}
- break;
-
- case CTYPE_SCALAR_INT:
+ } break;
+ case CTYPE_SCALAR_INT: {
code += " " + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", operators[func]) + ";\n";
- break;
-
- case CTYPE_VECTOR:
+ } break;
+ case CTYPE_VECTOR_2D: {
+ code += " {\n";
+ code += " bvec2 _bv = " + String(functions[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n";
+ code += " " + p_output_vars[0] + " = " + String(conditions[condition]).replace("$", "_bv") + ";\n";
+ code += " }\n";
+ } break;
+ case CTYPE_VECTOR_3D: {
code += " {\n";
code += " bvec3 _bv = " + String(functions[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n";
code += " " + p_output_vars[0] + " = " + String(conditions[condition]).replace("$", "_bv") + ";\n";
code += " }\n";
- break;
-
- case CTYPE_BOOLEAN:
+ } break;
+ case CTYPE_BOOLEAN: {
if (func > FUNC_NOT_EQUAL) {
return " " + p_output_vars[0] + " = false;\n";
}
code += " " + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", operators[func]) + ";\n";
- break;
-
- case CTYPE_TRANSFORM:
+ } break;
+ case CTYPE_TRANSFORM: {
if (func > FUNC_NOT_EQUAL) {
return " " + p_output_vars[0] + " = false;\n";
}
code += " " + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", operators[func]) + ";\n";
- break;
-
+ } break;
default:
break;
}
@@ -6013,18 +6538,23 @@ void VisualShaderNodeCompare::set_comparison_type(ComparisonType p_comparison_ty
}
switch (p_comparison_type) {
case CTYPE_SCALAR:
- set_input_port_default_value(0, 0.0);
- set_input_port_default_value(1, 0.0);
+ set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
+ set_input_port_default_value(1, 0.0, get_input_port_default_value(1));
simple_decl = true;
break;
case CTYPE_SCALAR_INT:
- set_input_port_default_value(0, 0);
- set_input_port_default_value(1, 0);
+ set_input_port_default_value(0, 0, get_input_port_default_value(0));
+ set_input_port_default_value(1, 0, get_input_port_default_value(1));
simple_decl = true;
break;
- case CTYPE_VECTOR:
- set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
- set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
+ case CTYPE_VECTOR_2D:
+ set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
+ set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
+ simple_decl = false;
+ break;
+ case CTYPE_VECTOR_3D:
+ set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
+ set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
simple_decl = false;
break;
case CTYPE_BOOLEAN:
@@ -6078,7 +6608,7 @@ Vector<StringName> VisualShaderNodeCompare::get_editable_properties() const {
Vector<StringName> props;
props.push_back("type");
props.push_back("function");
- if (comparison_type == CTYPE_VECTOR) {
+ if (comparison_type == CTYPE_VECTOR_2D || comparison_type == CTYPE_VECTOR_3D) {
props.push_back("condition");
}
return props;
@@ -6094,13 +6624,14 @@ void VisualShaderNodeCompare::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_condition", "condition"), &VisualShaderNodeCompare::set_condition);
ClassDB::bind_method(D_METHOD("get_condition"), &VisualShaderNodeCompare::get_condition);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Float,Int,Vector,Boolean,Transform"), "set_comparison_type", "get_comparison_type");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Float,Int,Vector2,Vector3,Boolean,Transform"), "set_comparison_type", "get_comparison_type");
ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "a == b,a != b,a > b,a >= b,a < b,a <= b"), "set_function", "get_function");
ADD_PROPERTY(PropertyInfo(Variant::INT, "condition", PROPERTY_HINT_ENUM, "All,Any"), "set_condition", "get_condition");
BIND_ENUM_CONSTANT(CTYPE_SCALAR);
BIND_ENUM_CONSTANT(CTYPE_SCALAR_INT);
- BIND_ENUM_CONSTANT(CTYPE_VECTOR);
+ BIND_ENUM_CONSTANT(CTYPE_VECTOR_2D);
+ BIND_ENUM_CONSTANT(CTYPE_VECTOR_3D);
BIND_ENUM_CONSTANT(CTYPE_BOOLEAN);
BIND_ENUM_CONSTANT(CTYPE_TRANSFORM);
BIND_ENUM_CONSTANT(CTYPE_MAX);
@@ -6135,8 +6666,13 @@ int VisualShaderNodeMultiplyAdd::get_input_port_count() const {
}
VisualShaderNodeMultiplyAdd::PortType VisualShaderNodeMultiplyAdd::get_input_port_type(int p_port) const {
- if (op_type == OP_TYPE_VECTOR) {
- return PORT_TYPE_VECTOR;
+ switch (op_type) {
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_3D:
+ return PORT_TYPE_VECTOR;
+ default:
+ break;
}
return PORT_TYPE_SCALAR;
}
@@ -6157,11 +6693,15 @@ int VisualShaderNodeMultiplyAdd::get_output_port_count() const {
}
VisualShaderNodeMultiplyAdd::PortType VisualShaderNodeMultiplyAdd::get_output_port_type(int p_port) const {
- if (op_type == OP_TYPE_SCALAR) {
- return PORT_TYPE_SCALAR;
- } else {
- return PORT_TYPE_VECTOR;
+ switch (op_type) {
+ case OP_TYPE_VECTOR_2D:
+ return PORT_TYPE_VECTOR_2D;
+ case OP_TYPE_VECTOR_3D:
+ return PORT_TYPE_VECTOR;
+ default:
+ break;
}
+ return PORT_TYPE_SCALAR;
}
String VisualShaderNodeMultiplyAdd::get_output_port_name(int p_port) const {
@@ -6178,16 +6718,21 @@ void VisualShaderNodeMultiplyAdd::set_op_type(OpType p_op_type) {
return;
}
switch (p_op_type) {
- case OP_TYPE_SCALAR:
- set_input_port_default_value(0, 0.0);
- set_input_port_default_value(1, 0.0);
- set_input_port_default_value(2, 0.0);
- break;
- case OP_TYPE_VECTOR:
- set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
- set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
- set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
- break;
+ case OP_TYPE_SCALAR: {
+ set_input_port_default_value(0, 0.0, get_input_port_default_value(0));
+ set_input_port_default_value(1, 0.0, get_input_port_default_value(1));
+ set_input_port_default_value(2, 0.0, get_input_port_default_value(2));
+ } break;
+ case OP_TYPE_VECTOR_2D: {
+ set_input_port_default_value(0, Vector2(), get_input_port_default_value(0));
+ set_input_port_default_value(1, Vector2(), get_input_port_default_value(1));
+ set_input_port_default_value(2, Vector2(), get_input_port_default_value(2));
+ } break;
+ case OP_TYPE_VECTOR_3D: {
+ set_input_port_default_value(0, Vector3(), get_input_port_default_value(0));
+ set_input_port_default_value(1, Vector3(), get_input_port_default_value(1));
+ set_input_port_default_value(2, Vector3(), get_input_port_default_value(2));
+ } break;
default:
break;
}
@@ -6209,10 +6754,11 @@ void VisualShaderNodeMultiplyAdd::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeMultiplyAdd::set_op_type);
ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeMultiplyAdd::get_op_type);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector"), "set_op_type", "get_op_type");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector2,Vector3"), "set_op_type", "get_op_type");
BIND_ENUM_CONSTANT(OP_TYPE_SCALAR);
- BIND_ENUM_CONSTANT(OP_TYPE_VECTOR);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_2D);
+ BIND_ENUM_CONSTANT(OP_TYPE_VECTOR_3D);
BIND_ENUM_CONSTANT(OP_TYPE_MAX);
}
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index bf5777a3fb..5c7a674d34 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -34,6 +34,49 @@
#include "scene/resources/visual_shader.h"
///////////////////////////////////////
+/// Vector Base Node
+///////////////////////////////////////
+
+class VisualShaderNodeVectorBase : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeVectorBase, VisualShaderNode);
+
+public:
+ enum OpType {
+ OP_TYPE_VECTOR_2D,
+ OP_TYPE_VECTOR_3D,
+ OP_TYPE_MAX,
+ };
+
+protected:
+ OpType op_type = OP_TYPE_VECTOR_3D;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override = 0;
+
+ virtual int get_input_port_count() const override = 0;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override = 0;
+
+ virtual int get_output_port_count() const override = 0;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override = 0;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override = 0;
+
+ virtual void set_op_type(OpType p_op_type);
+ OpType get_op_type() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
+ VisualShaderNodeVectorBase();
+};
+
+VARIANT_ENUM_CAST(VisualShaderNodeVectorBase::OpType)
+
+///////////////////////////////////////
/// CONSTANTS
///////////////////////////////////////
@@ -177,6 +220,36 @@ public:
///////////////////////////////////////
+class VisualShaderNodeVec2Constant : public VisualShaderNodeConstant {
+ GDCLASS(VisualShaderNodeVec2Constant, VisualShaderNodeConstant);
+ Vector2 constant;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+ void set_constant(const Vector2 &p_constant);
+ Vector2 get_constant() const;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
+ VisualShaderNodeVec2Constant();
+};
+
+///////////////////////////////////////
+
class VisualShaderNodeVec3Constant : public VisualShaderNodeConstant {
GDCLASS(VisualShaderNodeVec3Constant, VisualShaderNodeConstant);
Vector3 constant;
@@ -615,8 +688,8 @@ public:
VARIANT_ENUM_CAST(VisualShaderNodeIntOp::Operator)
-class VisualShaderNodeVectorOp : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorOp, VisualShaderNode);
+class VisualShaderNodeVectorOp : public VisualShaderNodeVectorBase {
+ GDCLASS(VisualShaderNodeVectorOp, VisualShaderNodeVectorBase);
public:
enum Operator {
@@ -644,19 +717,20 @@ public:
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
- virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual int get_output_port_count() const override;
- virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual void set_op_type(OpType p_op_type) override;
+
void set_operator(Operator p_op);
Operator get_operator() const;
virtual Vector<StringName> get_editable_properties() const override;
+ String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override;
VisualShaderNodeVectorOp();
};
@@ -923,8 +997,10 @@ VARIANT_ENUM_CAST(VisualShaderNodeIntFunc::Function)
/// VECTOR FUNC
///////////////////////////////////////
-class VisualShaderNodeVectorFunc : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorFunc, VisualShaderNode);
+class VisualShaderNodeVectorFunc : public VisualShaderNodeVectorBase {
+ GDCLASS(VisualShaderNodeVectorFunc, VisualShaderNodeVectorBase);
+
+ void _update_default_input_values();
public:
enum Function {
@@ -975,19 +1051,20 @@ public:
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
- virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual int get_output_port_count() const override;
- virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ virtual void set_op_type(OpType p_op_type) override;
+
void set_function(Function p_func);
Function get_function() const;
virtual Vector<StringName> get_editable_properties() const override;
+ String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override;
VisualShaderNodeVectorFunc();
};
@@ -1150,20 +1227,20 @@ public:
/// LENGTH
///////////////////////////////////////
-class VisualShaderNodeVectorLen : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorLen, VisualShaderNode);
+class VisualShaderNodeVectorLen : public VisualShaderNodeVectorBase {
+ GDCLASS(VisualShaderNodeVectorLen, VisualShaderNodeVectorBase);
public:
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
- virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
+ virtual void set_op_type(OpType p_op_type) override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeVectorLen();
@@ -1203,7 +1280,8 @@ public:
enum OpType {
OP_TYPE_FLOAT,
OP_TYPE_INT,
- OP_TYPE_VECTOR,
+ OP_TYPE_VECTOR_2D,
+ OP_TYPE_VECTOR_3D,
OP_TYPE_MAX,
};
@@ -1235,54 +1313,20 @@ public:
VARIANT_ENUM_CAST(VisualShaderNodeClamp::OpType)
///////////////////////////////////////
-/// DERIVATIVE FUNCTIONS
+/// DERIVATIVE FUNCTION
///////////////////////////////////////
-class VisualShaderNodeScalarDerivativeFunc : public VisualShaderNode {
- GDCLASS(VisualShaderNodeScalarDerivativeFunc, VisualShaderNode);
+class VisualShaderNodeDerivativeFunc : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeDerivativeFunc, VisualShaderNode);
public:
- enum Function {
- FUNC_SUM,
- FUNC_X,
- FUNC_Y,
- FUNC_MAX,
+ enum OpType {
+ OP_TYPE_SCALAR,
+ OP_TYPE_VECTOR_2D,
+ OP_TYPE_VECTOR_3D,
+ OP_TYPE_MAX,
};
-protected:
- Function func = FUNC_SUM;
-
- static void _bind_methods();
-
-public:
- virtual String get_caption() const override;
-
- virtual int get_input_port_count() const override;
- virtual PortType get_input_port_type(int p_port) const override;
- virtual String get_input_port_name(int p_port) const override;
-
- virtual int get_output_port_count() const override;
- virtual PortType get_output_port_type(int p_port) const override;
- virtual String get_output_port_name(int p_port) const override;
-
- virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
-
- void set_function(Function p_func);
- Function get_function() const;
-
- virtual Vector<StringName> get_editable_properties() const override;
-
- VisualShaderNodeScalarDerivativeFunc();
-};
-
-VARIANT_ENUM_CAST(VisualShaderNodeScalarDerivativeFunc::Function)
-
-///////////////////////////////////////
-
-class VisualShaderNodeVectorDerivativeFunc : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorDerivativeFunc, VisualShaderNode);
-
-public:
enum Function {
FUNC_SUM,
FUNC_X,
@@ -1291,8 +1335,10 @@ public:
};
protected:
+ OpType op_type = OP_TYPE_SCALAR;
Function func = FUNC_SUM;
+protected:
static void _bind_methods();
public:
@@ -1308,34 +1354,37 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+ void set_op_type(OpType p_op_type);
+ OpType get_op_type() const;
+
void set_function(Function p_func);
Function get_function() const;
virtual Vector<StringName> get_editable_properties() const override;
- VisualShaderNodeVectorDerivativeFunc();
+ VisualShaderNodeDerivativeFunc();
};
-VARIANT_ENUM_CAST(VisualShaderNodeVectorDerivativeFunc::Function)
+VARIANT_ENUM_CAST(VisualShaderNodeDerivativeFunc::OpType)
+VARIANT_ENUM_CAST(VisualShaderNodeDerivativeFunc::Function)
///////////////////////////////////////
/// FACEFORWARD
///////////////////////////////////////
-class VisualShaderNodeFaceForward : public VisualShaderNode {
- GDCLASS(VisualShaderNodeFaceForward, VisualShaderNode);
+class VisualShaderNodeFaceForward : public VisualShaderNodeVectorBase {
+ GDCLASS(VisualShaderNodeFaceForward, VisualShaderNodeVectorBase);
public:
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
- virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual int get_output_port_count() const override;
- virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
+ virtual void set_op_type(OpType p_op_type) override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeFaceForward();
@@ -1374,8 +1423,10 @@ class VisualShaderNodeStep : public VisualShaderNode {
public:
enum OpType {
OP_TYPE_SCALAR,
- OP_TYPE_VECTOR,
- OP_TYPE_VECTOR_SCALAR,
+ OP_TYPE_VECTOR_2D,
+ OP_TYPE_VECTOR_2D_SCALAR,
+ OP_TYPE_VECTOR_3D,
+ OP_TYPE_VECTOR_3D_SCALAR,
OP_TYPE_MAX,
};
@@ -1416,8 +1467,10 @@ class VisualShaderNodeSmoothStep : public VisualShaderNode {
public:
enum OpType {
OP_TYPE_SCALAR,
- OP_TYPE_VECTOR,
- OP_TYPE_VECTOR_SCALAR,
+ OP_TYPE_VECTOR_2D,
+ OP_TYPE_VECTOR_2D_SCALAR,
+ OP_TYPE_VECTOR_3D,
+ OP_TYPE_VECTOR_3D_SCALAR,
OP_TYPE_MAX,
};
@@ -1452,20 +1505,20 @@ VARIANT_ENUM_CAST(VisualShaderNodeSmoothStep::OpType)
/// DISTANCE
///////////////////////////////////////
-class VisualShaderNodeVectorDistance : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorDistance, VisualShaderNode);
+class VisualShaderNodeVectorDistance : public VisualShaderNodeVectorBase {
+ GDCLASS(VisualShaderNodeVectorDistance, VisualShaderNodeVectorBase);
public:
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
- virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
+ virtual void set_op_type(OpType p_op_type) override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeVectorDistance();
@@ -1504,8 +1557,10 @@ class VisualShaderNodeMix : public VisualShaderNode {
public:
enum OpType {
OP_TYPE_SCALAR,
- OP_TYPE_VECTOR,
- OP_TYPE_VECTOR_SCALAR,
+ OP_TYPE_VECTOR_2D,
+ OP_TYPE_VECTOR_2D_SCALAR,
+ OP_TYPE_VECTOR_3D,
+ OP_TYPE_VECTOR_3D_SCALAR,
OP_TYPE_MAX,
};
@@ -1540,8 +1595,8 @@ VARIANT_ENUM_CAST(VisualShaderNodeMix::OpType)
/// COMPOSE
///////////////////////////////////////
-class VisualShaderNodeVectorCompose : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorCompose, VisualShaderNode);
+class VisualShaderNodeVectorCompose : public VisualShaderNodeVectorBase {
+ GDCLASS(VisualShaderNodeVectorCompose, VisualShaderNodeVectorBase);
public:
virtual String get_caption() const override;
@@ -1551,9 +1606,9 @@ public:
virtual String get_input_port_name(int p_port) const override;
virtual int get_output_port_count() const override;
- virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
+ virtual void set_op_type(OpType p_op_type) override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeVectorCompose();
@@ -1584,20 +1639,20 @@ public:
/// DECOMPOSE
///////////////////////////////////////
-class VisualShaderNodeVectorDecompose : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorDecompose, VisualShaderNode);
+class VisualShaderNodeVectorDecompose : public VisualShaderNodeVectorBase {
+ GDCLASS(VisualShaderNodeVectorDecompose, VisualShaderNodeVectorBase);
public:
virtual String get_caption() const override;
virtual int get_input_port_count() const override;
- virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override;
+ virtual void set_op_type(OpType p_op_type) override;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
VisualShaderNodeVectorDecompose();
@@ -1849,6 +1904,49 @@ public:
///////////////////////////////////////
+class VisualShaderNodeVec2Uniform : public VisualShaderNodeUniform {
+ GDCLASS(VisualShaderNodeVec2Uniform, VisualShaderNodeUniform);
+
+private:
+ bool default_value_enabled = false;
+ Vector2 default_value;
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+ virtual bool is_show_prop_names() const override;
+ virtual bool is_use_prop_slots() const override;
+
+ void set_default_value_enabled(bool p_enabled);
+ bool is_default_value_enabled() const;
+
+ void set_default_value(const Vector2 &p_value);
+ Vector2 get_default_value() const;
+
+ bool is_qualifier_supported(Qualifier p_qual) const override;
+ bool is_convertible_to_constant() const override;
+
+ virtual Vector<StringName> get_editable_properties() const override;
+
+ VisualShaderNodeVec2Uniform();
+};
+
+///////////////////////////////////////
+
class VisualShaderNodeVec3Uniform : public VisualShaderNodeUniform {
GDCLASS(VisualShaderNodeVec3Uniform, VisualShaderNodeUniform);
@@ -2148,7 +2246,8 @@ public:
enum OpType {
OP_TYPE_FLOAT,
OP_TYPE_INT,
- OP_TYPE_VECTOR,
+ OP_TYPE_VECTOR_2D,
+ OP_TYPE_VECTOR_3D,
OP_TYPE_BOOLEAN,
OP_TYPE_TRANSFORM,
OP_TYPE_MAX,
@@ -2261,7 +2360,8 @@ public:
enum ComparisonType {
CTYPE_SCALAR,
CTYPE_SCALAR_INT,
- CTYPE_VECTOR,
+ CTYPE_VECTOR_2D,
+ CTYPE_VECTOR_3D,
CTYPE_BOOLEAN,
CTYPE_TRANSFORM,
CTYPE_MAX,
@@ -2329,7 +2429,8 @@ class VisualShaderNodeMultiplyAdd : public VisualShaderNode {
public:
enum OpType {
OP_TYPE_SCALAR,
- OP_TYPE_VECTOR,
+ OP_TYPE_VECTOR_2D,
+ OP_TYPE_VECTOR_3D,
OP_TYPE_MAX,
};
diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp
index c937d988d2..9d8e0f7547 100644
--- a/scene/resources/world_2d.cpp
+++ b/scene/resources/world_2d.cpp
@@ -83,8 +83,8 @@ World2D::World2D() {
// Create and configure the navigation_map to be more friendly with pixels than meters.
navigation_map = NavigationServer2D::get_singleton()->map_create();
NavigationServer2D::get_singleton()->map_set_active(navigation_map, true);
- NavigationServer2D::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/2d/default_cell_size", 10));
- NavigationServer2D::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/2d/default_edge_connection_margin", 5));
+ NavigationServer2D::get_singleton()->map_set_cell_size(navigation_map, GLOBAL_DEF("navigation/2d/default_cell_size", 1));
+ NavigationServer2D::get_singleton()->map_set_edge_connection_margin(navigation_map, GLOBAL_DEF("navigation/2d/default_edge_connection_margin", 1));
}
World2D::~World2D() {
diff --git a/servers/audio/effects/audio_effect_record.cpp b/servers/audio/effects/audio_effect_record.cpp
index 569832b8a8..a5866bb380 100644
--- a/servers/audio/effects/audio_effect_record.cpp
+++ b/servers/audio/effects/audio_effect_record.cpp
@@ -112,7 +112,7 @@ void AudioEffectRecordInstance::init() {
ring_buffer_read_pos = 0;
//We start a new recording
- recording_data.resize(0); //Clear data completely and reset length
+ recording_data.clear(); //Clear data completely and reset length
is_recording = true;
#ifdef NO_THREADS
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index c89f811678..f00b8077d1 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -456,10 +456,12 @@ void AudioServer::_mix_step() {
case AudioStreamPlaybackListNode::AWAITING_DELETION:
case AudioStreamPlaybackListNode::FADE_OUT_TO_DELETION:
playback_list.erase(playback, [](AudioStreamPlaybackListNode *p) {
- if (p->prev_bus_details)
+ if (p->prev_bus_details) {
delete p->prev_bus_details;
- if (p->bus_details)
+ }
+ if (p->bus_details) {
delete p->bus_details;
+ }
p->stream_playback.unref();
delete p;
});
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index d4ff42bc34..5ded5cf214 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -316,6 +316,11 @@ void DisplayServer::set_icon(const Ref<Image> &p_icon) {
WARN_PRINT("Icon not supported by this display server.");
}
+int64_t DisplayServer::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
+ WARN_PRINT("Native handle not supported by this display server.");
+ return 0;
+}
+
void DisplayServer::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
WARN_PRINT("Changing the VSync mode is not supported by this display server.");
}
@@ -388,6 +393,8 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_sub_window", "mode", "vsync_mode", "flags", "rect"), &DisplayServer::create_sub_window, DEFVAL(Rect2i()));
ClassDB::bind_method(D_METHOD("delete_sub_window", "window_id"), &DisplayServer::delete_sub_window);
+ ClassDB::bind_method(D_METHOD("window_get_native_handle", "handle_type", "window_id"), &DisplayServer::window_get_native_handle, DEFVAL(MAIN_WINDOW_ID));
+
ClassDB::bind_method(D_METHOD("window_set_title", "title", "window_id"), &DisplayServer::window_set_title, DEFVAL(MAIN_WINDOW_ID));
ClassDB::bind_method(D_METHOD("window_set_mouse_passthrough", "region", "window_id"), &DisplayServer::window_set_mouse_passthrough, DEFVAL(MAIN_WINDOW_ID));
@@ -552,6 +559,10 @@ void DisplayServer::_bind_methods() {
BIND_ENUM_CONSTANT(VSYNC_ENABLED);
BIND_ENUM_CONSTANT(VSYNC_ADAPTIVE);
BIND_ENUM_CONSTANT(VSYNC_MAILBOX);
+
+ BIND_ENUM_CONSTANT(DISPLAY_HANDLE);
+ BIND_ENUM_CONSTANT(WINDOW_HANDLE);
+ BIND_ENUM_CONSTANT(WINDOW_VIEW);
}
void DisplayServer::register_create_function(const char *p_name, CreateFunction p_function, GetRenderingDriversFunction p_get_drivers) {
diff --git a/servers/display_server.h b/servers/display_server.h
index 0c2bc5dd3a..8c6586dc20 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -65,6 +65,12 @@ public:
VSYNC_MAILBOX
};
+ enum HandleType {
+ DISPLAY_HANDLE,
+ WINDOW_HANDLE,
+ WINDOW_VIEW,
+ };
+
typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, VSyncMode, uint32_t, const Size2i &, Error &r_error);
typedef Vector<String> (*GetRenderingDriversFunction)();
@@ -232,6 +238,8 @@ public:
virtual void show_window(WindowID p_id);
virtual void delete_sub_window(WindowID p_id);
+ virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const;
+
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const = 0;
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) = 0;
@@ -387,6 +395,7 @@ VARIANT_ENUM_CAST(DisplayServer::MouseMode)
VARIANT_ENUM_CAST(DisplayServer::ScreenOrientation)
VARIANT_ENUM_CAST(DisplayServer::WindowMode)
VARIANT_ENUM_CAST(DisplayServer::WindowFlags)
+VARIANT_ENUM_CAST(DisplayServer::HandleType)
VARIANT_ENUM_CAST(DisplayServer::CursorShape)
VARIANT_ENUM_CAST(DisplayServer::VSyncMode)
diff --git a/servers/physics_3d/godot_soft_body_3d.cpp b/servers/physics_3d/godot_soft_body_3d.cpp
index 1de27760d5..095050b7f3 100644
--- a/servers/physics_3d/godot_soft_body_3d.cpp
+++ b/servers/physics_3d/godot_soft_body_3d.cpp
@@ -245,7 +245,7 @@ void GodotSoftBody3D::update_area() {
const Vector3 a = x1 - x0;
const Vector3 b = x2 - x0;
const Vector3 cr = vec3_cross(a, b);
- face.ra = cr.length();
+ face.ra = cr.length() * 0.5;
}
// Node area.
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 3fbf4fe436..bf8b6379d2 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -80,7 +80,7 @@
ShaderTypes *shader_types = nullptr;
PhysicsServer3D *_createGodotPhysics3DCallback() {
- bool using_threads = GLOBAL_GET("physics/3d/run_on_thread");
+ bool using_threads = GLOBAL_GET("physics/3d/run_on_separate_thread");
PhysicsServer3D *physics_server = memnew(GodotPhysicsServer3D(using_threads));
@@ -88,7 +88,7 @@ PhysicsServer3D *_createGodotPhysics3DCallback() {
}
PhysicsServer2D *_createGodotPhysics2DCallback() {
- bool using_threads = GLOBAL_GET("physics/2d/run_on_thread");
+ bool using_threads = GLOBAL_GET("physics/2d/run_on_separate_thread");
PhysicsServer2D *physics_server = memnew(GodotPhysicsServer2D(using_threads));
diff --git a/servers/rendering/rasterizer_dummy.h b/servers/rendering/rasterizer_dummy.h
index 83da8388e4..7032f3fb03 100644
--- a/servers/rendering/rasterizer_dummy.h
+++ b/servers/rendering/rasterizer_dummy.h
@@ -109,7 +109,7 @@ public:
void environment_set_canvas_max_layer(RID p_env, int p_max_layer) override {}
void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) override {}
- void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) override {}
+ void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) override {}
void environment_glow_set_use_bicubic_upscale(bool p_enable) override {}
void environment_glow_set_use_high_quality(bool p_enable) override {}
diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp
index 4ab50782df..25a366aa4b 100644
--- a/servers/rendering/renderer_rd/effects_rd.cpp
+++ b/servers/rendering/renderer_rd/effects_rd.cpp
@@ -115,6 +115,43 @@ RID EffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps)
return uniform_set;
}
+RID EffectsRD::_get_uniform_set_from_texture_pair(RID p_texture1, RID p_texture2, bool p_use_mipmaps) {
+ TexturePair tp;
+ tp.texture1 = p_texture1;
+ tp.texture2 = p_texture2;
+
+ if (texture_pair_to_uniform_set_cache.has(tp)) {
+ RID uniform_set = texture_pair_to_uniform_set_cache[tp];
+ if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ return uniform_set;
+ }
+ }
+
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.binding = 0;
+ u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler);
+ u.ids.push_back(p_texture1);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.binding = 1;
+ u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler);
+ u.ids.push_back(p_texture2);
+ uniforms.push_back(u);
+ }
+ // anything with the same configuration (one texture in binding 0 for set 0), is good
+ RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, tonemap.shader.version_get_shader(tonemap.shader_version, 0), 2);
+
+ texture_pair_to_uniform_set_cache[tp] = uniform_set;
+
+ return uniform_set;
+}
+
RID EffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) {
if (texture_to_compute_uniform_set_cache.has(p_texture)) {
RID uniform_set = texture_to_compute_uniform_set_cache[p_texture];
@@ -828,6 +865,7 @@ void EffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const Tone
tonemap.push_constant.use_glow = p_settings.use_glow;
tonemap.push_constant.glow_intensity = p_settings.glow_intensity;
+ tonemap.push_constant.glow_map_strength = p_settings.glow_map_strength;
tonemap.push_constant.glow_levels[0] = p_settings.glow_levels[0]; // clean this up to just pass by pointer or something
tonemap.push_constant.glow_levels[1] = p_settings.glow_levels[1];
tonemap.push_constant.glow_levels[2] = p_settings.glow_levels[2];
@@ -867,7 +905,7 @@ void EffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const Tone
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, tonemap.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer), false, RD::get_singleton()->draw_list_get_current_pass()));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_color), 0);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_settings.exposure_texture), 1);
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_settings.glow_texture, true), 2);
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture_pair(p_settings.glow_texture, p_settings.glow_map, true), 2);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_settings.color_correction_texture), 3);
RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
@@ -907,7 +945,7 @@ void EffectsRD::tonemapper(RD::DrawListID p_subpass_draw_list, RID p_source_colo
RD::get_singleton()->draw_list_bind_render_pipeline(p_subpass_draw_list, tonemap.pipelines[mode].get_render_pipeline(RD::INVALID_ID, p_dst_format_id, false, RD::get_singleton()->draw_list_get_current_pass()));
RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, _get_uniform_set_for_input(p_source_color), 0);
RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, _get_uniform_set_from_texture(p_settings.exposure_texture), 1); // should be set to a default texture, it's ignored
- RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, _get_uniform_set_from_texture(p_settings.glow_texture, true), 2); // should be set to a default texture, it's ignored
+ RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, _get_uniform_set_from_texture_pair(p_settings.glow_texture, p_settings.glow_map, true), 2); // should be set to a default texture, it's ignored
RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, _get_uniform_set_from_texture(p_settings.color_correction_texture), 3);
RD::get_singleton()->draw_list_bind_index_array(p_subpass_draw_list, index_array);
diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h
index a3fb4db3df..1a080756a8 100644
--- a/servers/rendering/renderer_rd/effects_rd.h
+++ b/servers/rendering/renderer_rd/effects_rd.h
@@ -274,7 +274,7 @@ private:
uint32_t glow_texture_size[2]; // 8 - 40
float glow_intensity; // 4 - 44
- uint32_t pad3; // 4 - 48
+ float glow_map_strength; // 4 - 48
uint32_t glow_mode; // 4 - 52
float glow_levels[7]; // 28 - 80
@@ -874,6 +874,7 @@ private:
}
};
+ Map<TexturePair, RID> texture_pair_to_uniform_set_cache;
Map<RID, RID> texture_to_compute_uniform_set_cache;
Map<TexturePair, RID> texture_pair_to_compute_uniform_set_cache;
Map<TexturePair, RID> image_pair_to_compute_uniform_set_cache;
@@ -882,6 +883,7 @@ private:
RID _get_uniform_set_from_image(RID p_texture);
RID _get_uniform_set_for_input(RID p_texture);
RID _get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps = false);
+ RID _get_uniform_set_from_texture_pair(RID p_texture1, RID p_texture2, bool p_use_mipmaps = false);
RID _get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps = false);
RID _get_compute_uniform_set_from_texture_and_sampler(RID p_texture, RID p_sampler);
RID _get_compute_uniform_set_from_texture_pair(RID p_texture, RID p_texture2, bool p_use_mipmaps = false);
@@ -943,10 +945,12 @@ public:
GlowMode glow_mode = GLOW_MODE_ADD;
float glow_intensity = 1.0;
+ float glow_map_strength = 0.0f;
float glow_levels[7] = { 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0 };
Vector2i glow_texture_size;
bool glow_use_bicubic_upscale = false;
RID glow_texture;
+ RID glow_map;
RS::EnvironmentToneMapper tonemap_mode = RS::ENV_TONE_MAPPER_LINEAR;
float exposure = 1.0;
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index 36604073cc..87301a9d3a 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -1081,6 +1081,10 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
distance = -distance_max;
}
+ if (p_render_data->cam_ortogonal) {
+ distance = 1.0;
+ }
+
uint32_t indices;
surf->sort.lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, &indices);
if (p_render_data->render_info) {
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index b9c51f5461..778d7baa5d 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -1042,7 +1042,7 @@ void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_in
RENDER_TIMESTAMP("Render Material");
{
- RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, true, 0);
+ RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, true, false);
//regular forward for now
Vector<Color> clear = {
Color(0, 0, 0, 0),
@@ -1429,6 +1429,10 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
distance = -distance_max;
}
+ if (p_render_data->cam_ortogonal) {
+ distance = 1.0;
+ }
+
uint32_t indices;
surf->lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, &indices);
if (p_render_data->render_info) {
diff --git a/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp
index 0d0d7513d0..0d9477d850 100644
--- a/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp
@@ -54,7 +54,7 @@ void RendererSceneEnvironmentRD::set_tonemap(RS::EnvironmentToneMapper p_tone_ma
auto_exp_scale = p_auto_exp_scale;
}
-void RendererSceneEnvironmentRD::set_glow(bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) {
+void RendererSceneEnvironmentRD::set_glow(bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) {
ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7");
glow_enabled = p_enable;
glow_levels = p_levels;
@@ -66,6 +66,8 @@ void RendererSceneEnvironmentRD::set_glow(bool p_enable, Vector<float> p_levels,
glow_hdr_bleed_threshold = p_hdr_bleed_threshold;
glow_hdr_bleed_scale = p_hdr_bleed_scale;
glow_hdr_luminance_cap = p_hdr_luminance_cap;
+ glow_map_strength = p_glow_map_strength;
+ glow_map = p_glow_map;
}
void RendererSceneEnvironmentRD::set_sdfgi(bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) {
diff --git a/servers/rendering/renderer_rd/renderer_scene_environment_rd.h b/servers/rendering/renderer_rd/renderer_scene_environment_rd.h
index 629d224b49..ed26fd467b 100644
--- a/servers/rendering/renderer_rd/renderer_scene_environment_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_environment_rd.h
@@ -102,6 +102,8 @@ public:
float glow_hdr_bleed_threshold = 1.0;
float glow_hdr_luminance_cap = 12.0;
float glow_hdr_bleed_scale = 2.0;
+ float glow_map_strength = 0.0f;
+ RID glow_map = RID();
/// SSAO
@@ -154,7 +156,7 @@ public:
void set_ambient_light(const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source);
void set_tonemap(RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale);
- void set_glow(bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap);
+ void set_glow(bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map);
void set_sdfgi(bool p_enable, int p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias);
void set_fog(bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective);
void set_volumetric_fog(bool p_enable, float p_density, const Color &p_scatterin, const Color &p_emission, float p_emission_energy, float p_anisotropy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount, float p_ambient_inject);
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index deaf613836..43a1812f89 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -289,10 +289,10 @@ void RendererSceneRenderRD::environment_set_tonemap(RID p_env, RS::EnvironmentTo
env->set_tonemap(p_tone_mapper, p_exposure, p_white, p_auto_exposure, p_min_luminance, p_max_luminance, p_auto_exp_speed, p_auto_exp_scale);
}
-void RendererSceneRenderRD::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) {
+void RendererSceneRenderRD::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) {
RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env);
ERR_FAIL_COND(!env);
- env->set_glow(p_enable, p_levels, p_intensity, p_strength, p_mix, p_bloom_threshold, p_blend_mode, p_hdr_bleed_threshold, p_hdr_bleed_scale, p_hdr_luminance_cap);
+ env->set_glow(p_enable, p_levels, p_intensity, p_strength, p_mix, p_bloom_threshold, p_blend_mode, p_hdr_bleed_threshold, p_hdr_bleed_scale, p_hdr_luminance_cap, p_glow_map_strength, p_glow_map);
}
void RendererSceneRenderRD::environment_glow_set_use_bicubic_upscale(bool p_enable) {
@@ -925,7 +925,7 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool
}
for (int i = 0; i < 4; i++) {
//clear subdivisions
- shadow_atlas->quadrants[i].shadows.resize(0);
+ shadow_atlas->quadrants[i].shadows.clear();
shadow_atlas->quadrants[i].shadows.resize(1 << shadow_atlas->quadrants[i].subdivision);
}
@@ -972,7 +972,7 @@ void RendererSceneRenderRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, i
}
}
- shadow_atlas->quadrants[p_quadrant].shadows.resize(0);
+ shadow_atlas->quadrants[p_quadrant].shadows.clear();
shadow_atlas->quadrants[p_quadrant].shadows.resize(subdiv * subdiv);
shadow_atlas->quadrants[p_quadrant].subdivision = subdiv;
@@ -1920,6 +1920,11 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) {
rb->ambient_buffer = RID();
rb->reflection_buffer = RID();
}
+
+ if (rb->gi.voxel_gi_buffer.is_valid()) {
+ RD::get_singleton()->free(rb->gi.voxel_gi_buffer);
+ rb->gi.voxel_gi_buffer = RID();
+ }
}
void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) {
@@ -2496,8 +2501,17 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
tonemap.glow_texture_size.y = rb->blur[1].mipmaps[0].height;
tonemap.glow_use_bicubic_upscale = glow_bicubic_upscale;
tonemap.glow_texture = rb->blur[1].texture;
+ if (env->glow_map.is_valid()) {
+ tonemap.glow_map_strength = env->glow_map_strength;
+ tonemap.glow_map = storage->texture_get_rd_texture(env->glow_map);
+ } else {
+ tonemap.glow_map_strength = 0.0f;
+ tonemap.glow_map = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
+ }
+
} else {
tonemap.glow_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ tonemap.glow_map = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
}
if (rb->screen_space_aa == RS::VIEWPORT_SCREEN_SPACE_AA_FXAA) {
@@ -2590,6 +2604,7 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr
tonemap.use_glow = false;
tonemap.glow_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ tonemap.glow_map = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
tonemap.use_auto_exposure = false;
tonemap.exposure_texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 592618ae05..899d2d763d 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -1061,7 +1061,7 @@ public:
virtual bool is_environment(RID p_env) const override;
- virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) override;
+ virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) override;
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) override;
virtual void environment_glow_set_use_high_quality(bool p_enable) override;
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
index 856ea5e74d..f6f39230f8 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -590,6 +590,7 @@ void RendererSceneSkyRD::Sky::free(RendererStorageRD *p_storage) {
if (material.is_valid()) {
p_storage->free(material);
+ material = RID();
}
}
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index 2e63ac57d9..145c4f902e 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -6238,7 +6238,7 @@ void RendererStorageRD::skeleton_allocate_data(RID p_skeleton, int p_bones, bool
if (skeleton->buffer.is_valid()) {
RD::get_singleton()->free(skeleton->buffer);
skeleton->buffer = RID();
- skeleton->data.resize(0);
+ skeleton->data.clear();
skeleton->uniform_set_mi = RID();
}
diff --git a/servers/rendering/renderer_rd/shaders/tonemap.glsl b/servers/rendering/renderer_rd/shaders/tonemap.glsl
index 948c6e1e39..41d41758f4 100644
--- a/servers/rendering/renderer_rd/shaders/tonemap.glsl
+++ b/servers/rendering/renderer_rd/shaders/tonemap.glsl
@@ -45,6 +45,7 @@ layout(set = 0, binding = 0) uniform sampler2D source_color;
layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;
layout(set = 2, binding = 0) uniform sampler2D source_glow;
+layout(set = 2, binding = 1) uniform sampler2D glow_map;
#ifdef USE_1D_LUT
layout(set = 3, binding = 0) uniform sampler2D source_color_correction;
@@ -63,7 +64,7 @@ layout(push_constant, binding = 1, std430) uniform Params {
uvec2 glow_texture_size;
float glow_intensity;
- uint pad3;
+ float glow_map_strength;
uint glow_mode;
float glow_levels[7];
@@ -405,6 +406,9 @@ void main() {
#ifndef SUBPASS
if (params.use_glow && params.glow_mode == GLOW_MODE_MIX) {
vec3 glow = gather_glow(source_glow, uv_interp) * params.luminance_multiplier;
+ if (params.glow_map_strength > 0.001) {
+ glow = mix(glow, texture(glow_map, uv_interp).rgb * glow, params.glow_map_strength);
+ }
color.rgb = mix(color.rgb, glow, params.glow_intensity);
}
@@ -425,9 +429,11 @@ void main() {
#ifndef SUBPASS
// Glow
-
if (params.use_glow && params.glow_mode != GLOW_MODE_MIX) {
vec3 glow = gather_glow(source_glow, uv_interp) * params.glow_intensity * params.luminance_multiplier;
+ if (params.glow_map_strength > 0.001) {
+ glow = mix(glow, texture(glow_map, uv_interp).rgb * glow, params.glow_map_strength);
+ }
// high dynamic range -> SRGB
glow = apply_tonemapping(glow, params.white);
diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h
index 426d22f83e..406d946e12 100644
--- a/servers/rendering/renderer_scene.h
+++ b/servers/rendering/renderer_scene.h
@@ -131,7 +131,7 @@ public:
virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0;
virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG) = 0;
- virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0;
+ virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) = 0;
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h
index 1e770ef66c..ed0229f0f9 100644
--- a/servers/rendering/renderer_scene_cull.h
+++ b/servers/rendering/renderer_scene_cull.h
@@ -1113,7 +1113,7 @@ public:
PASS6(environment_set_ssil, RID, bool, float, float, float, float)
PASS6(environment_set_ssil_quality, RS::EnvironmentSSILQuality, bool, float, int, float, float)
- PASS11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, RS::EnvironmentGlowBlendMode, float, float, float)
+ PASS13(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, RS::EnvironmentGlowBlendMode, float, float, float, float, RID)
PASS1(environment_glow_set_use_bicubic_upscale, bool)
PASS1(environment_glow_set_use_high_quality, bool)
diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h
index c34a46d166..3eb90ccc4d 100644
--- a/servers/rendering/renderer_scene_render.h
+++ b/servers/rendering/renderer_scene_render.h
@@ -123,7 +123,7 @@ public:
virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0;
#endif
- virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0;
+ virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) = 0;
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 17a665922f..5a84bace2d 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -549,8 +549,13 @@ void RendererViewport::draw_viewports() {
// get our xr interface in case we need it
Ref<XRInterface> xr_interface;
- if (XRServer::get_singleton() != nullptr) {
- xr_interface = XRServer::get_singleton()->get_primary_interface();
+ XRServer *xr_server = XRServer::get_singleton();
+ if (xr_server != nullptr) {
+ // let our XR server know we're about to render our frames so we can get our frame timing
+ xr_server->pre_render();
+
+ // retrieve the interface responsible for rendering
+ xr_interface = xr_server->get_primary_interface();
}
if (Engine::get_singleton()->is_editor_hint()) {
@@ -582,19 +587,26 @@ void RendererViewport::draw_viewports() {
bool visible = vp->viewport_to_screen_rect != Rect2();
- if (vp->use_xr && xr_interface.is_valid()) {
- visible = true; // XR viewport is always visible regardless of update mode, output is sent to HMD.
-
- // Override our size, make sure it matches our required size and is created as a stereo target
- Size2 xr_size = xr_interface->get_render_target_size();
-
- // Would have been nice if we could call viewport_set_size here,
- // but alas that takes our RID and we now have our pointer,
- // also we only check if view_count changes in render_target_set_size so we need to call that for this to reliably change
- vp->occlusion_buffer_dirty = vp->occlusion_buffer_dirty || (vp->size != xr_size);
- vp->size = xr_size;
- uint32_t view_count = xr_interface->get_view_count();
- RSG::storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y, view_count);
+ if (vp->use_xr) {
+ if (xr_interface.is_valid()) {
+ // Override our size, make sure it matches our required size and is created as a stereo target
+ Size2 xr_size = xr_interface->get_render_target_size();
+
+ // Would have been nice if we could call viewport_set_size here,
+ // but alas that takes our RID and we now have our pointer,
+ // also we only check if view_count changes in render_target_set_size so we need to call that for this to reliably change
+ vp->occlusion_buffer_dirty = vp->occlusion_buffer_dirty || (vp->size != xr_size);
+ vp->size = xr_size;
+ uint32_t view_count = xr_interface->get_view_count();
+ RSG::storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y, view_count);
+
+ // Inform xr interface we're about to render its viewport, if this returns false we don't render
+ visible = xr_interface->pre_draw_viewport(vp->render_target);
+ } else {
+ // don't render anything
+ visible = false;
+ vp->size = Size2();
+ }
}
if (vp->update_mode == RS::VIEWPORT_UPDATE_ALWAYS || vp->update_mode == RS::VIEWPORT_UPDATE_ONCE) {
@@ -647,7 +659,7 @@ void RendererViewport::draw_viewports() {
// measure
// commit our eyes
- Vector<BlitToScreen> blits = xr_interface->commit_views(vp->render_target, vp->viewport_to_screen_rect);
+ Vector<BlitToScreen> blits = xr_interface->post_draw_viewport(vp->render_target, vp->viewport_to_screen_rect);
if (vp->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID && blits.size() > 0) {
if (!blit_to_screen_list.has(vp->viewport_to_screen)) {
blit_to_screen_list[vp->viewport_to_screen] = Vector<BlitToScreen>();
@@ -657,9 +669,6 @@ void RendererViewport::draw_viewports() {
blit_to_screen_list[vp->viewport_to_screen].push_back(blits[b]);
}
}
-
- // and for our frame timing, mark when we've finished committing our eyes
- XRServer::get_singleton()->_mark_commit();
} else {
RSG::storage->render_target_set_external_texture(vp->render_target, 0);
@@ -813,7 +822,7 @@ void RendererViewport::viewport_set_active(RID p_viewport, bool p_active) {
ERR_FAIL_COND(!viewport);
if (p_active) {
- ERR_FAIL_COND_MSG(active_viewports.find(viewport) != -1, "Can't make active a Viewport that is already active.");
+ ERR_FAIL_COND_MSG(active_viewports.has(viewport), "Can't make active a Viewport that is already active.");
viewport->occlusion_buffer_dirty = true;
active_viewports.push_back(viewport);
} else {
diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp
index d7e9d210db..d93aad5d7b 100644
--- a/servers/rendering/rendering_server_default.cpp
+++ b/servers/rendering/rendering_server_default.cpp
@@ -93,6 +93,12 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
RSG::rasterizer->end_frame(p_swap_buffers);
+ XRServer *xr_server = XRServer::get_singleton();
+ if (xr_server != nullptr) {
+ // let our XR server know we're done so we can get our frame timing
+ xr_server->end_frame();
+ }
+
RSG::canvas->update_visibility_notifiers();
RSG::scene->update_visibility_notifiers();
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 54fd897a77..6d2c36537b 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -628,7 +628,7 @@ public:
FUNC6(environment_set_ssil, RID, bool, float, float, float, float)
FUNC6(environment_set_ssil_quality, EnvironmentSSILQuality, bool, float, int, float, float)
- FUNC11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float)
+ FUNC13(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float, float, RID)
FUNC1(environment_glow_set_use_bicubic_upscale, bool)
FUNC1(environment_glow_set_use_high_quality, bool)
diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp
index 78e81eac0b..43acae42f8 100644
--- a/servers/rendering/shader_compiler.cpp
+++ b/servers/rendering/shader_compiler.cpp
@@ -813,6 +813,9 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->single_statement) {
code += scode; //use directly
+ if (bnode->use_comma_between_statements && i + 1 < bnode->statements.size()) {
+ code += ",";
+ }
} else {
code += _mktab(p_level) + scode + ";\n";
}
@@ -1287,10 +1290,10 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
} else if (cfnode->flow_op == SL::FLOW_OP_FOR) {
String left = _dump_node_code(cfnode->blocks[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- String middle = _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
- String right = _dump_node_code(cfnode->expressions[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ String middle = _dump_node_code(cfnode->blocks[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ String right = _dump_node_code(cfnode->blocks[2], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += _mktab(p_level) + "for (" + left + ";" + middle + ";" + right + ")\n";
- code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
+ code += _dump_node_code(cfnode->blocks[3], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
} else if (cfnode->flow_op == SL::FLOW_OP_RETURN) {
if (cfnode->expressions.size()) {
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index f16f66544a..2e1ee41406 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -5252,21 +5252,32 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expression.push_back(e);
continue;
} else {
- if (tk.type != TK_SEMICOLON) {
- _set_error(vformat(RTR("Expected expression, found: '%s'."), get_token_text(tk)));
- return nullptr;
- } else {
-#ifdef DEBUG_ENABLED
- if (check_warnings && HAS_WARNING(ShaderWarning::FORMATTING_ERROR_FLAG)) {
- _add_line_warning(ShaderWarning::FORMATTING_ERROR, RTR("Empty statement. Remove ';' to fix this warning."));
- }
-#endif // DEBUG_ENABLED
+ bool valid = false;
+ if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_FOR_EXPRESSION && tk.type == TK_PARENTHESIS_CLOSE) {
+ valid = true;
_set_tkpos(prepos);
OperatorNode *func = alloc_node<OperatorNode>();
func->op = OP_EMPTY;
expr = func;
}
+ if (!valid) {
+ if (tk.type != TK_SEMICOLON) {
+ _set_error(vformat(RTR("Expected expression, found: '%s'."), get_token_text(tk)));
+ return nullptr;
+ } else {
+#ifdef DEBUG_ENABLED
+ if (check_warnings && HAS_WARNING(ShaderWarning::FORMATTING_ERROR_FLAG)) {
+ _add_line_warning(ShaderWarning::FORMATTING_ERROR, RTR("Empty statement. Remove ';' to fix this warning."));
+ }
+#endif // DEBUG_ENABLED
+ _set_tkpos(prepos);
+
+ OperatorNode *func = alloc_node<OperatorNode>();
+ func->op = OP_EMPTY;
+ expr = func;
+ }
+ }
}
ERR_FAIL_COND_V(!expr, nullptr);
@@ -6769,14 +6780,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
array_size = 0;
}
- if (tk.type == TK_COMMA) {
- if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR) {
- _set_error(vformat("Multiple declarations in '%s' loop are not supported.", "for"));
- return ERR_PARSE_ERROR;
- }
- } else if (tk.type == TK_SEMICOLON) {
+ if (tk.type == TK_SEMICOLON) {
break;
- } else {
+ } else if (tk.type != TK_COMMA) {
_set_expected_error(",", ";");
return ERR_PARSE_ERROR;
}
@@ -7138,43 +7144,35 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
cf->flow_op = FLOW_OP_FOR;
BlockNode *init_block = alloc_node<BlockNode>();
- init_block->block_type = BlockNode::BLOCK_TYPE_FOR;
+ init_block->block_type = BlockNode::BLOCK_TYPE_FOR_INIT;
init_block->parent_block = p_block;
init_block->single_statement = true;
cf->blocks.push_back(init_block);
- if (_parse_block(init_block, p_function_info, true, false, false) != OK) {
- return ERR_PARSE_ERROR;
- }
-
- Node *n = _parse_and_reduce_expression(init_block, p_function_info);
- if (!n) {
- return ERR_PARSE_ERROR;
- }
-
- if (n->get_datatype() != TYPE_BOOL) {
- _set_error(RTR("The middle expression is expected to be boolean."));
- return ERR_PARSE_ERROR;
- }
-
- tk = _get_token();
- if (tk.type != TK_SEMICOLON) {
- _set_expected_error(";");
- return ERR_PARSE_ERROR;
+ Error err = _parse_block(init_block, p_function_info, true, false, false);
+ if (err != OK) {
+ return err;
}
- cf->expressions.push_back(n);
-
- n = _parse_and_reduce_expression(init_block, p_function_info);
- if (!n) {
- return ERR_PARSE_ERROR;
+ BlockNode *condition_block = alloc_node<BlockNode>();
+ condition_block->block_type = BlockNode::BLOCK_TYPE_FOR_CONDITION;
+ condition_block->parent_block = init_block;
+ condition_block->single_statement = true;
+ condition_block->use_comma_between_statements = true;
+ cf->blocks.push_back(condition_block);
+ err = _parse_block(condition_block, p_function_info, true, false, false);
+ if (err != OK) {
+ return err;
}
- cf->expressions.push_back(n);
-
- tk = _get_token();
- if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_expected_error(")");
- return ERR_PARSE_ERROR;
+ BlockNode *expression_block = alloc_node<BlockNode>();
+ expression_block->block_type = BlockNode::BLOCK_TYPE_FOR_EXPRESSION;
+ expression_block->parent_block = init_block;
+ expression_block->single_statement = true;
+ expression_block->use_comma_between_statements = true;
+ cf->blocks.push_back(expression_block);
+ err = _parse_block(expression_block, p_function_info, true, false, false);
+ if (err != OK) {
+ return err;
}
BlockNode *block = alloc_node<BlockNode>();
@@ -7182,8 +7180,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
cf->blocks.push_back(block);
p_block->statements.push_back(cf);
- Error err = _parse_block(block, p_function_info, true, true, true);
- if (err) {
+ err = _parse_block(block, p_function_info, true, true, true);
+ if (err != OK) {
return err;
}
@@ -7333,10 +7331,48 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (!expr) {
return ERR_PARSE_ERROR;
}
+
+ bool empty = false;
+
+ if (expr->type == Node::TYPE_OPERATOR) {
+ OperatorNode *op = static_cast<OperatorNode *>(expr);
+ if (op->op == OP_EMPTY) {
+ empty = true;
+ }
+ }
+ if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_INIT) {
+ if (!empty && expr->type != BlockNode::TYPE_VARIABLE_DECLARATION) {
+ _set_error(RTR("The left expression is expected to be a variable declaration."));
+ return ERR_PARSE_ERROR;
+ }
+ }
+ if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_CONDITION) {
+ if (!empty && expr->get_datatype() != TYPE_BOOL) {
+ _set_error(RTR("The middle expression is expected to be boolean."));
+ return ERR_PARSE_ERROR;
+ }
+ }
+
p_block->statements.push_back(expr);
tk = _get_token();
- if (tk.type != TK_SEMICOLON) {
+ if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_CONDITION) {
+ if (tk.type == TK_COMMA) {
+ continue;
+ }
+ if (tk.type != TK_SEMICOLON) {
+ _set_expected_error(",", ";");
+ return ERR_PARSE_ERROR;
+ }
+ } else if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR_EXPRESSION) {
+ if (tk.type == TK_COMMA) {
+ continue;
+ }
+ if (tk.type != TK_PARENTHESIS_CLOSE) {
+ _set_expected_error(",", ")");
+ return ERR_PARSE_ERROR;
+ }
+ } else if (tk.type != TK_SEMICOLON) {
_set_expected_error(";");
return ERR_PARSE_ERROR;
}
@@ -7476,7 +7512,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
const String smode = String(mode);
- if (shader->render_modes.find(mode) != -1) {
+ if (shader->render_modes.has(mode)) {
_set_error(vformat(RTR("Duplicated render mode: '%s'."), smode));
return ERR_PARSE_ERROR;
}
@@ -7489,7 +7525,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (smode.begins_with(name)) {
if (!info.options.is_empty()) {
- if (info.options.find(smode.substr(name.length() + 1)) != -1) {
+ if (info.options.has(smode.substr(name.length() + 1))) {
found = true;
if (defined_modes.has(name)) {
@@ -7799,7 +7835,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (uniform) {
- if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL) {
+ if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL && Engine::get_singleton()->is_editor_hint()) { // Type checking for global uniforms is not allowed outside the editor.
//validate global uniform
DataType gvtype = global_var_get_type_func(name);
if (gvtype == TYPE_MAX) {
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index 1307eeac2b..f39b21621d 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -504,7 +504,9 @@ public:
enum BlockType {
BLOCK_TYPE_STANDART,
- BLOCK_TYPE_FOR,
+ BLOCK_TYPE_FOR_INIT,
+ BLOCK_TYPE_FOR_CONDITION,
+ BLOCK_TYPE_FOR_EXPRESSION,
BLOCK_TYPE_SWITCH,
BLOCK_TYPE_CASE,
BLOCK_TYPE_DEFAULT,
@@ -526,6 +528,7 @@ public:
Map<StringName, Variable> variables;
List<Node *> statements;
bool single_statement = false;
+ bool use_comma_between_statements = false;
BlockNode() :
Node(TYPE_BLOCK) {}
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 84e54eab22..584abbc351 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -2317,7 +2317,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("environment_set_bg_energy", "env", "energy"), &RenderingServer::environment_set_bg_energy);
ClassDB::bind_method(D_METHOD("environment_set_canvas_max_layer", "env", "max_layer"), &RenderingServer::environment_set_canvas_max_layer);
ClassDB::bind_method(D_METHOD("environment_set_ambient_light", "env", "color", "ambient", "energy", "sky_contibution", "reflection_source"), &RenderingServer::environment_set_ambient_light, DEFVAL(RS::ENV_AMBIENT_SOURCE_BG), DEFVAL(1.0), DEFVAL(0.0), DEFVAL(RS::ENV_REFLECTION_SOURCE_BG));
- ClassDB::bind_method(D_METHOD("environment_set_glow", "env", "enable", "levels", "intensity", "strength", "mix", "bloom_threshold", "blend_mode", "hdr_bleed_threshold", "hdr_bleed_scale", "hdr_luminance_cap"), &RenderingServer::environment_set_glow);
+ ClassDB::bind_method(D_METHOD("environment_set_glow", "env", "enable", "levels", "intensity", "strength", "mix", "bloom_threshold", "blend_mode", "hdr_bleed_threshold", "hdr_bleed_scale", "hdr_luminance_cap", "glow_map_strength", "glow_map"), &RenderingServer::environment_set_glow);
ClassDB::bind_method(D_METHOD("environment_set_tonemap", "env", "tone_mapper", "exposure", "white", "auto_exposure", "min_luminance", "max_luminance", "auto_exp_speed", "auto_exp_grey"), &RenderingServer::environment_set_tonemap);
ClassDB::bind_method(D_METHOD("environment_set_adjustment", "env", "enable", "brightness", "contrast", "saturation", "use_1d_color_correction", "color_correction"), &RenderingServer::environment_set_adjustment);
ClassDB::bind_method(D_METHOD("environment_set_ssr", "env", "enable", "max_steps", "fade_in", "fade_out", "depth_tolerance"), &RenderingServer::environment_set_ssr);
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index b067db3d27..472fff1bf1 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -991,7 +991,7 @@ public:
ENV_GLOW_BLEND_MODE_MIX,
};
- virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0;
+ virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, float p_glow_map_strength, RID p_glow_map) = 0;
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp
index d7e7960496..3c5faa4ef7 100644
--- a/servers/text/text_server_extension.cpp
+++ b/servers/text/text_server_extension.cpp
@@ -210,10 +210,14 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(_shaped_text_set_preserve_control, "shaped", "enabled");
GDVIRTUAL_BIND(_shaped_text_get_preserve_control, "shaped");
- GDVIRTUAL_BIND(_shaped_text_add_string, "shaped", "text", "fonts", "size", "opentype_features", "language");
+ GDVIRTUAL_BIND(_shaped_text_add_string, "shaped", "text", "fonts", "size", "opentype_features", "language", "meta");
GDVIRTUAL_BIND(_shaped_text_add_object, "shaped", "key", "size", "inline_align", "length");
GDVIRTUAL_BIND(_shaped_text_resize_object, "shaped", "key", "size", "inline_align");
+ GDVIRTUAL_BIND(_shaped_get_span_count, "shaped");
+ GDVIRTUAL_BIND(_shaped_get_span_meta, "shaped", "index");
+ GDVIRTUAL_BIND(_shaped_set_span_update_font, "shaped", "index", "fonts", "size", "opentype_features");
+
GDVIRTUAL_BIND(_shaped_text_substr, "shaped", "start", "length");
GDVIRTUAL_BIND(_shaped_text_get_parent, "shaped");
@@ -226,8 +230,8 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(_shaped_text_is_ready, "shaped");
- GDVIRTUAL_BIND(_shaped_text_get_glyphs, "shaped", "r_glyphs");
- GDVIRTUAL_BIND(_shaped_text_sort_logical, "shaped", "r_glyphs");
+ GDVIRTUAL_BIND(_shaped_text_get_glyphs, "shaped");
+ GDVIRTUAL_BIND(_shaped_text_sort_logical, "shaped");
GDVIRTUAL_BIND(_shaped_text_get_glyph_count, "shaped");
GDVIRTUAL_BIND(_shaped_text_get_range, "shaped");
@@ -239,7 +243,7 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(_shaped_text_get_trim_pos, "shaped");
GDVIRTUAL_BIND(_shaped_text_get_ellipsis_pos, "shaped");
GDVIRTUAL_BIND(_shaped_text_get_ellipsis_glyph_count, "shaped");
- GDVIRTUAL_BIND(_shaped_text_get_ellipsis_glyphs, "shaped", "r_glyphs");
+ GDVIRTUAL_BIND(_shaped_text_get_ellipsis_glyphs, "shaped");
GDVIRTUAL_BIND(_shaped_text_overrun_trim_to_width, "shaped", "width", "trim_flags");
@@ -501,7 +505,7 @@ void TextServerExtension::font_set_hinting(RID p_font_rid, TextServer::Hinting p
}
TextServer::Hinting TextServerExtension::font_get_hinting(RID p_font_rid) const {
- int ret;
+ TextServer::Hinting ret;
if (GDVIRTUAL_CALL(_font_get_hinting, p_font_rid, ret)) {
return (TextServer::Hinting)ret;
}
@@ -951,7 +955,7 @@ void TextServerExtension::shaped_text_set_direction(RID p_shaped, TextServer::Di
}
TextServer::Direction TextServerExtension::shaped_text_get_direction(RID p_shaped) const {
- int ret;
+ TextServer::Direction ret;
if (GDVIRTUAL_CALL(_shaped_text_get_direction, p_shaped, ret)) {
return (TextServer::Direction)ret;
}
@@ -959,7 +963,7 @@ TextServer::Direction TextServerExtension::shaped_text_get_direction(RID p_shape
}
TextServer::Direction TextServerExtension::shaped_text_get_inferred_direction(RID p_shaped) const {
- int ret;
+ TextServer::Direction ret;
if (GDVIRTUAL_CALL(_shaped_text_get_inferred_direction, p_shaped, ret)) {
return (TextServer::Direction)ret;
}
@@ -971,7 +975,7 @@ void TextServerExtension::shaped_text_set_orientation(RID p_shaped, TextServer::
}
TextServer::Orientation TextServerExtension::shaped_text_get_orientation(RID p_shaped) const {
- int ret;
+ TextServer::Orientation ret;
if (GDVIRTUAL_CALL(_shaped_text_get_orientation, p_shaped, ret)) {
return (TextServer::Orientation)ret;
}
@@ -1018,13 +1022,13 @@ bool TextServerExtension::shaped_text_get_preserve_control(RID p_shaped) const {
return false;
}
-bool TextServerExtension::shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) {
+bool TextServerExtension::shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
bool ret;
Array fonts;
for (int i = 0; i < p_fonts.size(); i++) {
fonts.push_back(p_fonts[i]);
}
- if (GDVIRTUAL_CALL(_shaped_text_add_string, p_shaped, p_text, fonts, p_size, p_opentype_features, p_language, ret)) {
+ if (GDVIRTUAL_CALL(_shaped_text_add_string, p_shaped, p_text, fonts, p_size, p_opentype_features, p_language, p_meta, ret)) {
return ret;
}
return false;
@@ -1046,6 +1050,30 @@ bool TextServerExtension::shaped_text_resize_object(RID p_shaped, Variant p_key,
return false;
}
+int TextServerExtension::shaped_get_span_count(RID p_shaped) const {
+ int ret;
+ if (GDVIRTUAL_CALL(_shaped_get_span_count, p_shaped, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+Variant TextServerExtension::shaped_get_span_meta(RID p_shaped, int p_index) const {
+ Variant ret;
+ if (GDVIRTUAL_CALL(_shaped_get_span_meta, p_shaped, p_index, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+void TextServerExtension::shaped_set_span_update_font(RID p_shaped, int p_index, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features) {
+ Array fonts;
+ for (int i = 0; i < p_fonts.size(); i++) {
+ fonts.push_back(p_fonts[i]);
+ }
+ GDVIRTUAL_CALL(_shaped_set_span_update_font, p_shaped, p_index, fonts, p_size, p_opentype_features);
+}
+
RID TextServerExtension::shaped_text_substr(RID p_shaped, int p_start, int p_length) const {
RID ret;
if (GDVIRTUAL_CALL(_shaped_text_substr, p_shaped, p_start, p_length, ret)) {
@@ -1111,16 +1139,16 @@ bool TextServerExtension::shaped_text_is_ready(RID p_shaped) const {
}
const Glyph *TextServerExtension::shaped_text_get_glyphs(RID p_shaped) const {
- const Glyph *ret;
- if (GDVIRTUAL_CALL(_shaped_text_get_glyphs, p_shaped, &ret)) {
+ GDNativePtr<Glyph> ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_glyphs, p_shaped, ret)) {
return ret;
}
return nullptr;
}
const Glyph *TextServerExtension::shaped_text_sort_logical(RID p_shaped) {
- const Glyph *ret;
- if (GDVIRTUAL_CALL(_shaped_text_sort_logical, p_shaped, &ret)) {
+ GDNativePtr<Glyph> ret;
+ if (GDVIRTUAL_CALL(_shaped_text_sort_logical, p_shaped, ret)) {
return ret;
}
return nullptr;
@@ -1183,8 +1211,8 @@ int TextServerExtension::shaped_text_get_ellipsis_pos(RID p_shaped) const {
}
const Glyph *TextServerExtension::shaped_text_get_ellipsis_glyphs(RID p_shaped) const {
- const Glyph *ret;
- if (GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyphs, p_shaped, &ret)) {
+ GDNativePtr<Glyph> ret;
+ if (GDVIRTUAL_CALL(_shaped_text_get_ellipsis_glyphs, p_shaped, ret)) {
return ret;
}
return nullptr;
diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h
index 6e203f22ee..9e7f666be1 100644
--- a/servers/text/text_server_extension.h
+++ b/servers/text/text_server_extension.h
@@ -132,7 +132,7 @@ public:
virtual void font_set_hinting(RID p_font_rid, Hinting p_hinting) override;
virtual Hinting font_get_hinting(RID p_font_rid) const override;
GDVIRTUAL2(_font_set_hinting, RID, Hinting);
- GDVIRTUAL1RC(/*Hinting*/ int, _font_get_hinting, RID);
+ GDVIRTUAL1RC(Hinting, _font_get_hinting, RID);
virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) override;
virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const override;
@@ -317,8 +317,8 @@ public:
virtual Direction shaped_text_get_direction(RID p_shaped) const override;
virtual Direction shaped_text_get_inferred_direction(RID p_shaped) const override;
GDVIRTUAL2(_shaped_text_set_direction, RID, Direction);
- GDVIRTUAL1RC(/*Direction*/ int, _shaped_text_get_direction, RID);
- GDVIRTUAL1RC(/*Direction*/ int, _shaped_text_get_inferred_direction, RID);
+ GDVIRTUAL1RC(Direction, _shaped_text_get_direction, RID);
+ GDVIRTUAL1RC(Direction, _shaped_text_get_inferred_direction, RID);
virtual void shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) override;
GDVIRTUAL2(_shaped_text_set_bidi_override, RID, const Array &);
@@ -331,7 +331,7 @@ public:
virtual void shaped_text_set_orientation(RID p_shaped, Orientation p_orientation = ORIENTATION_HORIZONTAL) override;
virtual Orientation shaped_text_get_orientation(RID p_shaped) const override;
GDVIRTUAL2(_shaped_text_set_orientation, RID, Orientation);
- GDVIRTUAL1RC(/*Orientation*/ int, _shaped_text_get_orientation, RID);
+ GDVIRTUAL1RC(Orientation, _shaped_text_get_orientation, RID);
virtual void shaped_text_set_preserve_invalid(RID p_shaped, bool p_enabled) override;
virtual bool shaped_text_get_preserve_invalid(RID p_shaped) const override;
@@ -343,13 +343,20 @@ public:
GDVIRTUAL2(_shaped_text_set_preserve_control, RID, bool);
GDVIRTUAL1RC(bool, _shaped_text_get_preserve_control, RID);
- virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") override;
+ virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override;
virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) override;
virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
- GDVIRTUAL6R(bool, _shaped_text_add_string, RID, const String &, const Array &, int, const Dictionary &, const String &);
+ GDVIRTUAL7R(bool, _shaped_text_add_string, RID, const String &, const Array &, int, const Dictionary &, const String &, const Variant &);
GDVIRTUAL5R(bool, _shaped_text_add_object, RID, Variant, const Size2 &, InlineAlignment, int);
GDVIRTUAL4R(bool, _shaped_text_resize_object, RID, Variant, const Size2 &, InlineAlignment);
+ virtual int shaped_get_span_count(RID p_shaped) const override;
+ virtual Variant shaped_get_span_meta(RID p_shaped, int p_index) const override;
+ virtual void shaped_set_span_update_font(RID p_shaped, int p_index, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary()) override;
+ GDVIRTUAL1RC(int, _shaped_get_span_count, RID);
+ GDVIRTUAL2RC(Variant, _shaped_get_span_meta, RID, int);
+ GDVIRTUAL5(_shaped_set_span_update_font, RID, int, const Array &, int, const Dictionary &);
+
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override;
virtual RID shaped_text_get_parent(RID p_shaped) const override;
GDVIRTUAL3RC(RID, _shaped_text_substr, RID, int, int);
@@ -373,8 +380,8 @@ public:
virtual const Glyph *shaped_text_get_glyphs(RID p_shaped) const override;
virtual const Glyph *shaped_text_sort_logical(RID p_shaped) override;
virtual int shaped_text_get_glyph_count(RID p_shaped) const override;
- GDVIRTUAL2C(_shaped_text_get_glyphs, RID, GDNativePtr<const Glyph *>);
- GDVIRTUAL2(_shaped_text_sort_logical, RID, GDNativePtr<const Glyph *>);
+ GDVIRTUAL1RC(GDNativePtr<Glyph>, _shaped_text_get_glyphs, RID);
+ GDVIRTUAL1R(GDNativePtr<Glyph>, _shaped_text_sort_logical, RID);
GDVIRTUAL1RC(int, _shaped_text_get_glyph_count, RID);
virtual Vector2i shaped_text_get_range(RID p_shaped) const override;
@@ -393,7 +400,7 @@ public:
virtual int shaped_text_get_ellipsis_glyph_count(RID p_shaped) const override;
GDVIRTUAL1RC(int, _shaped_text_get_trim_pos, RID);
GDVIRTUAL1RC(int, _shaped_text_get_ellipsis_pos, RID);
- GDVIRTUAL2C(_shaped_text_get_ellipsis_glyphs, RID, GDNativePtr<const Glyph *>);
+ GDVIRTUAL1RC(GDNativePtr<Glyph>, _shaped_text_get_ellipsis_glyphs, RID);
GDVIRTUAL1RC(int, _shaped_text_get_ellipsis_glyph_count, RID);
virtual void shaped_text_overrun_trim_to_width(RID p_shaped, float p_width, uint16_t p_trim_flags) override;
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index 17840584ee..b7cd39b9b2 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -363,10 +363,14 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("shaped_text_set_preserve_control", "shaped", "enabled"), &TextServer::shaped_text_set_preserve_control);
ClassDB::bind_method(D_METHOD("shaped_text_get_preserve_control", "shaped"), &TextServer::shaped_text_get_preserve_control);
- ClassDB::bind_method(D_METHOD("shaped_text_add_string", "shaped", "text", "fonts", "size", "opentype_features", "language"), &TextServer::shaped_text_add_string, DEFVAL(Dictionary()), DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("shaped_text_add_string", "shaped", "text", "fonts", "size", "opentype_features", "language", "meta"), &TextServer::shaped_text_add_string, DEFVAL(Dictionary()), DEFVAL(""), DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("shaped_text_add_object", "shaped", "key", "size", "inline_align", "length"), &TextServer::shaped_text_add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1));
ClassDB::bind_method(D_METHOD("shaped_text_resize_object", "shaped", "key", "size", "inline_align"), &TextServer::shaped_text_resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER));
+ ClassDB::bind_method(D_METHOD("shaped_get_span_count", "shaped"), &TextServer::shaped_get_span_count);
+ ClassDB::bind_method(D_METHOD("shaped_get_span_meta", "shaped", "index"), &TextServer::shaped_get_span_meta);
+ ClassDB::bind_method(D_METHOD("shaped_set_span_update_font", "shaped", "index", "fonts", "size", "opentype_features"), &TextServer::shaped_set_span_update_font, DEFVAL(Dictionary()));
+
ClassDB::bind_method(D_METHOD("shaped_text_substr", "shaped", "start", "length"), &TextServer::shaped_text_substr);
ClassDB::bind_method(D_METHOD("shaped_text_get_parent", "shaped"), &TextServer::shaped_text_get_parent);
ClassDB::bind_method(D_METHOD("shaped_text_fit_to_width", "shaped", "width", "jst_flags"), &TextServer::shaped_text_fit_to_width, DEFVAL(JUSTIFICATION_WORD_BOUND | JUSTIFICATION_KASHIDA));
diff --git a/servers/text_server.h b/servers/text_server.h
index 599cc3afd0..629a633b9f 100644
--- a/servers/text_server.h
+++ b/servers/text_server.h
@@ -155,20 +155,6 @@ protected:
TextServer::Direction direction = DIRECTION_LTR; // Desired text direction.
TextServer::Orientation orientation = ORIENTATION_HORIZONTAL;
- struct Span {
- int start = -1;
- int end = -1;
-
- Vector<RID> fonts;
- int font_size = 0;
-
- Variant embedded_key;
-
- String language;
- Dictionary features;
- };
- Vector<Span> spans;
-
struct EmbeddedObject {
int pos = 0;
InlineAlignment inline_align = INLINE_ALIGNMENT_CENTER;
@@ -387,10 +373,14 @@ public:
virtual void shaped_text_set_preserve_control(RID p_shaped, bool p_enabled) = 0;
virtual bool shaped_text_get_preserve_control(RID p_shaped) const = 0;
- virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") = 0;
+ virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) = 0;
virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) = 0;
virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) = 0;
+ virtual int shaped_get_span_count(RID p_shaped) const = 0;
+ virtual Variant shaped_get_span_meta(RID p_shaped, int p_index) const = 0;
+ virtual void shaped_set_span_update_font(RID p_shaped, int p_index, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary()) = 0;
+
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const = 0; // Copy shaped substring (e.g. line break) without reshaping, but correctly reordered, preservers range.
virtual RID shaped_text_get_parent(RID p_shaped) const = 0;
@@ -567,7 +557,6 @@ VARIANT_ENUM_CAST(TextServer::SpacingType);
VARIANT_ENUM_CAST(TextServer::FontStyle);
GDVIRTUAL_NATIVE_PTR(Glyph);
-GDVIRTUAL_NATIVE_PTR(Glyph *);
GDVIRTUAL_NATIVE_PTR(CaretInfo);
#endif // TEXT_SERVER_H
diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp
index 758f2416ec..7ae111b5e7 100644
--- a/servers/xr/xr_interface.cpp
+++ b/servers/xr/xr_interface.cpp
@@ -168,8 +168,5 @@ XRInterface::TrackingStatus XRInterface::get_tracking_status() const {
return XR_UNKNOWN_TRACKING;
}
-void XRInterface::notification(int p_what) {
-}
-
void XRInterface::trigger_haptic_pulse(const String &p_action_name, const StringName &p_tracker_name, double p_frequency, double p_amplitude, double p_duration_sec, double p_delay_sec) {
}
diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h
index aee98f8fee..6e105ffc26 100644
--- a/servers/xr/xr_interface.h
+++ b/servers/xr/xr_interface.h
@@ -123,10 +123,13 @@ public:
// note, external color/depth/vrs texture support will be added here soon.
- virtual Vector<BlitToScreen> commit_views(RID p_render_target, const Rect2 &p_screen_rect) = 0; /* commit rendered views to the XR interface */
-
virtual void process() = 0;
- virtual void notification(int p_what);
+ virtual void pre_render(){};
+ virtual bool pre_draw_viewport(RID p_render_target) { return true; }; /* inform XR interface we are about to start our viewport draw process */
+ virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) = 0; /* inform XR interface we finished our viewport draw process */
+ virtual void end_frame(){};
+
+ virtual void notification(int p_what){};
XRInterface();
~XRInterface();
diff --git a/servers/xr/xr_interface_extension.cpp b/servers/xr/xr_interface_extension.cpp
index 9dae3b162d..18131c1e89 100644
--- a/servers/xr/xr_interface_extension.cpp
+++ b/servers/xr/xr_interface_extension.cpp
@@ -52,9 +52,12 @@ void XRInterfaceExtension::_bind_methods() {
GDVIRTUAL_BIND(_get_transform_for_view, "view", "cam_transform");
GDVIRTUAL_BIND(_get_projection_for_view, "view", "aspect", "z_near", "z_far");
- GDVIRTUAL_BIND(_commit_views, "render_target", "screen_rect");
-
GDVIRTUAL_BIND(_process);
+ GDVIRTUAL_BIND(_pre_render);
+ GDVIRTUAL_BIND(_pre_draw_viewport, "render_target");
+ GDVIRTUAL_BIND(_post_draw_viewport, "render_target", "screen_rect");
+ GDVIRTUAL_BIND(_end_frame);
+
GDVIRTUAL_BIND(_notification, "what");
/** input and output **/
@@ -274,7 +277,7 @@ CameraMatrix XRInterfaceExtension::get_projection_for_view(uint32_t p_view, doub
void XRInterfaceExtension::add_blit(RID p_render_target, Rect2 p_src_rect, Rect2i p_dst_rect, bool p_use_layer, uint32_t p_layer, bool p_apply_lens_distortion, Vector2 p_eye_center, double p_k1, double p_k2, double p_upscale, double p_aspect_ratio) {
BlitToScreen blit;
- ERR_FAIL_COND_MSG(!can_add_blits, "add_blit can only be called from an XR plugin from within _commit_views!");
+ ERR_FAIL_COND_MSG(!can_add_blits, "add_blit can only be called from an XR plugin from within _post_draw_viewport!");
blit.render_target = p_render_target;
blit.src_rect = p_src_rect;
@@ -293,12 +296,31 @@ void XRInterfaceExtension::add_blit(RID p_render_target, Rect2 p_src_rect, Rect2
blits.push_back(blit);
}
-Vector<BlitToScreen> XRInterfaceExtension::commit_views(RID p_render_target, const Rect2 &p_screen_rect) {
+void XRInterfaceExtension::process() {
+ GDVIRTUAL_CALL(_process);
+}
+
+void XRInterfaceExtension::pre_render() {
+ GDVIRTUAL_CALL(_pre_render);
+}
+
+bool XRInterfaceExtension::pre_draw_viewport(RID p_render_target) {
+ bool do_render = true;
+
+ if (GDVIRTUAL_CALL(_pre_draw_viewport, p_render_target, do_render)) {
+ return do_render;
+ } else {
+ // if not implemented we're returning true
+ return true;
+ }
+}
+
+Vector<BlitToScreen> XRInterfaceExtension::post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) {
// This is just so our XR plugin can add blits...
blits.clear();
can_add_blits = true;
- if (GDVIRTUAL_CALL(_commit_views, p_render_target, p_screen_rect)) {
+ if (GDVIRTUAL_CALL(_post_draw_viewport, p_render_target, p_screen_rect)) {
return blits;
}
@@ -306,8 +328,8 @@ Vector<BlitToScreen> XRInterfaceExtension::commit_views(RID p_render_target, con
return blits;
}
-void XRInterfaceExtension::process() {
- GDVIRTUAL_CALL(_process);
+void XRInterfaceExtension::end_frame() {
+ GDVIRTUAL_CALL(_end_frame);
}
void XRInterfaceExtension::notification(int p_what) {
diff --git a/servers/xr/xr_interface_extension.h b/servers/xr/xr_interface_extension.h
index e22ec2b872..5a436b9fd0 100644
--- a/servers/xr/xr_interface_extension.h
+++ b/servers/xr/xr_interface_extension.h
@@ -109,13 +109,20 @@ public:
GDVIRTUAL4R(PackedFloat64Array, _get_projection_for_view, uint32_t, double, double, double);
void add_blit(RID p_render_target, Rect2 p_src_rect, Rect2i p_dst_rect, bool p_use_layer = false, uint32_t p_layer = 0, bool p_apply_lens_distortion = false, Vector2 p_eye_center = Vector2(), double p_k1 = 0.0, double p_k2 = 0.0, double p_upscale = 1.0, double p_aspect_ratio = 1.0);
- virtual Vector<BlitToScreen> commit_views(RID p_render_target, const Rect2 &p_screen_rect) override;
- GDVIRTUAL2(_commit_views, RID, const Rect2 &);
virtual void process() override;
+ virtual void pre_render() override;
+ virtual bool pre_draw_viewport(RID p_render_target) override;
+ virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override;
+ virtual void end_frame() override;
virtual void notification(int p_what) override;
GDVIRTUAL0(_process);
+ GDVIRTUAL0(_pre_render);
+ GDVIRTUAL1R(bool, _pre_draw_viewport, RID);
+ GDVIRTUAL2(_post_draw_viewport, RID, const Rect2 &);
+ GDVIRTUAL0(_end_frame);
+
GDVIRTUAL1(_notification, int);
/* access to some internals we need */
diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp
index 69f4c69b53..dbfe76a127 100644
--- a/servers/xr_server.cpp
+++ b/servers/xr_server.cpp
@@ -65,10 +65,6 @@ void XRServer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "primary_interface"), "set_primary_interface", "get_primary_interface");
- ClassDB::bind_method(D_METHOD("get_last_process_usec"), &XRServer::get_last_process_usec);
- ClassDB::bind_method(D_METHOD("get_last_commit_usec"), &XRServer::get_last_commit_usec);
- ClassDB::bind_method(D_METHOD("get_last_frame_usec"), &XRServer::get_last_frame_usec);
-
BIND_ENUM_CONSTANT(TRACKER_HEAD);
BIND_ENUM_CONSTANT(TRACKER_CONTROLLER);
BIND_ENUM_CONSTANT(TRACKER_BASESTATION);
@@ -351,24 +347,9 @@ PackedStringArray XRServer::get_suggested_pose_names(const StringName &p_tracker
return arr;
}
-uint64_t XRServer::get_last_process_usec() {
- return last_process_usec;
-};
-
-uint64_t XRServer::get_last_commit_usec() {
- return last_commit_usec;
-};
-
-uint64_t XRServer::get_last_frame_usec() {
- return last_frame_usec;
-};
-
void XRServer::_process() {
/* called from renderer_viewport.draw_viewports right before we start drawing our viewports */
- /* mark for our frame timing */
- last_process_usec = OS::get_singleton()->get_ticks_usec();
-
/* process all active interfaces */
for (int i = 0; i < interfaces.size(); i++) {
if (!interfaces[i].is_valid()) {
@@ -379,13 +360,32 @@ void XRServer::_process() {
};
};
-void XRServer::_mark_commit() {
- /* time this */
- last_commit_usec = OS::get_singleton()->get_ticks_usec();
+void XRServer::pre_render() {
+ // called from RendererViewport.draw_viewports right before we start drawing our viewports
+ // note that we can have multiple interfaces active if we have interfaces that purely handle tracking
- /* now store our difference as we may overwrite last_process_usec before this is accessed */
- last_frame_usec = last_commit_usec - last_process_usec;
-};
+ // process all active interfaces
+ for (int i = 0; i < interfaces.size(); i++) {
+ if (!interfaces[i].is_valid()) {
+ // ignore, not a valid reference
+ } else if (interfaces[i]->is_initialized()) {
+ interfaces.write[i]->pre_render();
+ };
+ };
+}
+
+void XRServer::end_frame() {
+ // called from RenderingServerDefault after Vulkan queues have been submitted
+
+ // process all active interfaces
+ for (int i = 0; i < interfaces.size(); i++) {
+ if (!interfaces[i].is_valid()) {
+ // ignore, not a valid reference
+ } else if (interfaces[i]->is_initialized()) {
+ interfaces.write[i]->end_frame();
+ };
+ };
+}
XRServer::XRServer() {
singleton = this;
diff --git a/servers/xr_server.h b/servers/xr_server.h
index a820634bd9..d9188d2de1 100644
--- a/servers/xr_server.h
+++ b/servers/xr_server.h
@@ -84,10 +84,6 @@ private:
Transform3D world_origin; /* our world origin point, maps a location in our virtual world to the origin point in our real world tracking volume */
Transform3D reference_frame; /* our reference frame */
- uint64_t last_process_usec; /* for frame timing, usec when we did our processing */
- uint64_t last_commit_usec; /* for frame timing, usec when we finished committing both eyes */
- uint64_t last_frame_usec; /* time it took between process and committing, we should probably average this over the last x frames */
-
protected:
static XRServer *singleton;
@@ -175,12 +171,16 @@ public:
PackedStringArray get_suggested_pose_names(const StringName &p_tracker_name) const;
// Q: Should we add get_suggested_input_names and get_suggested_haptic_names even though we don't use them for the IDE?
- uint64_t get_last_process_usec();
- uint64_t get_last_commit_usec();
- uint64_t get_last_frame_usec();
-
+ // Process is called before we handle our physics process and game process. This is where our interfaces will update controller data and such.
void _process();
- void _mark_commit();
+
+ // Pre-render is called right before we're rendering our viewports.
+ // This is where interfaces such as OpenVR and OpenXR will update positioning data.
+ // Many of these interfaces will also do a predictive sync which ensures we run at a steady framerate.
+ void pre_render();
+
+ // End-frame is called right after Godot has finished its rendering bits.
+ void end_frame();
XRServer();
~XRServer();
diff --git a/tests/core/math/test_rect2.h b/tests/core/math/test_rect2.h
index e07250a8a2..d98a94b1b5 100644
--- a/tests/core/math/test_rect2.h
+++ b/tests/core/math/test_rect2.h
@@ -439,6 +439,9 @@ TEST_CASE("[Rect2i] Enclosing") {
CHECK_MESSAGE(
!Rect2i(0, 100, 1280, 720).encloses(Rect2i(-4000, -4000, 100, 100)),
"encloses() with non-contained Rect2i should return the expected result.");
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).encloses(Rect2i(0, 100, 1280, 720)),
+ "encloses() with identical Rect2i should return the expected result.");
}
TEST_CASE("[Rect2i] Expanding") {
@@ -557,6 +560,9 @@ TEST_CASE("[Rect2i] Intersection") {
CHECK_MESSAGE(
!Rect2i(0, 100, 1280, 720).intersects(Rect2i(-4000, -4000, 100, 100)),
"intersects() with non-enclosed Rect2i should return the expected result.");
+ CHECK_MESSAGE(
+ !Rect2i(0, 0, 2, 2).intersects(Rect2i(2, 2, 2, 2)),
+ "intersects() with adjacent Rect2i should return the expected result.");
}
TEST_CASE("[Rect2i] Merging") {
diff --git a/tests/core/object/test_method_bind.h b/tests/core/object/test_method_bind.h
index 0c7e47fc89..350a08b6e2 100644
--- a/tests/core/object/test_method_bind.h
+++ b/tests/core/object/test_method_bind.h
@@ -51,9 +51,15 @@ public:
TEST_METHODRC,
TEST_METHODRC_ARGS,
TEST_METHOD_DEFARGS,
+ TEST_METHOD_OBJECT_CAST,
TEST_MAX
};
+ class ObjectSubclass : public Object {
+ public:
+ int value = 1;
+ };
+
int test_num = 0;
bool test_valid[TEST_MAX];
@@ -98,6 +104,10 @@ public:
test_valid[TEST_METHOD_DEFARGS] = p_arg1 == 1 && p_arg2 == 2 && p_arg3 == 3 && p_arg4 == 4 && p_arg5 == 5; //temporary
}
+ void test_method_object_cast(ObjectSubclass *p_object) {
+ test_valid[TEST_METHOD_OBJECT_CAST] = p_object->value == 1;
+ }
+
static void _bind_methods() {
ClassDB::bind_method(D_METHOD("test_method"), &MethodBindTester::test_method);
ClassDB::bind_method(D_METHOD("test_method_args"), &MethodBindTester::test_method_args);
@@ -108,6 +118,7 @@ public:
ClassDB::bind_method(D_METHOD("test_methodrc"), &MethodBindTester::test_methodrc);
ClassDB::bind_method(D_METHOD("test_methodrc_args"), &MethodBindTester::test_methodrc_args);
ClassDB::bind_method(D_METHOD("test_method_default_args"), &MethodBindTester::test_method_default_args, DEFVAL(9) /* wrong on purpose */, DEFVAL(4), DEFVAL(5));
+ ClassDB::bind_method(D_METHOD("test_method_object_cast", "object"), &MethodBindTester::test_method_object_cast);
}
virtual void run_tests() {
@@ -134,6 +145,10 @@ public:
test_valid[TEST_METHODRC_ARGS] = int(call("test_methodrc_args", test_num)) == test_num && test_valid[TEST_METHODRC_ARGS];
call("test_method_default_args", 1, 2, 3, 4);
+
+ ObjectSubclass *obj = memnew(ObjectSubclass);
+ call("test_method_object_cast", obj);
+ memdelete(obj);
}
};
@@ -152,6 +167,7 @@ TEST_CASE("[MethodBind] check all method binds") {
CHECK(mbt->test_valid[MethodBindTester::TEST_METHODRC]);
CHECK(mbt->test_valid[MethodBindTester::TEST_METHODRC_ARGS]);
CHECK(mbt->test_valid[MethodBindTester::TEST_METHOD_DEFARGS]);
+ CHECK(mbt->test_valid[MethodBindTester::TEST_METHOD_OBJECT_CAST]);
memdelete(mbt);
}
diff --git a/tests/core/string/test_string.h b/tests/core/string/test_string.h
index baab5ddfe7..0446f749cf 100644
--- a/tests/core/string/test_string.h
+++ b/tests/core/string/test_string.h
@@ -38,8 +38,9 @@
namespace TestString {
int u32scmp(const char32_t *l, const char32_t *r) {
- for (; *l == *r && *l && *r; l++, r++)
+ for (; *l == *r && *l && *r; l++, r++) {
;
+ }
return *l - *r;
}
@@ -877,7 +878,7 @@ TEST_CASE("[String] is_subsequence_of") {
String a = "is subsequence of";
CHECK(String("sub").is_subsequence_of(a));
CHECK(!String("Sub").is_subsequence_of(a));
- CHECK(String("Sub").is_subsequence_ofi(a));
+ CHECK(String("Sub").is_subsequence_ofn(a));
}
TEST_CASE("[String] match") {
diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h
index 84e71150c7..8bd35df107 100644
--- a/tests/scene/test_code_edit.h
+++ b/tests/scene/test_code_edit.h
@@ -2786,6 +2786,52 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
SEND_GUI_KEY_EVENT(code_edit, Key::APOSTROPHE);
SEND_GUI_KEY_EVENT(code_edit, Key::QUOTEDBL);
CHECK(code_edit->get_line(0) == "'\"'");
+
+ /* Wrap single line selection with brackets */
+ code_edit->clear();
+ code_edit->insert_text_at_caret("abc");
+ code_edit->select_all();
+ SEND_GUI_KEY_EVENT(code_edit, Key::BRACKETLEFT);
+ CHECK(code_edit->get_line(0) == "[abc]");
+
+ /* Caret should be after the last character of the single line selection */
+ CHECK(code_edit->get_caret_column() == 4);
+
+ /* Wrap multi line selection with brackets */
+ code_edit->clear();
+ code_edit->insert_text_at_caret("abc\nabc");
+ code_edit->select_all();
+ SEND_GUI_KEY_EVENT(code_edit, Key::BRACKETLEFT);
+ CHECK(code_edit->get_text() == "[abc\nabc]");
+
+ /* Caret should be after the last character of the multi line selection */
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 3);
+
+ /* If inserted character is not a auto brace completion open key, replace selected text with the inserted character */
+ code_edit->clear();
+ code_edit->insert_text_at_caret("abc");
+ code_edit->select_all();
+ SEND_GUI_KEY_EVENT(code_edit, Key::KEY_1);
+ CHECK(code_edit->get_text() == "1");
+
+ /* If potential multichar and single brace completion is matched, it should wrap the single. */
+ code_edit->clear();
+ code_edit->insert_text_at_caret("\'\'abc");
+ code_edit->select(0, 2, 0, 5);
+ SEND_GUI_KEY_EVENT(code_edit, Key::APOSTROPHE);
+ CHECK(code_edit->get_text() == "\'\'\'abc\'");
+
+ /* If only the potential multichar brace completion is matched, it does not wrap or complete. */
+ auto_brace_completion_pairs.erase("\'");
+ code_edit->set_auto_brace_completion_pairs(auto_brace_completion_pairs);
+ CHECK_FALSE(code_edit->has_auto_brace_completion_open_key("\'"));
+
+ code_edit->clear();
+ code_edit->insert_text_at_caret("\'\'abc");
+ code_edit->select(0, 2, 0, 5);
+ SEND_GUI_KEY_EVENT(code_edit, Key::APOSTROPHE);
+ CHECK(code_edit->get_text() == "\'\'\'");
}
SUBCASE("[CodeEdit] autocomplete") {
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 6333a0fe87..e1f911a9f9 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -206,7 +206,7 @@ Files extracted from upstream source:
## harfbuzz
- Upstream: https://github.com/harfbuzz/harfbuzz
-- Version: 3.2.0 (be91d2917d9860326cb5fd1d03ffe1042a72f6d3, 2021)
+- Version: 3.3.1 (45df259538c204540819d74456d30ffb40df488a, 2022)
- License: MIT
Files extracted from upstream source:
@@ -309,7 +309,7 @@ Files extracted from upstream source:
## libwebp
- Upstream: https://chromium.googlesource.com/webm/libwebp/
-- Version: 1.2.1 (9ce5843dbabcfd3f7c39ec7ceba9cbeb213cbfdf, 2021)
+- Version: 1.2.2 (b0a860891dcd4c0c2d7c6149e5cccb6eb881cc21, 2022)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -317,10 +317,6 @@ Files extracted from upstream source:
- `src/*` except from: `.am`, `.rc` and `.in` files
- `AUTHORS`, `COPYING`, `PATENTS`
-Important: The files `utils/bit_reader_utils.{c,h}` have Godot-made
-changes to ensure they build for Javascript/HTML5. Those
-changes are marked with `// -- GODOT --` comments.
-
## mbedtls
@@ -606,7 +602,7 @@ instead of `miniz.h` as an external dependency.
## thorvg
- Upstream: https://github.com/Samsung/thorvg
-- Version: 0.7.0 (e527f565b770f0a41df821e6618ccaeea94f465e, 2021)
+- Version: 0.7.1 (d53eb2a880002cb770ace1c1ace9c5dfcfc28252, 2022)
- License: MIT
Files extracted from upstream source:
@@ -614,8 +610,6 @@ Files extracted from upstream source:
See `thorvg/update-thorvg.sh` for extraction instructions. Set the version
number and run the script.
-Patches in the `patches` directory should be re-applied after updates.
-
## vhacd
diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh
index 1dcbe92904..1db0f1df92 100644
--- a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh
+++ b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh
@@ -839,7 +839,7 @@ struct StateTableDriver
}
if (!c->in_place)
- buffer->swap_buffers ();
+ buffer->sync ();
}
public:
diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh
index d745c11431..0bf9bd2912 100644
--- a/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh
+++ b/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh
@@ -146,7 +146,7 @@ struct DuctileGlyphAction
HBUINT32 variationAxis; /* The 4-byte tag identifying the ductile axis.
* This would normally be 0x64756374 ('duct'),
* but you may use any axis the font contains. */
- HBFixed minimumLimit; /* The lowest value for the ductility axis tha
+ HBFixed minimumLimit; /* The lowest value for the ductility axis that
* still yields an acceptable appearance. Normally
* this will be 1.0. */
HBFixed noStretchValue; /* This is the default value that corresponds to
diff --git a/thirdparty/harfbuzz/src/hb-algs.hh b/thirdparty/harfbuzz/src/hb-algs.hh
index 446d87e28b..3a3ab08046 100644
--- a/thirdparty/harfbuzz/src/hb-algs.hh
+++ b/thirdparty/harfbuzz/src/hb-algs.hh
@@ -36,6 +36,7 @@
#include <algorithm>
#include <initializer_list>
+#include <functional>
#include <new>
/*
@@ -210,12 +211,23 @@ struct
}
HB_FUNCOBJ (hb_bool);
+template <typename T>
+static inline
+T hb_coerce (const T v) { return v; }
+template <typename T, typename V,
+ hb_enable_if (!hb_is_same (hb_decay<T>, hb_decay<V>) && std::is_pointer<V>::value)>
+static inline
+T hb_coerce (const V v) { return *v; }
+
struct
{
private:
template <typename T> constexpr auto
- impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
+ impl (const T& v, hb_priority<2>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
+
+ template <typename T> constexpr auto
+ impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v)))
template <typename T,
hb_enable_if (std::is_integral<T>::value)> constexpr auto
@@ -435,23 +447,29 @@ struct
private:
template <typename T1, typename T2> auto
- impl (T1&& v1, T2 &&v2, hb_priority<2>) const HB_AUTO_RETURN
+ impl (T1&& v1, T2 &&v2, hb_priority<3>) const HB_AUTO_RETURN
(
std::forward<T2> (v2).cmp (std::forward<T1> (v1)) == 0
)
template <typename T1, typename T2> auto
- impl (T1&& v1, T2 &&v2, hb_priority<1>) const HB_AUTO_RETURN
+ impl (T1&& v1, T2 &&v2, hb_priority<2>) const HB_AUTO_RETURN
(
std::forward<T1> (v1).cmp (std::forward<T2> (v2)) == 0
)
template <typename T1, typename T2> auto
- impl (T1&& v1, T2 &&v2, hb_priority<0>) const HB_AUTO_RETURN
+ impl (T1&& v1, T2 &&v2, hb_priority<1>) const HB_AUTO_RETURN
(
std::forward<T1> (v1) == std::forward<T2> (v2)
)
+ template <typename T1, typename T2> auto
+ impl (T1&& v1, T2 &&v2, hb_priority<0>) const HB_AUTO_RETURN
+ (
+ std::forward<T2> (v2) == std::forward<T1> (v1)
+ )
+
public:
template <typename T1, typename T2> auto
@@ -472,6 +490,10 @@ struct hb_pair_t
typedef T2 second_t;
typedef hb_pair_t<T1, T2> pair_t;
+ template <typename U1 = T1, typename U2 = T2,
+ hb_enable_if (std::is_default_constructible<U1>::value &&
+ std::is_default_constructible<U2>::value)>
+ hb_pair_t () : first (), second () {}
hb_pair_t (T1 a, T2 b) : first (a), second (b) {}
template <typename Q1, typename Q2,
@@ -870,7 +892,7 @@ hb_bsearch_impl (unsigned *pos, /* Out */
#pragma GCC diagnostic ignored "-Wcast-align"
V* p = (V*) (((const char *) base) + (mid * stride));
#pragma GCC diagnostic pop
- int c = compar ((const void *) hb_addressof (key), (const void *) p, ds...);
+ int c = compar ((const void *) std::addressof (key), (const void *) p, ds...);
if (c < 0)
max = mid - 1;
else if (c > 0)
diff --git a/thirdparty/harfbuzz/src/hb-array.hh b/thirdparty/harfbuzz/src/hb-array.hh
index 0beffb078f..1d1476d7cd 100644
--- a/thirdparty/harfbuzz/src/hb-array.hh
+++ b/thirdparty/harfbuzz/src/hb-array.hh
@@ -412,7 +412,7 @@ bool hb_array_t<T>::operator == (const hb_array_t<T> &o) const
return true;
}
-/* TODO Specialize opeator== for hb_bytes_t and hb_ubytes_t. */
+/* TODO Specialize operator== for hb_bytes_t and hb_ubytes_t. */
template <>
inline uint32_t hb_array_t<const char>::hash () const {
diff --git a/thirdparty/harfbuzz/src/hb-bimap.hh b/thirdparty/harfbuzz/src/hb-bimap.hh
index d466af8b60..a9e1278de7 100644
--- a/thirdparty/harfbuzz/src/hb-bimap.hh
+++ b/thirdparty/harfbuzz/src/hb-bimap.hh
@@ -33,20 +33,6 @@
/* Bi-directional map */
struct hb_bimap_t
{
- /* XXX(remove) */
- void init ()
- {
- forw_map.init ();
- back_map.init ();
- }
-
- /* XXX(remove) */
- void fini ()
- {
- forw_map.fini ();
- back_map.fini ();
- }
-
void reset ()
{
forw_map.reset ();
diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc
index be3161a54d..e50afcb203 100644
--- a/thirdparty/harfbuzz/src/hb-buffer.cc
+++ b/thirdparty/harfbuzz/src/hb-buffer.cc
@@ -86,7 +86,46 @@ hb_segment_properties_hash (const hb_segment_properties_t *p)
(intptr_t) (p->language);
}
+/**
+ * hb_segment_properties_overlay:
+ * @p: #hb_segment_properties_t to fill in.
+ * @src: #hb_segment_properties_t to fill in from.
+ *
+ * Fills in missing fields of @p from @src in a considered manner.
+ *
+ * First, if @p does not have direction set, direction is copied from @src.
+ *
+ * Next, if @p and @src have the same direction (which can be unset), if @p
+ * does not have script set, script is copied from @src.
+ *
+ * Finally, if @p and @src have the same direction and script (which either
+ * can be unset), if @p does not have language set, language is copied from
+ * @src.
+ *
+ * Since: 3.3.0
+ **/
+void
+hb_segment_properties_overlay (hb_segment_properties_t *p,
+ const hb_segment_properties_t *src)
+{
+ if (unlikely (!p || !src))
+ return;
+ if (!p->direction)
+ p->direction = src->direction;
+
+ if (p->direction != src->direction)
+ return;
+
+ if (!p->script)
+ p->script = src->script;
+
+ if (p->script != src->script)
+ return;
+
+ if (!p->language)
+ p->language = src->language;
+}
/* Here is how the buffer works internally:
*
@@ -96,14 +135,14 @@ hb_segment_properties_hash (const hb_segment_properties_t *p)
* As an optimization, both info and out_info may point to the
* same piece of memory, which is owned by info. This remains the
* case as long as out_len doesn't exceed i at any time.
- * In that case, swap_buffers() is mostly no-op and the glyph operations
+ * In that case, sync() is mostly no-op and the glyph operations
* operate mostly in-place.
*
* As soon as out_info gets longer than info, out_info is moved over
* to an alternate buffer (which we reuse the pos buffer for), and its
* current contents (out_len entries) are copied to the new place.
*
- * This should all remain transparent to the user. swap_buffers() then
+ * This should all remain transparent to the user. sync() then
* switches info over to out_info and does housekeeping.
*/
@@ -217,11 +256,24 @@ hb_buffer_t::get_scratch_buffer (unsigned int *size)
/* HarfBuzz-Internal API */
void
+hb_buffer_t::similar (const hb_buffer_t &src)
+{
+ hb_unicode_funcs_destroy (unicode);
+ unicode = hb_unicode_funcs_reference (src.unicode);
+ flags = src.flags;
+ cluster_level = src.cluster_level;
+ replacement = src.invisible;
+ invisible = src.invisible;
+ not_found = src.not_found;
+}
+
+void
hb_buffer_t::reset ()
{
hb_unicode_funcs_destroy (unicode);
unicode = hb_unicode_funcs_reference (hb_unicode_funcs_get_default ());
flags = HB_BUFFER_FLAG_DEFAULT;
+ cluster_level = HB_BUFFER_CLUSTER_LEVEL_DEFAULT;
replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
invisible = 0;
not_found = 0;
@@ -232,11 +284,10 @@ hb_buffer_t::reset ()
void
hb_buffer_t::clear ()
{
+ content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT;
props = default_props;
- scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
- content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
successful = true;
have_output = false;
have_positions = false;
@@ -244,16 +295,44 @@ hb_buffer_t::clear ()
idx = 0;
len = 0;
out_len = 0;
- out_info = info;
- serial = 0;
+ out_info = info;
memset (context, 0, sizeof context);
memset (context_len, 0, sizeof context_len);
deallocate_var_all ();
+ serial = 0;
+ scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
+}
+
+void
+hb_buffer_t::enter ()
+{
+ deallocate_var_all ();
+ serial = 0;
+ scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
+ if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_LEN_FACTOR)))
+ {
+ max_len = hb_max (len * HB_BUFFER_MAX_LEN_FACTOR,
+ (unsigned) HB_BUFFER_MAX_LEN_MIN);
+ }
+ if (likely (!hb_unsigned_mul_overflows (len, HB_BUFFER_MAX_OPS_FACTOR)))
+ {
+ max_ops = hb_max (len * HB_BUFFER_MAX_OPS_FACTOR,
+ (unsigned) HB_BUFFER_MAX_OPS_MIN);
+ }
+}
+void
+hb_buffer_t::leave ()
+{
+ max_len = HB_BUFFER_MAX_LEN_DEFAULT;
+ max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
+ deallocate_var_all ();
+ serial = 0;
}
+
void
hb_buffer_t::add (hb_codepoint_t codepoint,
unsigned int cluster)
@@ -307,7 +386,7 @@ hb_buffer_t::clear_positions ()
}
void
-hb_buffer_t::swap_buffers ()
+hb_buffer_t::sync ()
{
assert (have_output);
@@ -494,33 +573,6 @@ done:
}
void
-hb_buffer_t::unsafe_to_break_impl (unsigned int start, unsigned int end)
-{
- unsigned int cluster = UINT_MAX;
- cluster = _infos_find_min_cluster (info, start, end, cluster);
- _unsafe_to_break_set_mask (info, start, end, cluster);
-}
-void
-hb_buffer_t::unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end)
-{
- if (!have_output)
- {
- unsafe_to_break_impl (start, end);
- return;
- }
-
- assert (start <= out_len);
- assert (idx <= end);
-
- unsigned int cluster = UINT_MAX;
- cluster = _infos_find_min_cluster (out_info, start, out_len, cluster);
- cluster = _infos_find_min_cluster (info, idx, end, cluster);
-
- _unsafe_to_break_set_mask (out_info, start, out_len, cluster);
- _unsafe_to_break_set_mask (info, idx, end, cluster);
-}
-
-void
hb_buffer_t::guess_segment_properties ()
{
assert_unicode ();
@@ -565,12 +617,11 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) =
HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
0, /* invisible */
0, /* not_found */
- HB_BUFFER_SCRATCH_FLAG_DEFAULT,
- HB_BUFFER_MAX_LEN_DEFAULT,
- HB_BUFFER_MAX_OPS_DEFAULT,
+
HB_BUFFER_CONTENT_TYPE_INVALID,
HB_SEGMENT_PROPERTIES_DEFAULT,
+
false, /* successful */
false, /* have_output */
true /* have_positions */
@@ -610,6 +661,46 @@ hb_buffer_create ()
}
/**
+ * hb_buffer_create_similar:
+ * @src: An #hb_buffer_t
+ *
+ * Creates a new #hb_buffer_t, similar to hb_buffer_create(). The only
+ * difference is that the buffer is configured similarly to @src.
+ *
+ * Return value: (transfer full):
+ * A newly allocated #hb_buffer_t, similar to hb_buffer_create().
+ *
+ * Since: 3.3.0
+ **/
+hb_buffer_t *
+hb_buffer_create_similar (const hb_buffer_t *src)
+{
+ hb_buffer_t *buffer = hb_buffer_create ();
+
+ buffer->similar (*src);
+
+ return buffer;
+}
+
+/**
+ * hb_buffer_reset:
+ * @buffer: An #hb_buffer_t
+ *
+ * Resets the buffer to its initial status, as if it was just newly created
+ * with hb_buffer_create().
+ *
+ * Since: 0.9.2
+ **/
+void
+hb_buffer_reset (hb_buffer_t *buffer)
+{
+ if (unlikely (hb_object_is_immutable (buffer)))
+ return;
+
+ buffer->reset ();
+}
+
+/**
* hb_buffer_get_empty:
*
* Fetches an empty #hb_buffer_t.
@@ -1157,24 +1248,6 @@ hb_buffer_get_not_found_glyph (hb_buffer_t *buffer)
/**
- * hb_buffer_reset:
- * @buffer: An #hb_buffer_t
- *
- * Resets the buffer to its initial status, as if it was just newly created
- * with hb_buffer_create().
- *
- * Since: 0.9.2
- **/
-void
-hb_buffer_reset (hb_buffer_t *buffer)
-{
- if (unlikely (hb_object_is_immutable (buffer)))
- return;
-
- buffer->reset ();
-}
-
-/**
* hb_buffer_clear_contents:
* @buffer: An #hb_buffer_t
*
@@ -1749,6 +1822,8 @@ hb_buffer_append (hb_buffer_t *buffer,
if (!buffer->have_positions && source->have_positions)
buffer->clear_positions ();
+ hb_segment_properties_overlay (&buffer->props, &source->props);
+
memcpy (buffer->info + orig_len, source->info + start, (end - start) * sizeof (buffer->info[0]));
if (buffer->have_positions)
memcpy (buffer->pos + orig_len, source->pos + start, (end - start) * sizeof (buffer->pos[0]));
diff --git a/thirdparty/harfbuzz/src/hb-buffer.h b/thirdparty/harfbuzz/src/hb-buffer.h
index a183cb9d4a..9fbd7b1ec3 100644
--- a/thirdparty/harfbuzz/src/hb-buffer.h
+++ b/thirdparty/harfbuzz/src/hb-buffer.h
@@ -76,18 +76,68 @@ typedef struct hb_glyph_info_t {
* @HB_GLYPH_FLAG_UNSAFE_TO_BREAK: Indicates that if input text is broken at the
* beginning of the cluster this glyph is part of,
* then both sides need to be re-shaped, as the
- * result might be different. On the flip side,
- * it means that when this flag is not present,
- * then it's safe to break the glyph-run at the
- * beginning of this cluster, and the two sides
- * represent the exact same result one would get
- * if breaking input text at the beginning of
- * this cluster and shaping the two sides
- * separately. This can be used to optimize
- * paragraph layout, by avoiding re-shaping
- * of each line after line-breaking, or limiting
- * the reshaping to a small piece around the
- * breaking point only.
+ * result might be different.
+ * On the flip side, it means that when this
+ * flag is not present, then it is safe to break
+ * the glyph-run at the beginning of this
+ * cluster, and the two sides will represent the
+ * exact same result one would get if breaking
+ * input text at the beginning of this cluster
+ * and shaping the two sides separately.
+ * This can be used to optimize paragraph
+ * layout, by avoiding re-shaping of each line
+ * after line-breaking.
+ * @HB_GLYPH_FLAG_UNSAFE_TO_CONCAT: Indicates that if input text is changed on one
+ * side of the beginning of the cluster this glyph
+ * is part of, then the shaping results for the
+ * other side might change.
+ * Note that the absence of this flag will NOT by
+ * itself mean that it IS safe to concat text.
+ * Only two pieces of text both of which clear of
+ * this flag can be concatenated safely.
+ * This can be used to optimize paragraph
+ * layout, by avoiding re-shaping of each line
+ * after line-breaking, by limiting the
+ * reshaping to a small piece around the
+ * breaking positin only, even if the breaking
+ * position carries the
+ * #HB_GLYPH_FLAG_UNSAFE_TO_BREAK or when
+ * hyphenation or other text transformation
+ * happens at line-break position, in the following
+ * way:
+ * 1. Iterate back from the line-break position
+ * until the first cluster start position that is
+ * NOT unsafe-to-concat, 2. shape the segment from
+ * there till the end of line, 3. check whether the
+ * resulting glyph-run also is clear of the
+ * unsafe-to-concat at its start-of-text position;
+ * if it is, just splice it into place and the line
+ * is shaped; If not, move on to a position further
+ * back that is clear of unsafe-to-concat and retry
+ * from there, and repeat.
+ * At the start of next line a similar algorithm can
+ * be implemented. That is: 1. Iterate forward from
+ * the line-break position untill the first cluster
+ * start position that is NOT unsafe-to-concat, 2.
+ * shape the segment from beginning of the line to
+ * that position, 3. check whether the resulting
+ * glyph-run also is clear of the unsafe-to-concat
+ * at its end-of-text position; if it is, just splice
+ * it into place and the beginning is shaped; If not,
+ * move on to a position further forward that is clear
+ * of unsafe-to-concat and retry up to there, and repeat.
+ * A slight complication will arise in the
+ * implementation of the algorithm above,
+ * because while our buffer API has a way to
+ * return flags for position corresponding to
+ * start-of-text, there is currently no position
+ * corresponding to end-of-text. This limitation
+ * can be alleviated by shaping more text than needed
+ * and looking for unsafe-to-concat flag within text
+ * clusters.
+ * The #HB_GLYPH_FLAG_UNSAFE_TO_BREAK flag will
+ * always imply this flag.
+ * Since: 3.3.0
* @HB_GLYPH_FLAG_DEFINED: All the currently defined flags.
*
* Flags for #hb_glyph_info_t.
@@ -96,8 +146,9 @@ typedef struct hb_glyph_info_t {
*/
typedef enum { /*< flags >*/
HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001,
+ HB_GLYPH_FLAG_UNSAFE_TO_CONCAT = 0x00000002,
- HB_GLYPH_FLAG_DEFINED = 0x00000001 /* OR of all defined flags */
+ HB_GLYPH_FLAG_DEFINED = 0x00000003 /* OR of all defined flags */
} hb_glyph_flags_t;
HB_EXTERN hb_glyph_flags_t
@@ -170,6 +221,9 @@ hb_segment_properties_equal (const hb_segment_properties_t *a,
HB_EXTERN unsigned int
hb_segment_properties_hash (const hb_segment_properties_t *p);
+HB_EXTERN void
+hb_segment_properties_overlay (hb_segment_properties_t *p,
+ const hb_segment_properties_t *src);
/**
@@ -185,6 +239,13 @@ HB_EXTERN hb_buffer_t *
hb_buffer_create (void);
HB_EXTERN hb_buffer_t *
+hb_buffer_create_similar (const hb_buffer_t *src);
+
+HB_EXTERN void
+hb_buffer_reset (hb_buffer_t *buffer);
+
+
+HB_EXTERN hb_buffer_t *
hb_buffer_get_empty (void);
HB_EXTERN hb_buffer_t *
@@ -391,8 +452,9 @@ HB_EXTERN hb_codepoint_t
hb_buffer_get_not_found_glyph (hb_buffer_t *buffer);
-HB_EXTERN void
-hb_buffer_reset (hb_buffer_t *buffer);
+/*
+ * Content API.
+ */
HB_EXTERN void
hb_buffer_clear_contents (hb_buffer_t *buffer);
diff --git a/thirdparty/harfbuzz/src/hb-buffer.hh b/thirdparty/harfbuzz/src/hb-buffer.hh
index 0f8140f1b3..adf4aa2b6f 100644
--- a/thirdparty/harfbuzz/src/hb-buffer.hh
+++ b/thirdparty/harfbuzz/src/hb-buffer.hh
@@ -67,8 +67,8 @@ enum hb_buffer_scratch_flags_t {
HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000002u,
HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u,
HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u,
- HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK = 0x00000010u,
- HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000020u,
+ HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000010u,
+ HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS = 0x00000020u,
/* Reserved for complex shapers' internal use. */
HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u,
@@ -87,18 +87,21 @@ struct hb_buffer_t
{
hb_object_header_t header;
- /* Information about how the text in the buffer should be treated */
+ /*
+ * Information about how the text in the buffer should be treated.
+ */
+
hb_unicode_funcs_t *unicode; /* Unicode functions */
hb_buffer_flags_t flags; /* BOT / EOT / etc. */
hb_buffer_cluster_level_t cluster_level;
hb_codepoint_t replacement; /* U+FFFD or something else. */
hb_codepoint_t invisible; /* 0 or something else. */
hb_codepoint_t not_found; /* 0 or something else. */
- hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
- unsigned int max_len; /* Maximum allowed len. */
- int max_ops; /* Maximum allowed operations. */
- /* Buffer contents */
+ /*
+ * Buffer contents
+ */
+
hb_buffer_content_type_t content_type;
hb_segment_properties_t props; /* Script, language, direction */
@@ -115,8 +118,6 @@ struct hb_buffer_t
hb_glyph_info_t *out_info;
hb_glyph_position_t *pos;
- unsigned int serial;
-
/* Text before / after the main buffer contents.
* Always in Unicode, and ordered outward.
* Index 0 is for "pre-context", 1 for "post-context". */
@@ -124,7 +125,25 @@ struct hb_buffer_t
hb_codepoint_t context[2][CONTEXT_LENGTH];
unsigned int context_len[2];
- /* Debugging API */
+
+ /*
+ * Managed by enter / leave
+ */
+
+#ifndef HB_NDEBUG
+ uint8_t allocated_var_bits;
+#endif
+ uint8_t serial;
+ hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
+ unsigned int max_len; /* Maximum allowed len. */
+ int max_ops; /* Maximum allowed operations. */
+ /* The bits here reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
+
+
+ /*
+ * Messaging callback
+ */
+
#ifndef HB_NO_BUFFER_MESSAGE
hb_buffer_message_func_t message_func;
void *message_data;
@@ -134,11 +153,6 @@ struct hb_buffer_t
static constexpr unsigned message_depth = 0u;
#endif
- /* Internal debugging. */
- /* The bits here reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
-#ifndef HB_NDEBUG
- uint8_t allocated_var_bits;
-#endif
/* Methods */
@@ -190,12 +204,17 @@ struct hb_buffer_t
hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; }
hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; }
+ HB_INTERNAL void similar (const hb_buffer_t &src);
HB_INTERNAL void reset ();
HB_INTERNAL void clear ();
+ /* Called around shape() */
+ HB_INTERNAL void enter ();
+ HB_INTERNAL void leave ();
+
unsigned int backtrack_len () const { return have_output ? out_len : idx; }
unsigned int lookahead_len () const { return len - idx; }
- unsigned int next_serial () { return serial++; }
+ uint8_t next_serial () { return ++serial ? serial : ++serial; }
HB_INTERNAL void add (hb_codepoint_t codepoint,
unsigned int cluster);
@@ -252,7 +271,7 @@ struct hb_buffer_t
HB_INTERNAL void guess_segment_properties ();
- HB_INTERNAL void swap_buffers ();
+ HB_INTERNAL void sync ();
HB_INTERNAL void clear_output ();
HB_INTERNAL void clear_positions ();
@@ -366,15 +385,80 @@ struct hb_buffer_t
/* Merge clusters for deleting current glyph, and skip it. */
HB_INTERNAL void delete_glyph ();
- void unsafe_to_break (unsigned int start,
- unsigned int end)
+
+ void set_glyph_flags (hb_mask_t mask,
+ unsigned start = 0,
+ unsigned end = (unsigned) -1,
+ bool interior = false,
+ bool from_out_buffer = false)
{
- if (end - start < 2)
+ end = hb_min (end, len);
+
+ if (interior && !from_out_buffer && end - start < 2)
return;
- unsafe_to_break_impl (start, end);
+
+ scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
+
+ if (!from_out_buffer || !have_output)
+ {
+ if (!interior)
+ {
+ for (unsigned i = start; i < end; i++)
+ info[i].mask |= mask;
+ }
+ else
+ {
+ unsigned cluster = _infos_find_min_cluster (info, start, end);
+ _infos_set_glyph_flags (info, start, end, cluster, mask);
+ }
+ }
+ else
+ {
+ assert (start <= out_len);
+ assert (idx <= end);
+
+ if (!interior)
+ {
+ for (unsigned i = start; i < out_len; i++)
+ out_info[i].mask |= mask;
+ for (unsigned i = idx; i < end; i++)
+ info[i].mask |= mask;
+ }
+ else
+ {
+ unsigned cluster = _infos_find_min_cluster (info, idx, end);
+ cluster = _infos_find_min_cluster (out_info, start, out_len, cluster);
+
+ _infos_set_glyph_flags (out_info, start, out_len, cluster, mask);
+ _infos_set_glyph_flags (info, idx, end, cluster, mask);
+ }
+ }
+ }
+
+ void unsafe_to_break (unsigned int start = 0, unsigned int end = -1)
+ {
+ set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
+ start, end,
+ true);
+ }
+ void unsafe_to_concat (unsigned int start = 0, unsigned int end = -1)
+ {
+ set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
+ start, end,
+ true);
+ }
+ void unsafe_to_break_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
+ {
+ set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK | HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
+ start, end,
+ true, true);
+ }
+ void unsafe_to_concat_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
+ {
+ set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
+ start, end,
+ false, true);
}
- HB_INTERNAL void unsafe_to_break_impl (unsigned int start, unsigned int end);
- HB_INTERNAL void unsafe_to_break_from_outbuffer (unsigned int start, unsigned int end);
/* Internal methods */
@@ -465,36 +549,31 @@ struct hb_buffer_t
set_cluster (hb_glyph_info_t &inf, unsigned int cluster, unsigned int mask = 0)
{
if (inf.cluster != cluster)
- {
- if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
- inf.mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
- else
- inf.mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
- }
+ inf.mask = (inf.mask & ~HB_GLYPH_FLAG_DEFINED) | (mask & HB_GLYPH_FLAG_DEFINED);
inf.cluster = cluster;
}
-
+ void
+ _infos_set_glyph_flags (hb_glyph_info_t *infos,
+ unsigned int start, unsigned int end,
+ unsigned int cluster,
+ hb_mask_t mask)
+ {
+ for (unsigned int i = start; i < end; i++)
+ if (cluster != infos[i].cluster)
+ {
+ scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS;
+ infos[i].mask |= mask;
+ }
+ }
static unsigned
_infos_find_min_cluster (const hb_glyph_info_t *infos,
unsigned start, unsigned end,
- unsigned cluster)
+ unsigned cluster = UINT_MAX)
{
for (unsigned int i = start; i < end; i++)
cluster = hb_min (cluster, infos[i].cluster);
return cluster;
}
- void
- _unsafe_to_break_set_mask (hb_glyph_info_t *infos,
- unsigned int start, unsigned int end,
- unsigned int cluster)
- {
- for (unsigned int i = start; i < end; i++)
- if (cluster != infos[i].cluster)
- {
- scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK;
- infos[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
- }
- }
void clear_glyph_flags (hb_mask_t mask = 0)
{
diff --git a/thirdparty/harfbuzz/src/hb-cff-interp-common.hh b/thirdparty/harfbuzz/src/hb-cff-interp-common.hh
index c251e2d0ed..641de0eff2 100644
--- a/thirdparty/harfbuzz/src/hb-cff-interp-common.hh
+++ b/thirdparty/harfbuzz/src/hb-cff-interp-common.hh
@@ -217,9 +217,6 @@ inline unsigned int OpCode_Size (op_code_t op) { return Is_OpCode_ESC (op) ? 2:
struct number_t
{
- void init () { set_real (0.0); }
- void fini () {}
-
void set_int (int v) { value = v; }
int to_int () const { return value; }
@@ -245,7 +242,7 @@ struct number_t
}
protected:
- double value;
+ double value = 0.;
};
/* byte string */
@@ -380,10 +377,8 @@ struct cff_stack_t
count = 0;
elements.init ();
elements.resize (kSizeLimit);
- for (unsigned int i = 0; i < elements.length; i++)
- elements[i].init ();
}
- void fini () { elements.fini_deep (); }
+ void fini () { elements.fini (); }
ELEM& operator [] (unsigned int i)
{
@@ -523,9 +518,6 @@ struct arg_stack_t : cff_stack_t<ARG, 513>
/* an operator prefixed by its operands in a byte string */
struct op_str_t
{
- void init () {}
- void fini () {}
-
op_code_t op;
byte_str_t str;
};
@@ -553,7 +545,7 @@ struct parsed_values_t
opStart = 0;
values.init ();
}
- void fini () { values.fini_deep (); }
+ void fini () { values.fini (); }
void add_op (op_code_t op, const byte_str_ref_t& str_ref = byte_str_ref_t ())
{
diff --git a/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh b/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh
index 52d778ffe2..ef299369b5 100644
--- a/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh
+++ b/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh
@@ -94,12 +94,6 @@ struct biased_subrs_t
struct point_t
{
- void init ()
- {
- x.init ();
- y.init ();
- }
-
void set_int (int _x, int _y)
{
x.set_int (_x);
@@ -128,7 +122,7 @@ struct cs_interp_env_t : interp_env_t<ARG>
hstem_count = 0;
vstem_count = 0;
hintmask_size = 0;
- pt.init ();
+ pt.set_int (0, 0);
callStack.init ();
globalSubrs.init (globalSubrs_);
localSubrs.init (localSubrs_);
@@ -841,7 +835,6 @@ struct path_procs_t
if (likely (env.argStack.get_count () == 11))
{
point_t d;
- d.init ();
for (unsigned int i = 0; i < 10; i += 2)
d.move (env.eval_arg (i), env.eval_arg (i+1));
diff --git a/thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh b/thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh
index d961566447..766183760e 100644
--- a/thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh
+++ b/thirdparty/harfbuzz/src/hb-cff2-interp-cs.hh
@@ -35,18 +35,6 @@ using namespace OT;
struct blend_arg_t : number_t
{
- void init ()
- {
- number_t::init ();
- deltas.init ();
- }
-
- void fini ()
- {
- number_t::fini ();
- deltas.fini_deep ();
- }
-
void set_int (int v) { reset_blends (); number_t::set_int (v); }
void set_fixed (int32_t v) { reset_blends (); number_t::set_fixed (v); }
void set_real (double v) { reset_blends (); number_t::set_real (v); }
@@ -202,7 +190,7 @@ struct cff2_cs_opset_t : cs_opset_t<blend_arg_t, OPSET, cff2_cs_interp_env_t, PA
switch (op) {
case OpCode_callsubr:
case OpCode_callgsubr:
- /* a subroutine number shoudln't be a blended value */
+ /* a subroutine number shouldn't be a blended value */
if (unlikely (env.argStack.peek ().blending ()))
{
env.set_error ();
diff --git a/thirdparty/harfbuzz/src/hb-common.cc b/thirdparty/harfbuzz/src/hb-common.cc
index 26c8ad0f49..249a8a8010 100644
--- a/thirdparty/harfbuzz/src/hb-common.cc
+++ b/thirdparty/harfbuzz/src/hb-common.cc
@@ -29,10 +29,31 @@
#include "hb.hh"
#include "hb-machinery.hh"
+#if !defined(HB_NO_SETLOCALE) && (!defined(HAVE_NEWLOCALE) || !defined(HAVE_USELOCALE))
+#define HB_NO_SETLOCALE 1
+#endif
+
+#ifndef HB_NO_SETLOCALE
+
#include <locale.h>
+#ifdef HAVE_XLOCALE_H
+#include <xlocale.h> // Needed on BSD/OS X for uselocale
+#endif
+
+#ifdef WIN32
+#define hb_locale_t _locale_t
+#else
+#define hb_locale_t locale_t
+#endif
+#define hb_setlocale setlocale
+#define hb_uselocale uselocale
+
+#else
+
+#define hb_locale_t void *
+#define hb_setlocale(Category, Locale) "C"
+#define hb_uselocale(Locale) ((hb_locale_t) 0)
-#ifdef HB_NO_SETLOCALE
-#define setlocale(Category, Locale) "C"
#endif
/**
@@ -122,7 +143,7 @@ hb_tag_from_string (const char *str, int len)
* @tag: #hb_tag_t to convert
* @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t): Converted string
*
- * Converts an #hb_tag_t to a string and returns it in @buf.
+ * Converts an #hb_tag_t to a string and returns it in @buf.
* Strings will be four characters long.
*
* Since: 0.9.5
@@ -151,13 +172,13 @@ const char direction_strings[][4] = {
* @str: (array length=len) (element-type uint8_t): String to convert
* @len: Length of @str, or -1 if it is %NULL-terminated
*
- * Converts a string to an #hb_direction_t.
+ * Converts a string to an #hb_direction_t.
*
* Matching is loose and applies only to the first letter. For
* examples, "LTR" and "left-to-right" will both return #HB_DIRECTION_LTR.
*
* Unmatched strings will return #HB_DIRECTION_INVALID.
- *
+ *
* Return value: The #hb_direction_t matching @str
*
* Since: 0.9.2
@@ -413,7 +434,7 @@ hb_language_get_default ()
hb_language_t language = default_language;
if (unlikely (language == HB_LANGUAGE_INVALID))
{
- language = hb_language_from_string (setlocale (LC_CTYPE, nullptr), -1);
+ language = hb_language_from_string (hb_setlocale (LC_CTYPE, nullptr), -1);
(void) default_language.cmpexch (HB_LANGUAGE_INVALID, language);
}
@@ -1039,6 +1060,47 @@ hb_variation_from_string (const char *str, int len,
return false;
}
+#ifndef HB_NO_SETLOCALE
+
+static inline void free_static_C_locale ();
+
+static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<hb_locale_t>,
+ hb_C_locale_lazy_loader_t>
+{
+ static hb_locale_t create ()
+ {
+ hb_locale_t l = newlocale (LC_ALL_MASK, "C", NULL);
+ if (!l)
+ return l;
+
+ hb_atexit (free_static_C_locale);
+
+ return l;
+ }
+ static void destroy (hb_locale_t l)
+ {
+ freelocale (l);
+ }
+ static hb_locale_t get_null ()
+ {
+ return (hb_locale_t) 0;
+ }
+} static_C_locale;
+
+static inline
+void free_static_C_locale ()
+{
+ static_C_locale.free_instance ();
+}
+
+static hb_locale_t
+get_C_locale ()
+{
+ return static_C_locale.get_unconst ();
+}
+
+#endif
+
/**
* hb_variation_to_string:
* @variation: an #hb_variation_t to convert
@@ -1064,7 +1126,11 @@ hb_variation_to_string (hb_variation_t *variation,
while (len && s[len - 1] == ' ')
len--;
s[len++] = '=';
+
+ hb_locale_t oldlocale HB_UNUSED;
+ oldlocale = hb_uselocale (get_C_locale ());
len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value));
+ (void) hb_uselocale (oldlocale);
assert (len < ARRAY_LENGTH (s));
len = hb_min (len, size - 1);
diff --git a/thirdparty/harfbuzz/src/hb-coretext.cc b/thirdparty/harfbuzz/src/hb-coretext.cc
index a512f3b8b7..5f383064c4 100644
--- a/thirdparty/harfbuzz/src/hb-coretext.cc
+++ b/thirdparty/harfbuzz/src/hb-coretext.cc
@@ -481,8 +481,8 @@ struct active_feature_t {
a->rec.setting < b->rec.setting ? -1 : a->rec.setting > b->rec.setting ? 1 :
0;
}
- bool operator== (const active_feature_t *f) {
- return cmp (this, f) == 0;
+ bool operator== (const active_feature_t& f) const {
+ return cmp (this, &f) == 0;
}
};
@@ -677,7 +677,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
{
active_features.push (event->feature);
} else {
- active_feature_t *feature = active_features.find (&event->feature);
+ active_feature_t *feature = active_features.lsearch (event->feature);
if (feature)
active_features.remove (feature - active_features.arrayZ);
}
@@ -1213,7 +1213,8 @@ resize_and_retry:
}
}
- buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
+ buffer->clear_glyph_flags ();
+ buffer->unsafe_to_break ();
#undef FAIL
diff --git a/thirdparty/harfbuzz/src/hb-directwrite.cc b/thirdparty/harfbuzz/src/hb-directwrite.cc
index dea87b8cd0..f177ff31c0 100644
--- a/thirdparty/harfbuzz/src/hb-directwrite.cc
+++ b/thirdparty/harfbuzz/src/hb-directwrite.cc
@@ -762,7 +762,8 @@ retry_getglyphs:
if (isRightToLeft) hb_buffer_reverse (buffer);
- buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
+ buffer->clear_glyph_flags ();
+ buffer->unsafe_to_break ();
delete [] clusterMap;
delete [] glyphIndices;
diff --git a/thirdparty/harfbuzz/src/hb-draw.h b/thirdparty/harfbuzz/src/hb-draw.h
index bddc876399..f82cc34842 100644
--- a/thirdparty/harfbuzz/src/hb-draw.h
+++ b/thirdparty/harfbuzz/src/hb-draw.h
@@ -50,7 +50,7 @@ typedef void (*hb_draw_close_path_func_t) (void *user_data);
*
* Glyph draw callbacks.
*
- * _move_to, _line_to and _cubic_to calls are nessecary to be defined but we
+ * _move_to, _line_to and _cubic_to calls are necessary to be defined but we
* translate _quadratic_to calls to _cubic_to if the callback isn't defined.
*
* Since: EXPERIMENTAL
diff --git a/thirdparty/harfbuzz/src/hb-face.cc b/thirdparty/harfbuzz/src/hb-face.cc
index 2c0087370c..5365598636 100644
--- a/thirdparty/harfbuzz/src/hb-face.cc
+++ b/thirdparty/harfbuzz/src/hb-face.cc
@@ -143,7 +143,7 @@ hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
typedef struct hb_face_for_data_closure_t {
hb_blob_t *blob;
- unsigned int index;
+ uint16_t index;
} hb_face_for_data_closure_t;
static hb_face_for_data_closure_t *
@@ -156,7 +156,7 @@ _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index)
return nullptr;
closure->blob = blob;
- closure->index = index;
+ closure->index = (uint16_t) (index & 0xFFFFu);
return closure;
}
@@ -195,9 +195,19 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
* @index: The index of the face within @blob
*
* Constructs a new face object from the specified blob and
- * a face index into that blob. This is used for blobs of
- * file formats such as Dfont and TTC that can contain more
- * than one face.
+ * a face index into that blob.
+ *
+ * The face index is used for blobs of file formats such as TTC and
+ * and DFont that can contain more than one face. Face indices within
+ * such collections are zero-based.
+ *
+ * <note>Note: If the blob font format is not a collection, @index
+ * is ignored. Otherwise, only the lower 16-bits of @index are used.
+ * The unmodified @index can be accessed via hb_face_get_index().</note>
+ *
+ * <note>Note: The high 16-bits of @index, if non-zero, are used by
+ * hb_font_create() to load named-instances in variable fonts. See
+ * hb_font_create() for details.</note>
*
* Return value: (transfer full): The new face object
*
@@ -420,7 +430,8 @@ hb_face_reference_blob (hb_face_t *face)
* Assigns the specified face-index to @face. Fails if the
* face is immutable.
*
- * <note>Note: face indices within a collection are zero-based.</note>
+ * <note>Note: changing the index has no effect on the face itself
+ * This only changes the value returned by hb_face_get_index().</note>
*
* Since: 0.9.2
**/
diff --git a/thirdparty/harfbuzz/src/hb-font.cc b/thirdparty/harfbuzz/src/hb-font.cc
index fa8da96395..350fcac139 100644
--- a/thirdparty/harfbuzz/src/hb-font.cc
+++ b/thirdparty/harfbuzz/src/hb-font.cc
@@ -631,7 +631,7 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
* @destroy: (nullable): A callback to call when @data is not needed anymore
* @replace: Whether to replace an existing data with the same key
*
- * Attaches a user-data key/data pair to the specified font-functions structure.
+ * Attaches a user-data key/data pair to the specified font-functions structure.
*
* Return value: %true if success, %false otherwise
*
@@ -821,7 +821,7 @@ hb_font_get_glyph (hb_font_t *font,
* @glyph: (out): The glyph ID retrieved
*
* Fetches the nominal glyph ID for a Unicode code point in the
- * specified font.
+ * specified font.
*
* This version of the function should not be used to fetch glyph IDs
* for code points modified by variation selectors. For variation-selector
@@ -940,7 +940,7 @@ hb_font_get_glyph_v_advance (hb_font_t *font,
* @advance_stride: The stride between successive advances
*
* Fetches the advances for a sequence of glyph IDs in the specified
- * font, for horizontal text segments.
+ * font, for horizontal text segments.
*
* Since: 1.8.6
**/
@@ -964,7 +964,7 @@ hb_font_get_glyph_h_advances (hb_font_t* font,
* @advance_stride: (out): The stride between successive advances
*
* Fetches the advances for a sequence of glyph IDs in the specified
- * font, for vertical text segments.
+ * font, for vertical text segments.
*
* Since: 1.8.6
**/
@@ -1278,7 +1278,7 @@ hb_font_get_glyph_origin_for_direction (hb_font_t *font,
* @font: #hb_font_t to work upon
* @glyph: The glyph ID to query
* @direction: The direction of the text segment
- * @x: (inout): Input = The original X coordinate
+ * @x: (inout): Input = The original X coordinate
* Output = The X coordinate plus the X-coordinate of the origin
* @y: (inout): Input = The original Y coordinate
* Output = The Y coordinate plus the Y-coordinate of the origin
@@ -1306,7 +1306,7 @@ hb_font_add_glyph_origin_for_direction (hb_font_t *font,
* @font: #hb_font_t to work upon
* @glyph: The glyph ID to query
* @direction: The direction of the text segment
- * @x: (inout): Input = The original X coordinate
+ * @x: (inout): Input = The original X coordinate
* Output = The X coordinate minus the X-coordinate of the origin
* @y: (inout): Input = The original Y coordinate
* Output = The Y coordinate minus the Y-coordinate of the origin
@@ -1477,6 +1477,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
1000, /* x_scale */
1000, /* y_scale */
+ 0., /* slant */
+ 0., /* slant_xy; */
1<<16, /* x_mult */
1<<16, /* y_mult */
@@ -1521,6 +1523,13 @@ _hb_font_create (hb_face_t *face)
*
* Constructs a new font object from the specified face.
*
+ * <note>Note: If @face's index value (as passed to hb_face_create()
+ * has non-zero top 16-bits, those bits minus one are passed to
+ * hb_font_set_var_named_instance(), effectively loading a named-instance
+ * of a variable font, instead of the default-instance. This allows
+ * specifying which named-instance to load by default when creating the
+ * face.</note>
+ *
* Return value: (transfer full): The new font object
*
* Since: 0.9.2
@@ -1535,6 +1544,11 @@ hb_font_create (hb_face_t *face)
hb_ot_font_set_funcs (font);
#endif
+#ifndef HB_NO_VAR
+ if (face && face->index >> 16)
+ hb_font_set_var_named_instance (font, (face->index >> 16) - 1);
+#endif
+
return font;
}
@@ -1578,6 +1592,7 @@ hb_font_create_sub_font (hb_font_t *parent)
font->x_scale = parent->x_scale;
font->y_scale = parent->y_scale;
+ font->slant = parent->slant;
font->mults_changed ();
font->x_ppem = parent->x_ppem;
font->y_ppem = parent->y_ppem;
@@ -1668,12 +1683,12 @@ hb_font_destroy (hb_font_t *font)
/**
* hb_font_set_user_data: (skip)
* @font: #hb_font_t to work upon
- * @key: The user-data key
+ * @key: The user-data key
* @data: A pointer to the user data
* @destroy: (nullable): A callback to call when @data is not needed anymore
* @replace: Whether to replace an existing data with the same key
*
- * Attaches a user-data key/data pair to the specified font object.
+ * Attaches a user-data key/data pair to the specified font object.
*
* Return value: %true if success, %false otherwise
*
@@ -1875,7 +1890,7 @@ hb_font_set_funcs (hb_font_t *font,
* @font_data: (destroy destroy) (scope notified): Data to attach to @font
* @destroy: (nullable): The function to call when @font_data is not needed anymore
*
- * Replaces the user data attached to a font, updating the font's
+ * Replaces the user data attached to a font, updating the font's
* @destroy callback.
*
* Since: 0.9.2
@@ -1949,7 +1964,7 @@ hb_font_get_scale (hb_font_t *font,
* @x_ppem: Horizontal ppem value to assign
* @y_ppem: Vertical ppem value to assign
*
- * Sets the horizontal and vertical pixels-per-em (ppem) of a font.
+ * Sets the horizontal and vertical pixels-per-em (ppem) of a font.
*
* Since: 0.9.2
**/
@@ -1971,7 +1986,7 @@ hb_font_set_ppem (hb_font_t *font,
* @x_ppem: (out): Horizontal ppem value
* @y_ppem: (out): Vertical ppem value
*
- * Fetches the horizontal and vertical points-per-em (ppem) of a font.
+ * Fetches the horizontal and vertical points-per-em (ppem) of a font.
*
* Since: 0.9.2
**/
@@ -2015,7 +2030,7 @@ hb_font_set_ptem (hb_font_t *font,
*
* Return value: Point size. A value of zero means "not set."
*
- * Since: 0.9.2
+ * Since: 1.6.0
**/
float
hb_font_get_ptem (hb_font_t *font)
@@ -2023,6 +2038,49 @@ hb_font_get_ptem (hb_font_t *font)
return font->ptem;
}
+/**
+ * hb_font_set_synthetic_slant:
+ * @font: #hb_font_t to work upon
+ * @slant: synthetic slant value.
+ *
+ * Sets the "synthetic slant" of a font. By default is zero.
+ * Synthetic slant is the graphical skew that the renderer
+ * applies to the font at rendering time.
+ *
+ * HarfBuzz needs to know this value to adjust shaping results,
+ * metrics, and style values to match the slanted rendering.
+ *
+ * <note>Note: The slant value is a ratio. For example, a
+ * 20% slant would be represented as a 0.2 value.</note>
+ *
+ * Since: 3.3.0
+ **/
+HB_EXTERN void
+hb_font_set_synthetic_slant (hb_font_t *font, float slant)
+{
+ if (hb_object_is_immutable (font))
+ return;
+
+ font->slant = slant;
+ font->mults_changed ();
+}
+
+/**
+ * hb_font_get_synthetic_slant:
+ * @font: #hb_font_t to work upon
+ *
+ * Fetches the "synthetic slant" of a font.
+ *
+ * Return value: Synthetic slant. By default is zero.
+ *
+ * Since: 3.3.0
+ **/
+HB_EXTERN float
+hb_font_get_synthetic_slant (hb_font_t *font)
+{
+ return font->slant;
+}
+
#ifndef HB_NO_VAR
/*
* Variations
@@ -2036,6 +2094,10 @@ hb_font_get_ptem (hb_font_t *font)
*
* Applies a list of font-variation settings to a font.
*
+ * Note that this overrides all existing variations set on @font.
+ * Axes not included in @variations will be effectively set to their
+ * default values.
+ *
* Since: 1.4.2
*/
void
@@ -2091,6 +2153,10 @@ hb_font_set_variations (hb_font_t *font,
* Applies a list of variation coordinates (in design-space units)
* to a font.
*
+ * Note that this overrides all existing variations set on @font.
+ * Axes not included in @coords will be effectively set to their
+ * default values.
+ *
* Since: 1.4.2
*/
void
@@ -2154,6 +2220,10 @@ hb_font_set_var_named_instance (hb_font_t *font,
* Applies a list of variation coordinates (in normalized units)
* to a font.
*
+ * Note that this overrides all existing variations set on @font.
+ * Axes not included in @coords will be effectively set to their
+ * default values.
+ *
* <note>Note: Coordinates should be normalized to 2.14.</note>
*
* Since: 1.4.2
@@ -2196,14 +2266,19 @@ hb_font_set_var_coords_normalized (hb_font_t *font,
/**
* hb_font_get_var_coords_normalized:
* @font: #hb_font_t to work upon
- * @length: Number of coordinates retrieved
+ * @length: (out): Number of coordinates retrieved
*
* Fetches the list of normalized variation coordinates currently
* set on a font.
*
+ * Note that this returned array may only contain values for some
+ * (or none) of the axes; omitted axes effectively have zero values.
+ *
* Return value is valid as long as variation coordinates of the font
* are not modified.
*
+ * Return value: coordinates array
+ *
* Since: 1.4.2
*/
const int *
@@ -2216,18 +2291,24 @@ hb_font_get_var_coords_normalized (hb_font_t *font,
return font->coords;
}
-#ifdef HB_EXPERIMENTAL_API
/**
* hb_font_get_var_coords_design:
* @font: #hb_font_t to work upon
- * @length: (out): number of coordinates
+ * @length: (out): Number of coordinates retrieved
+ *
+ * Fetches the list of variation coordinates (in design-space units) currently
+ * set on a font.
+ *
+ * Note that this returned array may only contain values for some
+ * (or none) of the axes; omitted axes effectively have their default
+ * values.
*
* Return value is valid as long as variation coordinates of the font
* are not modified.
*
* Return value: coordinates array
*
- * Since: EXPERIMENTAL
+ * Since: 3.3.0
*/
const float *
hb_font_get_var_coords_design (hb_font_t *font,
@@ -2239,7 +2320,6 @@ hb_font_get_var_coords_design (hb_font_t *font,
return font->design_coords;
}
#endif
-#endif
#ifndef HB_DISABLE_DEPRECATED
/*
diff --git a/thirdparty/harfbuzz/src/hb-font.h b/thirdparty/harfbuzz/src/hb-font.h
index 15dc126523..a3bbb2e37b 100644
--- a/thirdparty/harfbuzz/src/hb-font.h
+++ b/thirdparty/harfbuzz/src/hb-font.h
@@ -1024,6 +1024,12 @@ HB_EXTERN float
hb_font_get_ptem (hb_font_t *font);
HB_EXTERN void
+hb_font_set_synthetic_slant (hb_font_t *font, float slant);
+
+HB_EXTERN float
+hb_font_get_synthetic_slant (hb_font_t *font);
+
+HB_EXTERN void
hb_font_set_variations (hb_font_t *font,
const hb_variation_t *variations,
unsigned int variations_length);
@@ -1033,11 +1039,9 @@ hb_font_set_var_coords_design (hb_font_t *font,
const float *coords,
unsigned int coords_length);
-#ifdef HB_EXPERIMENTAL_API
HB_EXTERN const float *
hb_font_get_var_coords_design (hb_font_t *font,
unsigned int *length);
-#endif
HB_EXTERN void
hb_font_set_var_coords_normalized (hb_font_t *font,
diff --git a/thirdparty/harfbuzz/src/hb-font.hh b/thirdparty/harfbuzz/src/hb-font.hh
index 1b7f445e8b..0d73589e8c 100644
--- a/thirdparty/harfbuzz/src/hb-font.hh
+++ b/thirdparty/harfbuzz/src/hb-font.hh
@@ -109,6 +109,8 @@ struct hb_font_t
int32_t x_scale;
int32_t y_scale;
+ float slant;
+ float slant_xy;
int64_t x_mult;
int64_t y_mult;
@@ -617,6 +619,7 @@ struct hb_font_t
signed upem = face->get_upem ();
x_mult = ((int64_t) x_scale << 16) / upem;
y_mult = ((int64_t) y_scale << 16) / upem;
+ slant_xy = y_scale ? slant * x_scale / y_scale : 0.f;
}
hb_position_t em_mult (int16_t v, int64_t mult)
diff --git a/thirdparty/harfbuzz/src/hb-graphite2.cc b/thirdparty/harfbuzz/src/hb-graphite2.cc
index 42420ac0b0..63dc18b466 100644
--- a/thirdparty/harfbuzz/src/hb-graphite2.cc
+++ b/thirdparty/harfbuzz/src/hb-graphite2.cc
@@ -439,7 +439,8 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
if (feats) gr_featureval_destroy (feats);
gr_seg_destroy (seg);
- buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
+ buffer->clear_glyph_flags ();
+ buffer->unsafe_to_break ();
return true;
}
diff --git a/thirdparty/harfbuzz/src/hb-iter.hh b/thirdparty/harfbuzz/src/hb-iter.hh
index ad2e45e3c5..43a3098f65 100644
--- a/thirdparty/harfbuzz/src/hb-iter.hh
+++ b/thirdparty/harfbuzz/src/hb-iter.hh
@@ -90,8 +90,8 @@ struct hb_iter_t
* it will be returning pointer to temporary rvalue.
* TODO Use a wrapper return type to fix for non-reference type. */
template <typename T = item_t,
- hb_enable_if (hb_is_reference (T))>
- hb_remove_reference<item_t>* operator -> () const { return hb_addressof (**thiz()); }
+ hb_enable_if (std::is_reference<T>::value)>
+ hb_remove_reference<item_t>* operator -> () const { return std::addressof (**thiz()); }
item_t operator * () const { return thiz()->__item__ (); }
item_t operator * () { return thiz()->__item__ (); }
item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); }
@@ -289,7 +289,7 @@ struct hb_is_source_of
{
private:
template <typename Iter2 = Iter,
- hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference<hb_add_const<Item>>))>
+ hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference<const Item>))>
static hb_true_type impl (hb_priority<2>);
template <typename Iter2 = Iter>
static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) >> hb_declval (Item &), hb_true_type ());
diff --git a/thirdparty/harfbuzz/src/hb-kern.hh b/thirdparty/harfbuzz/src/hb-kern.hh
index 3f952fe7fc..9ea945caed 100644
--- a/thirdparty/harfbuzz/src/hb-kern.hh
+++ b/thirdparty/harfbuzz/src/hb-kern.hh
@@ -49,6 +49,10 @@ struct hb_kern_machine_t
hb_mask_t kern_mask,
bool scale = true) const
{
+ if (!buffer->message (font, "start kern"))
+ return;
+
+ buffer->unsafe_to_concat ();
OT::hb_ot_apply_context_t c (1, font, buffer);
c.set_lookup_mask (kern_mask);
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
@@ -67,7 +71,8 @@ struct hb_kern_machine_t
}
skippy_iter.reset (idx, 1);
- if (!skippy_iter.next ())
+ unsigned unsafe_to;
+ if (!skippy_iter.next (&unsafe_to))
{
idx++;
continue;
@@ -125,6 +130,8 @@ struct hb_kern_machine_t
skip:
idx = skippy_iter.idx;
}
+
+ (void) buffer->message (font, "end kern");
}
const Driver &driver;
diff --git a/thirdparty/harfbuzz/src/hb-machinery.hh b/thirdparty/harfbuzz/src/hb-machinery.hh
index 010c2570d7..5046ac1933 100644
--- a/thirdparty/harfbuzz/src/hb-machinery.hh
+++ b/thirdparty/harfbuzz/src/hb-machinery.hh
@@ -244,19 +244,19 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
{
Stored *p = (Stored *) hb_calloc (1, sizeof (Stored));
if (likely (p))
- p->init (data);
+ p = new (p) Stored (data);
return p;
}
static Stored *create ()
{
Stored *p = (Stored *) hb_calloc (1, sizeof (Stored));
if (likely (p))
- p->init ();
+ p = new (p) Stored ();
return p;
}
static void destroy (Stored *p)
{
- p->fini ();
+ p->~Stored ();
hb_free (p);
}
diff --git a/thirdparty/harfbuzz/src/hb-map.hh b/thirdparty/harfbuzz/src/hb-map.hh
index 793dcf22ca..9341637eac 100644
--- a/thirdparty/harfbuzz/src/hb-map.hh
+++ b/thirdparty/harfbuzz/src/hb-map.hh
@@ -37,13 +37,10 @@
template <typename K, typename V,
typename k_invalid_t = K,
typename v_invalid_t = V,
- k_invalid_t kINVALID = hb_is_pointer (K) ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1,
- v_invalid_t vINVALID = hb_is_pointer (V) ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
+ k_invalid_t kINVALID = std::is_pointer<K>::value ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1,
+ v_invalid_t vINVALID = std::is_pointer<V>::value ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
struct hb_hashmap_t
{
- static constexpr K INVALID_KEY = kINVALID;
- static constexpr V INVALID_VALUE = vINVALID;
-
hb_hashmap_t () { init (); }
~hb_hashmap_t () { fini (); }
@@ -64,24 +61,40 @@ struct hb_hashmap_t
hb_copy (o, *this);
}
- static_assert (std::is_trivially_copyable<K>::value, "");
- static_assert (std::is_trivially_copyable<V>::value, "");
- static_assert (std::is_trivially_destructible<K>::value, "");
- static_assert (std::is_trivially_destructible<V>::value, "");
-
struct item_t
{
K key;
V value;
uint32_t hash;
- void clear () { key = kINVALID; value = vINVALID; hash = 0; }
+ void clear ()
+ {
+ new (std::addressof (key)) K ();
+ key = hb_coerce<K> (kINVALID);
+ new (std::addressof (value)) V ();
+ value = hb_coerce<V> (vINVALID);
+ hash = 0;
+ }
bool operator == (const K &o) { return hb_deref (key) == hb_deref (o); }
bool operator == (const item_t &o) { return *this == o.key; }
- bool is_unused () const { return key == kINVALID; }
- bool is_tombstone () const { return key != kINVALID && value == vINVALID; }
- bool is_real () const { return key != kINVALID && value != vINVALID; }
+ bool is_unused () const
+ {
+ const K inv = hb_coerce<K> (kINVALID);
+ return key == inv;
+ }
+ bool is_tombstone () const
+ {
+ const K kinv = hb_coerce<K> (kINVALID);
+ const V vinv = hb_coerce<V> (vINVALID);
+ return key != kinv && value == vinv;
+ }
+ bool is_real () const
+ {
+ const K kinv = hb_coerce<K> (kINVALID);
+ const V vinv = hb_coerce<V> (vINVALID);
+ return key != kinv && value != vinv;
+ }
hb_pair_t<K, V> get_pair() const { return hb_pair_t<K, V> (key, value); }
};
@@ -118,8 +131,13 @@ struct hb_hashmap_t
}
void fini_shallow ()
{
- hb_free (items);
- items = nullptr;
+ if (likely (items)) {
+ unsigned size = mask + 1;
+ for (unsigned i = 0; i < size; i++)
+ items[i].~item_t ();
+ hb_free (items);
+ items = nullptr;
+ }
population = occupancy = 0;
}
void fini ()
@@ -163,10 +181,15 @@ struct hb_hashmap_t
/* Insert back old items. */
if (old_items)
for (unsigned int i = 0; i < old_size; i++)
+ {
if (old_items[i].is_real ())
+ {
set_with_hash (old_items[i].key,
old_items[i].hash,
std::move (old_items[i].value));
+ }
+ old_items[i].~item_t ();
+ }
hb_free (old_items);
@@ -178,22 +201,22 @@ struct hb_hashmap_t
V get (K key) const
{
- if (unlikely (!items)) return vINVALID;
+ if (unlikely (!items)) return hb_coerce<V> (vINVALID);
unsigned int i = bucket_for (key);
- return items[i].is_real () && items[i] == key ? items[i].value : vINVALID;
+ return items[i].is_real () && items[i] == key ? items[i].value : hb_coerce<V> (vINVALID);
}
- void del (K key) { set (key, vINVALID); }
+ void del (K key) { set (key, hb_coerce<V> (vINVALID)); }
/* Has interface. */
- static constexpr V SENTINEL = vINVALID;
typedef V value_t;
value_t operator [] (K k) const { return get (k); }
bool has (K k, V *vp = nullptr) const
{
V v = (*this)[k];
if (vp) *vp = v;
- return v != SENTINEL;
+ const V vinv = hb_coerce<V> (vINVALID);
+ return v != vinv;
}
/* Projection. */
V operator () (K k) const { return get (k); }
@@ -248,11 +271,13 @@ struct hb_hashmap_t
bool set_with_hash (K key, uint32_t hash, VV&& value)
{
if (unlikely (!successful)) return false;
- if (unlikely (key == kINVALID)) return true;
+ const K kinv = hb_coerce<K> (kINVALID);
+ if (unlikely (key == kinv)) return true;
if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false;
unsigned int i = bucket_for_hash (key, hash);
- if (value == vINVALID && items[i].key != key)
+ const V vinv = hb_coerce<V> (vINVALID);
+ if (value == vinv && items[i].key != key)
return true; /* Trying to delete non-existent key. */
if (!items[i].is_unused ())
diff --git a/thirdparty/harfbuzz/src/hb-meta.hh b/thirdparty/harfbuzz/src/hb-meta.hh
index 0ea5774a9f..3fea5d995e 100644
--- a/thirdparty/harfbuzz/src/hb-meta.hh
+++ b/thirdparty/harfbuzz/src/hb-meta.hh
@@ -29,6 +29,7 @@
#include "hb.hh"
+#include <memory>
#include <type_traits>
#include <utility>
@@ -85,30 +86,13 @@ template <> struct hb_priority<0> {};
template <typename T> struct hb_type_identity_t { typedef T type; };
template <typename T> using hb_type_identity = typename hb_type_identity_t<T>::type;
-struct
-{
- template <typename T> constexpr T*
- operator () (T& arg) const
- {
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
- /* https://en.cppreference.com/w/cpp/memory/addressof */
- return reinterpret_cast<T*> (
- &const_cast<char&> (
- reinterpret_cast<const volatile char&> (arg)));
-#pragma GCC diagnostic pop
- }
-}
-HB_FUNCOBJ (hb_addressof);
-
template <typename T> static inline T hb_declval ();
#define hb_declval(T) (hb_declval<T> ())
template <typename T> struct hb_match_const : hb_type_identity_t<T>, hb_false_type {};
template <typename T> struct hb_match_const<const T> : hb_type_identity_t<T>, hb_true_type {};
template <typename T> using hb_remove_const = typename hb_match_const<T>::type;
-template <typename T> using hb_add_const = const T;
-#define hb_is_const(T) hb_match_const<T>::value
+
template <typename T> struct hb_match_reference : hb_type_identity_t<T>, hb_false_type {};
template <typename T> struct hb_match_reference<T &> : hb_type_identity_t<T>, hb_true_type {};
template <typename T> struct hb_match_reference<T &&> : hb_type_identity_t<T>, hb_true_type {};
@@ -119,14 +103,13 @@ template <typename T> using hb_add_lvalue_reference = decltype (_hb_try_add_lval
template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<1>) -> hb_type_identity<T&&>;
template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<0>) -> hb_type_identity<T>;
template <typename T> using hb_add_rvalue_reference = decltype (_hb_try_add_rvalue_reference<T> (hb_prioritize));
-#define hb_is_reference(T) hb_match_reference<T>::value
+
template <typename T> struct hb_match_pointer : hb_type_identity_t<T>, hb_false_type {};
template <typename T> struct hb_match_pointer<T *> : hb_type_identity_t<T>, hb_true_type {};
template <typename T> using hb_remove_pointer = typename hb_match_pointer<T>::type;
template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<hb_remove_reference<T>*>;
template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<T>;
template <typename T> using hb_add_pointer = decltype (_hb_try_add_pointer<T> (hb_prioritize));
-#define hb_is_pointer(T) hb_match_pointer<T>::value
/* TODO Add feature-parity to std::decay. */
@@ -137,8 +120,8 @@ template <typename T> using hb_decay = hb_remove_const<hb_remove_reference<T>>;
template <typename From, typename To>
using hb_is_cr_convertible = hb_bool_constant<
hb_is_same (hb_decay<From>, hb_decay<To>) &&
- (!hb_is_const (From) || hb_is_const (To)) &&
- (!hb_is_reference (To) || hb_is_const (To) || hb_is_reference (To))
+ (!std::is_const<From>::value || std::is_const<To>::value) &&
+ (!std::is_reference<To>::value || std::is_const<To>::value || std::is_reference<To>::value)
>;
#define hb_is_cr_convertible(From,To) hb_is_cr_convertible<From, To>::value
@@ -153,16 +136,6 @@ struct
}
HB_FUNCOBJ (hb_deref);
-struct
-{
- template <typename T> constexpr auto
- operator () (T&& v) const HB_AUTO_RETURN (std::forward<T> (v))
-
- template <typename T> constexpr auto
- operator () (T& v) const HB_AUTO_RETURN (hb_addressof (v))
-}
-HB_FUNCOBJ (hb_ref);
-
template <typename T>
struct hb_reference_wrapper
{
@@ -176,7 +149,7 @@ struct hb_reference_wrapper
template <typename T>
struct hb_reference_wrapper<T&>
{
- hb_reference_wrapper (T& v) : v (hb_addressof (v)) {}
+ hb_reference_wrapper (T& v) : v (std::addressof (v)) {}
bool operator == (const hb_reference_wrapper& o) const { return v == o.v; }
bool operator != (const hb_reference_wrapper& o) const { return v != o.v; }
operator T& () const { return *v; }
diff --git a/thirdparty/harfbuzz/src/hb-ms-feature-ranges.cc b/thirdparty/harfbuzz/src/hb-ms-feature-ranges.cc
deleted file mode 100644
index 6d09b252d8..0000000000
--- a/thirdparty/harfbuzz/src/hb-ms-feature-ranges.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright © 2011,2012,2013 Google, Inc.
- * Copyright © 2021 Khaled Hosny
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#include "hb-ms-feature-ranges.hh"
-
-bool
-hb_ms_setup_features (const hb_feature_t *features,
- unsigned int num_features,
- hb_vector_t<hb_ms_feature_t> &feature_records, /* OUT */
- hb_vector_t<hb_ms_range_record_t> &range_records /* OUT */)
-{
- feature_records.shrink(0);
- range_records.shrink(0);
-
- /* Sort features by start/end events. */
- hb_vector_t<hb_ms_feature_event_t> feature_events;
- for (unsigned int i = 0; i < num_features; i++)
- {
- hb_ms_active_feature_t feature;
- feature.fea.tag_le = hb_uint32_swap (features[i].tag);
- feature.fea.value = features[i].value;
- feature.order = i;
-
- hb_ms_feature_event_t *event;
-
- event = feature_events.push ();
- event->index = features[i].start;
- event->start = true;
- event->feature = feature;
-
- event = feature_events.push ();
- event->index = features[i].end;
- event->start = false;
- event->feature = feature;
- }
- feature_events.qsort ();
- /* Add a strategic final event. */
- {
- hb_ms_active_feature_t feature;
- feature.fea.tag_le = 0;
- feature.fea.value = 0;
- feature.order = num_features + 1;
-
- auto *event = feature_events.push ();
- event->index = 0; /* This value does magic. */
- event->start = false;
- event->feature = feature;
- }
-
- /* Scan events and save features for each range. */
- hb_vector_t<hb_ms_active_feature_t> active_features;
- unsigned int last_index = 0;
- for (unsigned int i = 0; i < feature_events.length; i++)
- {
- auto *event = &feature_events[i];
-
- if (event->index != last_index)
- {
- /* Save a snapshot of active features and the range. */
- auto *range = range_records.push ();
- auto offset = feature_records.length;
-
- active_features.qsort ();
- for (unsigned int j = 0; j < active_features.length; j++)
- {
- if (!j || active_features[j].fea.tag_le != feature_records[feature_records.length - 1].tag_le)
- {
- feature_records.push (active_features[j].fea);
- }
- else
- {
- /* Overrides value for existing feature. */
- feature_records[feature_records.length - 1].value = active_features[j].fea.value;
- }
- }
-
- /* Will convert to pointer after all is ready, since feature_records.array
- * may move as we grow it. */
- range->features.features = reinterpret_cast<hb_ms_feature_t *> (offset);
- range->features.num_features = feature_records.length - offset;
- range->index_first = last_index;
- range->index_last = event->index - 1;
-
- last_index = event->index;
- }
-
- if (event->start)
- {
- active_features.push (event->feature);
- }
- else
- {
- auto *feature = active_features.find (&event->feature);
- if (feature)
- active_features.remove (feature - active_features.arrayZ);
- }
- }
-
- if (!range_records.length) /* No active feature found. */
- num_features = 0;
-
- /* Fixup the pointers. */
- for (unsigned int i = 0; i < range_records.length; i++)
- {
- auto *range = &range_records[i];
- range->features.features = (hb_ms_feature_t *) feature_records + reinterpret_cast<uintptr_t> (range->features.features);
- }
-
- return !!num_features;
-}
-
-void
-hb_ms_make_feature_ranges (hb_vector_t<hb_ms_feature_t> &feature_records,
- hb_vector_t<hb_ms_range_record_t> &range_records,
- unsigned int chars_offset,
- unsigned int chars_len,
- uint16_t *log_clusters,
- hb_vector_t<hb_ms_features_t*> &range_features, /* OUT */
- hb_vector_t<uint32_t> &range_counts /* OUT */)
-{
- range_features.shrink (0);
- range_counts.shrink (0);
-
- auto *last_range = &range_records[0];
- for (unsigned int i = chars_offset; i < chars_len; i++)
- {
- auto *range = last_range;
- while (log_clusters[i] < range->index_first)
- range--;
- while (log_clusters[i] > range->index_last)
- range++;
- if (!range_features.length ||
- &range->features != range_features[range_features.length - 1])
- {
- auto **features = range_features.push ();
- auto *c = range_counts.push ();
- if (unlikely (!features || !c))
- {
- range_features.shrink (0);
- range_counts.shrink (0);
- break;
- }
- *features = &range->features;
- *c = 1;
- }
- else
- {
- range_counts[range_counts.length - 1]++;
- }
-
- last_range = range;
- }
-}
diff --git a/thirdparty/harfbuzz/src/hb-ms-feature-ranges.hh b/thirdparty/harfbuzz/src/hb-ms-feature-ranges.hh
index 401d1e1d97..d40fdeaa82 100644
--- a/thirdparty/harfbuzz/src/hb-ms-feature-ranges.hh
+++ b/thirdparty/harfbuzz/src/hb-ms-feature-ranges.hh
@@ -52,8 +52,8 @@ struct hb_ms_active_feature_t {
a->fea.value < b->fea.value ? -1 : a->fea.value > b->fea.value ? 1 :
0;
}
- bool operator== (const hb_ms_active_feature_t *f)
- { return cmp (this, f) == 0; }
+ bool operator== (const hb_ms_active_feature_t& f) const
+ { return cmp (this, &f) == 0; }
};
struct hb_ms_feature_event_t {
@@ -77,20 +77,153 @@ struct hb_ms_range_record_t {
unsigned int index_last; /* == end - 1 */
};
-HB_INTERNAL bool
+static inline bool
hb_ms_setup_features (const hb_feature_t *features,
unsigned int num_features,
hb_vector_t<hb_ms_feature_t> &feature_records, /* OUT */
- hb_vector_t<hb_ms_range_record_t> &range_records /* OUT */);
+ hb_vector_t<hb_ms_range_record_t> &range_records /* OUT */)
+{
+ feature_records.shrink(0);
+ range_records.shrink(0);
+ /* Sort features by start/end events. */
+ hb_vector_t<hb_ms_feature_event_t> feature_events;
+ for (unsigned int i = 0; i < num_features; i++)
+ {
+ hb_ms_active_feature_t feature;
+ feature.fea.tag_le = hb_uint32_swap (features[i].tag);
+ feature.fea.value = features[i].value;
+ feature.order = i;
+
+ hb_ms_feature_event_t *event;
+
+ event = feature_events.push ();
+ event->index = features[i].start;
+ event->start = true;
+ event->feature = feature;
+
+ event = feature_events.push ();
+ event->index = features[i].end;
+ event->start = false;
+ event->feature = feature;
+ }
+ feature_events.qsort ();
+ /* Add a strategic final event. */
+ {
+ hb_ms_active_feature_t feature;
+ feature.fea.tag_le = 0;
+ feature.fea.value = 0;
+ feature.order = num_features + 1;
+
+ auto *event = feature_events.push ();
+ event->index = 0; /* This value does magic. */
+ event->start = false;
+ event->feature = feature;
+ }
+
+ /* Scan events and save features for each range. */
+ hb_vector_t<hb_ms_active_feature_t> active_features;
+ unsigned int last_index = 0;
+ for (unsigned int i = 0; i < feature_events.length; i++)
+ {
+ auto *event = &feature_events[i];
+
+ if (event->index != last_index)
+ {
+ /* Save a snapshot of active features and the range. */
+ auto *range = range_records.push ();
+ auto offset = feature_records.length;
+
+ active_features.qsort ();
+ for (unsigned int j = 0; j < active_features.length; j++)
+ {
+ if (!j || active_features[j].fea.tag_le != feature_records[feature_records.length - 1].tag_le)
+ {
+ feature_records.push (active_features[j].fea);
+ }
+ else
+ {
+ /* Overrides value for existing feature. */
+ feature_records[feature_records.length - 1].value = active_features[j].fea.value;
+ }
+ }
+
+ /* Will convert to pointer after all is ready, since feature_records.array
+ * may move as we grow it. */
+ range->features.features = reinterpret_cast<hb_ms_feature_t *> (offset);
+ range->features.num_features = feature_records.length - offset;
+ range->index_first = last_index;
+ range->index_last = event->index - 1;
-HB_INTERNAL void
+ last_index = event->index;
+ }
+
+ if (event->start)
+ {
+ active_features.push (event->feature);
+ }
+ else
+ {
+ auto *feature = active_features.lsearch (event->feature);
+ if (feature)
+ active_features.remove (feature - active_features.arrayZ);
+ }
+ }
+
+ if (!range_records.length) /* No active feature found. */
+ num_features = 0;
+
+ /* Fixup the pointers. */
+ for (unsigned int i = 0; i < range_records.length; i++)
+ {
+ auto *range = &range_records[i];
+ range->features.features = (hb_ms_feature_t *) feature_records + reinterpret_cast<uintptr_t> (range->features.features);
+ }
+
+ return !!num_features;
+}
+
+static inline void
hb_ms_make_feature_ranges (hb_vector_t<hb_ms_feature_t> &feature_records,
hb_vector_t<hb_ms_range_record_t> &range_records,
unsigned int chars_offset,
unsigned int chars_len,
uint16_t *log_clusters,
hb_vector_t<hb_ms_features_t*> &range_features, /* OUT */
- hb_vector_t<uint32_t> &range_counts /* OUT */);
+ hb_vector_t<uint32_t> &range_counts /* OUT */)
+{
+ range_features.shrink (0);
+ range_counts.shrink (0);
+
+ auto *last_range = &range_records[0];
+ for (unsigned int i = chars_offset; i < chars_len; i++)
+ {
+ auto *range = last_range;
+ while (log_clusters[i] < range->index_first)
+ range--;
+ while (log_clusters[i] > range->index_last)
+ range++;
+ if (!range_features.length ||
+ &range->features != range_features[range_features.length - 1])
+ {
+ auto **features = range_features.push ();
+ auto *c = range_counts.push ();
+ if (unlikely (!features || !c))
+ {
+ range_features.shrink (0);
+ range_counts.shrink (0);
+ break;
+ }
+ *features = &range->features;
+ *c = 1;
+ }
+ else
+ {
+ range_counts[range_counts.length - 1]++;
+ }
+
+ last_range = range;
+ }
+}
#endif /* HB_MS_FEATURE_RANGES_HH */
diff --git a/thirdparty/harfbuzz/src/hb-object.hh b/thirdparty/harfbuzz/src/hb-object.hh
index 0e15cb12c4..4b5bc32ade 100644
--- a/thirdparty/harfbuzz/src/hb-object.hh
+++ b/thirdparty/harfbuzz/src/hb-object.hh
@@ -53,7 +53,7 @@ struct hb_lockable_set_t
item_t *replace_or_insert (T v, lock_t &l, bool replace)
{
l.lock ();
- item_t *item = items.find (v);
+ item_t *item = items.lsearch (v);
if (item) {
if (replace) {
item_t old = *item;
@@ -76,7 +76,7 @@ struct hb_lockable_set_t
void remove (T v, lock_t &l)
{
l.lock ();
- item_t *item = items.find (v);
+ item_t *item = items.lsearch (v);
if (item)
{
item_t old = *item;
@@ -93,7 +93,7 @@ struct hb_lockable_set_t
bool find (T v, item_t *i, lock_t &l)
{
l.lock ();
- item_t *item = items.find (v);
+ item_t *item = items.lsearch (v);
if (item)
*i = *item;
l.unlock ();
diff --git a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh
index 180c87cb89..c102c15173 100644
--- a/thirdparty/harfbuzz/src/hb-ot-cff-common.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-cff-common.hh
@@ -68,8 +68,6 @@ struct code_pair_t
typedef hb_vector_t<unsigned char> str_buff_t;
struct str_buff_vec_t : hb_vector_t<str_buff_t>
{
- void fini () { SUPER::fini_deep (); }
-
unsigned int total_size () const
{
unsigned int size = 0;
diff --git a/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh b/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh
index 5dd183e3a0..6fb59315c9 100644
--- a/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-cff1-table.hh
@@ -1144,8 +1144,8 @@ struct cff1
{
sc.end_processing ();
topDict.fini ();
- fontDicts.fini_deep ();
- privateDicts.fini_deep ();
+ fontDicts.fini ();
+ privateDicts.fini ();
hb_blob_destroy (blob);
blob = nullptr;
}
@@ -1245,32 +1245,32 @@ struct cff1
}
protected:
- hb_blob_t *blob;
+ hb_blob_t *blob = nullptr;
hb_sanitize_context_t sc;
public:
- const Encoding *encoding;
- const Charset *charset;
- const CFF1NameIndex *nameIndex;
- const CFF1TopDictIndex *topDictIndex;
- const CFF1StringIndex *stringIndex;
- const CFF1Subrs *globalSubrs;
- const CFF1CharStrings *charStrings;
- const CFF1FDArray *fdArray;
- const CFF1FDSelect *fdSelect;
- unsigned int fdCount;
+ const Encoding *encoding = nullptr;
+ const Charset *charset = nullptr;
+ const CFF1NameIndex *nameIndex = nullptr;
+ const CFF1TopDictIndex *topDictIndex = nullptr;
+ const CFF1StringIndex *stringIndex = nullptr;
+ const CFF1Subrs *globalSubrs = nullptr;
+ const CFF1CharStrings *charStrings = nullptr;
+ const CFF1FDArray *fdArray = nullptr;
+ const CFF1FDSelect *fdSelect = nullptr;
+ unsigned int fdCount = 0;
cff1_top_dict_values_t topDict;
hb_vector_t<cff1_font_dict_values_t>
fontDicts;
hb_vector_t<PRIVDICTVAL> privateDicts;
- unsigned int num_glyphs;
+ unsigned int num_glyphs = 0;
};
struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t>
{
- void init (hb_face_t *face)
+ accelerator_t (hb_face_t *face)
{
SUPER::init (face);
@@ -1295,8 +1295,7 @@ struct cff1
}
glyph_names.qsort ();
}
-
- void fini ()
+ ~accelerator_t ()
{
glyph_names.fini ();
@@ -1398,7 +1397,10 @@ struct cff1
DEFINE_SIZE_STATIC (4);
};
-struct cff1_accelerator_t : cff1::accelerator_t {};
+struct cff1_accelerator_t : cff1::accelerator_t {
+ cff1_accelerator_t (hb_face_t *face) : cff1::accelerator_t (face) {}
+};
+
} /* namespace OT */
#endif /* HB_OT_CFF1_TABLE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh b/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh
index 829217feaa..6e1b01c8fe 100644
--- a/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-cff2-table.hh
@@ -397,7 +397,7 @@ struct cff2
template <typename PRIVOPSET, typename PRIVDICTVAL>
struct accelerator_templ_t
{
- void init (hb_face_t *face)
+ accelerator_templ_t (hb_face_t *face)
{
topDict.init ();
fontDicts.init ();
@@ -412,15 +412,15 @@ struct cff2
const OT::cff2 *cff2 = this->blob->template as<OT::cff2> ();
if (cff2 == &Null (OT::cff2))
- { fini (); return; }
+ goto fail;
{ /* parse top dict */
byte_str_t topDictStr (cff2 + cff2->topDict, cff2->topDictSize);
- if (unlikely (!topDictStr.sanitize (&sc))) { fini (); return; }
+ if (unlikely (!topDictStr.sanitize (&sc))) goto fail;
cff2_top_dict_interpreter_t top_interp;
top_interp.env.init (topDictStr);
topDict.init ();
- if (unlikely (!top_interp.interpret (topDict))) { fini (); return; }
+ if (unlikely (!top_interp.interpret (topDict))) goto fail;
}
globalSubrs = &StructAtOffset<CFF2Subrs> (cff2, cff2->topDict + cff2->topDictSize);
@@ -434,49 +434,55 @@ struct cff2
(globalSubrs == &Null (CFF2Subrs)) || unlikely (!globalSubrs->sanitize (&sc)) ||
(fdArray == &Null (CFF2FDArray)) || unlikely (!fdArray->sanitize (&sc)) ||
(((fdSelect != &Null (CFF2FDSelect)) && unlikely (!fdSelect->sanitize (&sc, fdArray->count)))))
- { fini (); return; }
+ goto fail;
num_glyphs = charStrings->count;
if (num_glyphs != sc.get_num_glyphs ())
- { fini (); return; }
+ goto fail;
fdCount = fdArray->count;
if (!privateDicts.resize (fdCount))
- { fini (); return; }
+ goto fail;
/* parse font dicts and gather private dicts */
for (unsigned int i = 0; i < fdCount; i++)
{
const byte_str_t fontDictStr = (*fdArray)[i];
- if (unlikely (!fontDictStr.sanitize (&sc))) { fini (); return; }
+ if (unlikely (!fontDictStr.sanitize (&sc))) goto fail;
cff2_font_dict_values_t *font;
cff2_font_dict_interpreter_t font_interp;
font_interp.env.init (fontDictStr);
font = fontDicts.push ();
- if (unlikely (font == &Crap (cff2_font_dict_values_t))) { fini (); return; }
+ if (unlikely (font == &Crap (cff2_font_dict_values_t))) goto fail;
font->init ();
- if (unlikely (!font_interp.interpret (*font))) { fini (); return; }
+ if (unlikely (!font_interp.interpret (*font))) goto fail;
const byte_str_t privDictStr (StructAtOffsetOrNull<UnsizedByteStr> (cff2, font->privateDictInfo.offset), font->privateDictInfo.size);
- if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
+ if (unlikely (!privDictStr.sanitize (&sc))) goto fail;
dict_interpreter_t<PRIVOPSET, PRIVDICTVAL, cff2_priv_dict_interp_env_t> priv_interp;
priv_interp.env.init(privDictStr);
privateDicts[i].init ();
- if (unlikely (!priv_interp.interpret (privateDicts[i]))) { fini (); return; }
+ if (unlikely (!priv_interp.interpret (privateDicts[i]))) goto fail;
privateDicts[i].localSubrs = &StructAtOffsetOrNull<CFF2Subrs> (&privDictStr[0], privateDicts[i].subrsOffset);
if (privateDicts[i].localSubrs != &Null (CFF2Subrs) &&
unlikely (!privateDicts[i].localSubrs->sanitize (&sc)))
- { fini (); return; }
+ goto fail;
}
- }
- void fini ()
+
+ return;
+
+ fail:
+ _fini ();
+ }
+ ~accelerator_templ_t () { _fini (); }
+ void _fini ()
{
sc.end_processing ();
topDict.fini ();
- fontDicts.fini_deep ();
- privateDicts.fini_deep ();
+ fontDicts.fini ();
+ privateDicts.fini ();
hb_blob_destroy (blob);
blob = nullptr;
}
@@ -484,26 +490,28 @@ struct cff2
bool is_valid () const { return blob; }
protected:
- hb_blob_t *blob;
+ hb_blob_t *blob = nullptr;
hb_sanitize_context_t sc;
public:
cff2_top_dict_values_t topDict;
- const CFF2Subrs *globalSubrs;
- const CFF2VariationStore *varStore;
- const CFF2CharStrings *charStrings;
- const CFF2FDArray *fdArray;
- const CFF2FDSelect *fdSelect;
- unsigned int fdCount;
+ const CFF2Subrs *globalSubrs = nullptr;
+ const CFF2VariationStore *varStore = nullptr;
+ const CFF2CharStrings *charStrings = nullptr;
+ const CFF2FDArray *fdArray = nullptr;
+ const CFF2FDSelect *fdSelect = nullptr;
+ unsigned int fdCount = 0;
hb_vector_t<cff2_font_dict_values_t> fontDicts;
hb_vector_t<PRIVDICTVAL> privateDicts;
- unsigned int num_glyphs;
+ unsigned int num_glyphs = 0;
};
struct accelerator_t : accelerator_templ_t<cff2_private_dict_opset_t, cff2_private_dict_values_t>
{
+ accelerator_t (hb_face_t *face) : accelerator_templ_t (face) {}
+
HB_INTERNAL bool get_extents (hb_font_t *font,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents) const;
@@ -525,7 +533,10 @@ struct cff2
DEFINE_SIZE_STATIC (5);
};
-struct cff2_accelerator_t : cff2::accelerator_t {};
+struct cff2_accelerator_t : cff2::accelerator_t {
+ cff2_accelerator_t (hb_face_t *face) : cff2::accelerator_t (face) {}
+};
+
} /* namespace OT */
#endif /* HB_OT_CFF2_TABLE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh
index d837adc788..fde57cdc5b 100644
--- a/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-cmap-table.hh
@@ -369,7 +369,6 @@ struct CmapSubtableFormat4
{
accelerator_t () {}
accelerator_t (const CmapSubtableFormat4 *subtable) { init (subtable); }
- ~accelerator_t () { fini (); }
void init (const CmapSubtableFormat4 *subtable)
{
@@ -381,7 +380,6 @@ struct CmapSubtableFormat4
glyphIdArray = idRangeOffset + segCount;
glyphIdArrayLength = (subtable->length - 16 - 8 * segCount) / 2;
}
- void fini () {}
bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
{
@@ -1607,7 +1605,7 @@ struct cmap
unsigned format = (this + _.subtable).u.format;
if (format == 12) has_format12 = true;
- const EncodingRecord *table = hb_addressof (_);
+ const EncodingRecord *table = std::addressof (_);
if (_.platformID == 0 && _.encodingID == 3) unicode_bmp = table;
else if (_.platformID == 0 && _.encodingID == 4) unicode_ucs4 = table;
else if (_.platformID == 3 && _.encodingID == 1) ms_bmp = table;
@@ -1665,7 +1663,7 @@ struct cmap
struct accelerator_t
{
- void init (hb_face_t *face)
+ accelerator_t (hb_face_t *face)
{
this->table = hb_sanitize_context_t ().reference_table<cmap> (face);
bool symbol;
@@ -1700,8 +1698,7 @@ struct cmap
}
}
}
-
- void fini () { this->table.destroy (); }
+ ~accelerator_t () { this->table.destroy (); }
bool get_nominal_glyph (hb_codepoint_t unicode,
hb_codepoint_t *glyph) const
@@ -1863,7 +1860,9 @@ struct cmap
DEFINE_SIZE_ARRAY (4, encodingRecord);
};
-struct cmap_accelerator_t : cmap::accelerator_t {};
+struct cmap_accelerator_t : cmap::accelerator_t {
+ cmap_accelerator_t (hb_face_t *face) : cmap::accelerator_t (face) {}
+};
} /* namespace OT */
diff --git a/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh
index 14459914ee..23fa56c4f6 100644
--- a/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-color-cbdt-table.hh
@@ -360,6 +360,16 @@ struct IndexSubtable
struct IndexSubtableRecord
{
+ /* XXX Remove this and fix by not inserting it into vector. */
+ IndexSubtableRecord& operator = (const IndexSubtableRecord &o)
+ {
+ firstGlyphIndex = o.firstGlyphIndex;
+ lastGlyphIndex = o.lastGlyphIndex;
+ offsetToSubtable = (unsigned) o.offsetToSubtable;
+ assert (offsetToSubtable.is_null ());
+ return *this;
+ }
+
bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
@@ -809,15 +819,14 @@ struct CBDT
struct accelerator_t
{
- void init (hb_face_t *face)
+ accelerator_t (hb_face_t *face)
{
- cblc = hb_sanitize_context_t ().reference_table<CBLC> (face);
- cbdt = hb_sanitize_context_t ().reference_table<CBDT> (face);
+ this->cblc = hb_sanitize_context_t ().reference_table<CBLC> (face);
+ this->cbdt = hb_sanitize_context_t ().reference_table<CBDT> (face);
upem = hb_face_get_upem (face);
}
-
- void fini ()
+ ~accelerator_t ()
{
this->cblc.destroy ();
this->cbdt.destroy ();
@@ -978,7 +987,10 @@ CBLC::subset (hb_subset_context_t *c) const
return_trace (CBLC::sink_cbdt (c, &cbdt_prime));
}
-struct CBDT_accelerator_t : CBDT::accelerator_t {};
+struct CBDT_accelerator_t : CBDT::accelerator_t {
+ CBDT_accelerator_t (hb_face_t *face) : CBDT::accelerator_t (face) {}
+};
+
} /* namespace OT */
diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh
index 008422d089..dac755c02c 100644
--- a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh
@@ -71,7 +71,7 @@ struct hb_colrv1_closure_context_t :
bool paint_visited (const void *paint)
{
hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) paint - (uintptr_t) base);
- if (visited_paint.has (delta))
+ if (visited_paint.in_error() || visited_paint.has (delta))
return true;
visited_paint.add (delta);
@@ -1270,13 +1270,9 @@ struct COLR
struct accelerator_t
{
- accelerator_t () {}
- ~accelerator_t () { fini (); }
-
- void init (hb_face_t *face)
+ accelerator_t (hb_face_t *face)
{ colr = hb_sanitize_context_t ().reference_table<COLR> (face); }
-
- void fini () { this->colr.destroy (); }
+ ~accelerator_t () { this->colr.destroy (); }
bool is_valid () { return colr.get_blob ()->length; }
@@ -1535,6 +1531,10 @@ struct COLR
DEFINE_SIZE_MIN (14);
};
+struct COLR_accelerator_t : COLR::accelerator_t {
+ COLR_accelerator_t (hb_face_t *face) : COLR::accelerator_t (face) {}
+};
+
} /* namespace OT */
diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colrv1-closure.hh b/thirdparty/harfbuzz/src/hb-ot-color-colrv1-closure.hh
index ca85ba6ad6..fbaf2ec26b 100644
--- a/thirdparty/harfbuzz/src/hb-ot-color-colrv1-closure.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-color-colrv1-closure.hh
@@ -43,7 +43,7 @@ HB_INTERNAL void PaintColrLayers::closurev1 (hb_colrv1_closure_context_t* c) con
const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
{
- const Paint &paint = hb_addressof (paint_offset_lists) + paint_offset_lists[i];
+ const Paint &paint = std::addressof (paint_offset_lists) + paint_offset_lists[i];
paint.dispatch (c);
}
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-color-sbix-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-sbix-table.hh
index d2911f19e6..9741ebd450 100644
--- a/thirdparty/harfbuzz/src/hb-ot-color-sbix-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-color-sbix-table.hh
@@ -202,12 +202,12 @@ struct sbix
struct accelerator_t
{
- void init (hb_face_t *face)
+ accelerator_t (hb_face_t *face)
{
table = hb_sanitize_context_t ().reference_table<sbix> (face);
num_glyphs = face->get_num_glyphs ();
}
- void fini () { table.destroy (); }
+ ~accelerator_t () { table.destroy (); }
bool has_data () const { return table->has_data (); }
@@ -407,7 +407,10 @@ struct sbix
DEFINE_SIZE_ARRAY (8, strikes);
};
-struct sbix_accelerator_t : sbix::accelerator_t {};
+struct sbix_accelerator_t : sbix::accelerator_t {
+ sbix_accelerator_t (hb_face_t *face) : sbix::accelerator_t (face) {}
+};
+
} /* namespace OT */
diff --git a/thirdparty/harfbuzz/src/hb-ot-color-svg-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-svg-table.hh
index e022ef43b7..fc649f1006 100644
--- a/thirdparty/harfbuzz/src/hb-ot-color-svg-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-color-svg-table.hh
@@ -79,9 +79,9 @@ struct SVG
struct accelerator_t
{
- void init (hb_face_t *face)
+ accelerator_t (hb_face_t *face)
{ table = hb_sanitize_context_t ().reference_table<SVG> (face); }
- void fini () { table.destroy (); }
+ ~accelerator_t () { table.destroy (); }
hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const
{
@@ -116,7 +116,9 @@ struct SVG
DEFINE_SIZE_STATIC (10);
};
-struct SVG_accelerator_t : SVG::accelerator_t {};
+struct SVG_accelerator_t : SVG::accelerator_t {
+ SVG_accelerator_t (hb_face_t *face) : SVG::accelerator_t (face) {}
+};
} /* namespace OT */
diff --git a/thirdparty/harfbuzz/src/hb-ot-color.cc b/thirdparty/harfbuzz/src/hb-ot-color.cc
index 4170b71317..16077765bd 100644
--- a/thirdparty/harfbuzz/src/hb-ot-color.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-color.cc
@@ -90,15 +90,15 @@ hb_ot_color_palette_get_count (hb_face_t *face)
/**
* hb_ot_color_palette_get_name_id:
* @face: #hb_face_t to work upon
- * @palette_index: The index of the color palette
+ * @palette_index: The index of the color palette
*
* Fetches the `name` table Name ID that provides display names for
- * a `CPAL` color palette.
+ * a `CPAL` color palette.
*
* Palette display names can be generic (e.g., "Default") or provide
* specific, themed names (e.g., "Spring", "Summer", "Fall", and "Winter").
*
- * Return value: the Named ID found for the palette.
+ * Return value: the Named ID found for the palette.
* If the requested palette has no name the result is #HB_OT_NAME_ID_INVALID.
*
* Since: 2.1.0
@@ -116,7 +116,7 @@ hb_ot_color_palette_get_name_id (hb_face_t *face,
* @color_index: The index of the color
*
* Fetches the `name` table Name ID that provides display names for
- * the specificed color in a face's `CPAL` color palette.
+ * the specified color in a face's `CPAL` color palette.
*
* Display names can be generic (e.g., "Background") or specific
* (e.g., "Eye color").
@@ -256,6 +256,8 @@ hb_ot_color_has_svg (hb_face_t *face)
*
* Fetches the SVG document for a glyph. The blob may be either plain text or gzip-encoded.
*
+ * If the glyph has no SVG document, the singleton empty blob is returned.
+ *
* Return value: (transfer full): An #hb_blob_t containing the SVG document of the glyph, if available
*
* Since: 2.1.0
@@ -296,6 +298,8 @@ hb_ot_color_has_png (hb_face_t *face)
* as input. To get an optimally sized PNG blob, the UPEM value must be set on the @font
* object. If UPEM is unset, the blob returned will be the largest PNG available.
*
+ * If the glyph has no PNG image, the singleton empty blob is returned.
+ *
* Return value: (transfer full): An #hb_blob_t containing the PNG image for the glyph, if available
*
* Since: 2.1.0
diff --git a/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh b/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh
index 6aa34295c7..9bac30fff3 100644
--- a/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-glyf-table.hh
@@ -207,8 +207,7 @@ struct glyf
_populate_subset_glyphs (const hb_subset_plan_t *plan,
hb_vector_t<SubsetGlyph> *glyphs /* OUT */) const
{
- OT::glyf::accelerator_t glyf;
- glyf.init (plan->source);
+ OT::glyf::accelerator_t glyf (plan->source);
+ hb_range (plan->num_output_glyphs ())
| hb_map ([&] (hb_codepoint_t new_gid)
@@ -233,8 +232,6 @@ struct glyf
})
| hb_sink (glyphs)
;
-
- glyf.fini ();
}
static bool
@@ -595,7 +592,7 @@ struct glyf
if (unlikely (!header.numberOfContours)) return;
unsigned flags_offset = length (instructions_length ());
- if (unlikely (length (flags_offset + 1) > bytes.length)) return;
+ if (unlikely (flags_offset + 1 > bytes.length)) return;
HBUINT8 &first_flag = (HBUINT8 &) StructAtOffset<HBUINT16> (&bytes, flags_offset);
first_flag = (uint8_t) first_flag | FLAG_OVERLAP_SIMPLE;
@@ -920,7 +917,7 @@ struct glyf
struct accelerator_t
{
- void init (hb_face_t *face_)
+ accelerator_t (hb_face_t *face_)
{
short_offset = false;
num_glyphs = 0;
@@ -953,8 +950,7 @@ struct glyf
num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
num_glyphs = hb_min (num_glyphs, face->get_num_glyphs ());
}
-
- void fini ()
+ ~accelerator_t ()
{
loca_table.destroy ();
glyf_table.destroy ();
@@ -1358,7 +1354,10 @@ struct glyf
* defining it _MIN instead. */
};
-struct glyf_accelerator_t : glyf::accelerator_t {};
+struct glyf_accelerator_t : glyf::accelerator_t {
+ glyf_accelerator_t (hb_face_t *face) : glyf::accelerator_t (face) {}
+};
+
} /* namespace OT */
diff --git a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh
index 7d2d2d3eb8..36bffa70a5 100644
--- a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh
@@ -127,8 +127,7 @@ struct hmtxvmtx
T *table_prime = c->serializer->start_embed <T> ();
if (unlikely (!table_prime)) return_trace (false);
- accelerator_t _mtx;
- _mtx.init (c->plan->source);
+ accelerator_t _mtx (c->plan->source);
unsigned num_advances = _mtx.num_advances_for_subset (c->plan);
auto it =
@@ -144,8 +143,6 @@ struct hmtxvmtx
table_prime->serialize (c->serializer, it, num_advances);
- _mtx.fini ();
-
if (unlikely (c->serializer->in_error ()))
return_trace (false);
@@ -160,8 +157,8 @@ struct hmtxvmtx
{
friend struct hmtxvmtx;
- void init (hb_face_t *face,
- unsigned int default_advance_ = 0)
+ accelerator_t (hb_face_t *face,
+ unsigned int default_advance_ = 0)
{
default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face);
@@ -193,8 +190,7 @@ struct hmtxvmtx
var_table = hb_sanitize_context_t ().reference_table<HVARVVAR> (face, T::variationsTag);
}
-
- void fini ()
+ ~accelerator_t ()
{
table.destroy ();
var_table.destroy ();
@@ -338,8 +334,12 @@ struct vmtx : hmtxvmtx<vmtx, vhea> {
static constexpr bool is_horizontal = false;
};
-struct hmtx_accelerator_t : hmtx::accelerator_t {};
-struct vmtx_accelerator_t : vmtx::accelerator_t {};
+struct hmtx_accelerator_t : hmtx::accelerator_t {
+ hmtx_accelerator_t (hb_face_t *face) : hmtx::accelerator_t (face) {}
+};
+struct vmtx_accelerator_t : vmtx::accelerator_t {
+ vmtx_accelerator_t (hb_face_t *face) : vmtx::accelerator_t (face) {}
+};
} /* namespace OT */
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
index 4fb1893435..60a1906155 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
@@ -128,7 +128,7 @@ struct hb_prune_langsys_context_t
bool visited (const T *p, hb_set_t &visited_set)
{
hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) p - (uintptr_t) table);
- if (visited_set.has (delta))
+ if (visited_set.in_error () || visited_set.has (delta))
return true;
visited_set.add (delta);
@@ -655,7 +655,6 @@ struct LangSys
void collect_features (hb_prune_langsys_context_t *c) const
{
if (!has_required_feature () && !get_feature_count ()) return;
- if (c->visitedLangsys (this)) return;
if (has_required_feature () &&
c->duplicate_feature_map->has (reqFeatureIndex))
c->new_feature_indexes->add (get_required_feature_index ());
@@ -750,11 +749,15 @@ struct Script
{
//only collect features from non-redundant langsys
const LangSys& d = get_default_lang_sys ();
- d.collect_features (c);
+ if (!c->visitedLangsys (&d)) {
+ d.collect_features (c);
+ }
for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
{
+
const LangSys& l = this+_.first.offset;
+ if (c->visitedLangsys (&l)) continue;
if (l.compare (d, c->duplicate_feature_map)) continue;
l.collect_features (c);
@@ -766,6 +769,7 @@ struct Script
for (auto _ : + hb_zip (langSys, hb_range (langsys_count)))
{
const LangSys& l = this+_.first.offset;
+ if (c->visitedLangsys (&l)) continue;
l.collect_features (c);
c->script_langsys_map->get (script_index)->add (_.second);
}
@@ -845,7 +849,7 @@ struct FeatureParamsSize
if (unlikely (!c->check_struct (this))) return_trace (false);
/* This subtable has some "history", if you will. Some earlier versions of
- * Adobe tools calculated the offset of the FeatureParams sutable from the
+ * Adobe tools calculated the offset of the FeatureParams subtable from the
* beginning of the FeatureList table! Now, that is dealt with in the
* Feature implementation. But we still need to be able to tell junk from
* real data. Note: We don't check that the nameID actually exists.
@@ -2926,8 +2930,6 @@ struct VariationStore
hb_vector_t<hb_inc_bimap_t> inner_maps;
inner_maps.resize ((unsigned) dataSets.len);
- for (unsigned i = 0; i < inner_maps.length; i++)
- inner_maps[i].init ();
for (unsigned idx : c->plan->layout_variation_indices->iter ())
{
@@ -2935,18 +2937,11 @@ struct VariationStore
uint16_t minor = idx & 0xFFFF;
if (major >= inner_maps.length)
- {
- for (unsigned i = 0; i < inner_maps.length; i++)
- inner_maps[i].fini ();
return_trace (false);
- }
inner_maps[major].add (minor);
}
varstore_prime->serialize (c->serializer, this, inner_maps.as_array ());
- for (unsigned i = 0; i < inner_maps.length; i++)
- inner_maps[i].fini ();
-
return_trace (
!c->serializer->in_error()
&& varstore_prime->dataSets);
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh
index aea644f3e1..a76d644c4b 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh
@@ -585,17 +585,16 @@ struct GDEF
struct accelerator_t
{
- void init (hb_face_t *face)
+ accelerator_t (hb_face_t *face)
{
- this->table = hb_sanitize_context_t ().reference_table<GDEF> (face);
- if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face)))
+ table = hb_sanitize_context_t ().reference_table<GDEF> (face);
+ if (unlikely (table->is_blocklisted (table.get_blob (), face)))
{
- hb_blob_destroy (this->table.get_blob ());
- this->table = hb_blob_get_empty ();
+ hb_blob_destroy (table.get_blob ());
+ table = hb_blob_get_empty ();
}
}
-
- void fini () { this->table.destroy (); }
+ ~accelerator_t () { table.destroy (); }
hb_blob_ptr_t<GDEF> table;
};
@@ -715,7 +714,9 @@ struct GDEF
DEFINE_SIZE_MIN (12);
};
-struct GDEF_accelerator_t : GDEF::accelerator_t {};
+struct GDEF_accelerator_t : GDEF::accelerator_t {
+ GDEF_accelerator_t (hb_face_t *face) : GDEF::accelerator_t (face) {}
+};
} /* namespace OT */
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh
index 6db3e08940..e28c951f3f 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh
@@ -706,7 +706,7 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Coverage or
float mark_x, mark_y, base_x, base_y;
- buffer->unsafe_to_break (glyph_pos, buffer->idx);
+ buffer->unsafe_to_break (glyph_pos, buffer->idx + 1);
mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y);
glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
@@ -1235,6 +1235,7 @@ struct PairSet
buffer->idx = pos;
return_trace (true);
}
+ buffer->unsafe_to_concat (buffer->idx, pos + 1);
return_trace (false);
}
@@ -1362,7 +1363,12 @@ struct PairPosFormat1
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset (buffer->idx, 1);
- if (!skippy_iter.next ()) return_trace (false);
+ unsigned unsafe_to;
+ if (!skippy_iter.next (&unsafe_to))
+ {
+ buffer->unsafe_to_concat (buffer->idx, unsafe_to);
+ return_trace (false);
+ }
return_trace ((this+pairSet[index]).apply (c, valueFormat, skippy_iter.idx));
}
@@ -1555,7 +1561,12 @@ struct PairPosFormat2
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset (buffer->idx, 1);
- if (!skippy_iter.next ()) return_trace (false);
+ unsigned unsafe_to;
+ if (!skippy_iter.next (&unsafe_to))
+ {
+ buffer->unsafe_to_concat (buffer->idx, unsafe_to);
+ return_trace (false);
+ }
unsigned int len1 = valueFormat1.get_len ();
unsigned int len2 = valueFormat2.get_len ();
@@ -1563,13 +1574,81 @@ struct PairPosFormat2
unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
- if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false);
+ if (unlikely (klass1 >= class1Count || klass2 >= class2Count))
+ {
+ buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
+ return_trace (false);
+ }
const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
- bool applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
- bool applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
+
+ bool applied_first = false, applied_second = false;
+
+
+ /* Isolate simple kerning and apply it half to each side.
+ * Results in better cursor positinoing / underline drawing. */
+ {
+ if (!len2)
+ {
+ const hb_direction_t dir = buffer->props.direction;
+ const bool horizontal = HB_DIRECTION_IS_HORIZONTAL (dir);
+ const bool backward = HB_DIRECTION_IS_BACKWARD (dir);
+ unsigned mask = horizontal ? ValueFormat::xAdvance : ValueFormat::yAdvance;
+ if (backward)
+ mask |= mask >> 2; /* Add eg. xPlacement in RTL. */
+ /* Add Devices. */
+ mask |= mask << 4;
+
+ if (valueFormat1 & ~mask)
+ goto bail;
+
+ /* Is simple kern. Apply value on an empty position slot,
+ * then split it between sides. */
+
+ hb_glyph_position_t pos{};
+ if (valueFormat1.apply_value (c, this, v, pos))
+ {
+ hb_position_t *src = &pos.x_advance;
+ hb_position_t *dst1 = &buffer->cur_pos().x_advance;
+ hb_position_t *dst2 = &buffer->pos[skippy_iter.idx].x_advance;
+ unsigned i = horizontal ? 0 : 1;
+
+ hb_position_t kern = src[i];
+ hb_position_t kern1 = kern >> 1;
+ hb_position_t kern2 = kern - kern1;
+
+ if (!backward)
+ {
+ dst1[i] += kern1;
+ dst2[i] += kern2;
+ dst2[i + 2] += kern2;
+ }
+ else
+ {
+ dst1[i] += kern1;
+ dst1[i + 2] += src[i + 2] - kern2;
+ dst2[i] += kern2;
+ }
+
+ applied_first = applied_second = kern != 0;
+ goto success;
+ }
+ goto boring;
+ }
+ }
+ bail:
+
+
+ applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
+ applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
+
+ success:
if (applied_first || applied_second)
buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
+ else
+ boring:
+ buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
+
buffer->idx = skippy_iter.idx;
if (len2)
@@ -1799,10 +1878,19 @@ struct CursivePosFormat1
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset (buffer->idx, 1);
- if (!skippy_iter.prev ()) return_trace (false);
+ unsigned unsafe_from;
+ if (!skippy_iter.prev (&unsafe_from))
+ {
+ buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
+ return_trace (false);
+ }
const EntryExitRecord &prev_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)];
- if (!prev_record.exitAnchor) return_trace (false);
+ if (!prev_record.exitAnchor)
+ {
+ buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+ return_trace (false);
+ }
unsigned int i = skippy_iter.idx;
unsigned int j = buffer->idx;
@@ -2066,7 +2154,13 @@ struct MarkBasePosFormat1
skippy_iter.reset (buffer->idx, 1);
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
do {
- if (!skippy_iter.prev ()) return_trace (false);
+ unsigned unsafe_from;
+ if (!skippy_iter.prev (&unsafe_from))
+ {
+ buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
+ return_trace (false);
+ }
+
/* We only want to attach to the first of a MultipleSubst sequence.
* https://github.com/harfbuzz/harfbuzz/issues/740
* Reject others...
@@ -2089,7 +2183,11 @@ struct MarkBasePosFormat1
//if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { return_trace (false); }
unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[skippy_iter.idx].codepoint);
- if (base_index == NOT_COVERED) return_trace (false);
+ if (base_index == NOT_COVERED)
+ {
+ buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+ return_trace (false);
+ }
return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx));
}
@@ -2320,21 +2418,34 @@ struct MarkLigPosFormat1
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset (buffer->idx, 1);
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
- if (!skippy_iter.prev ()) return_trace (false);
+ unsigned unsafe_from;
+ if (!skippy_iter.prev (&unsafe_from))
+ {
+ buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
+ return_trace (false);
+ }
/* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
//if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { return_trace (false); }
unsigned int j = skippy_iter.idx;
unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint);
- if (lig_index == NOT_COVERED) return_trace (false);
+ if (lig_index == NOT_COVERED)
+ {
+ buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+ return_trace (false);
+ }
const LigatureArray& lig_array = this+ligatureArray;
const LigatureAttach& lig_attach = lig_array[lig_index];
/* Find component to attach to */
unsigned int comp_count = lig_attach.rows;
- if (unlikely (!comp_count)) return_trace (false);
+ if (unlikely (!comp_count))
+ {
+ buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+ return_trace (false);
+ }
/* We must now check whether the ligature ID of the current mark glyph
* is identical to the ligature ID of the found ligature. If yes, we
@@ -2517,9 +2628,18 @@ struct MarkMarkPosFormat1
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset (buffer->idx, 1);
skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
- if (!skippy_iter.prev ()) return_trace (false);
+ unsigned unsafe_from;
+ if (!skippy_iter.prev (&unsafe_from))
+ {
+ buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
+ return_trace (false);
+ }
- if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return_trace (false); }
+ if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]))
+ {
+ buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+ return_trace (false);
+ }
unsigned int j = skippy_iter.idx;
@@ -2544,11 +2664,16 @@ struct MarkMarkPosFormat1
}
/* Didn't match. */
+ buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
return_trace (false);
good:
unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint);
- if (mark2_index == NOT_COVERED) return_trace (false);
+ if (mark2_index == NOT_COVERED)
+ {
+ buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+ return_trace (false);
+ }
return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
}
@@ -2951,7 +3076,7 @@ GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer H
}
void
-GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
+GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
{
_hb_buffer_assert_gsubgpos_vars (buffer);
@@ -2961,12 +3086,21 @@ GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
/* Handle attachments */
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT)
- for (unsigned int i = 0; i < len; i++)
+ for (unsigned i = 0; i < len; i++)
propagate_attachment_offsets (pos, len, i, direction);
+
+ if (unlikely (font->slant))
+ {
+ for (unsigned i = 0; i < len; i++)
+ if (unlikely (pos[i].y_offset))
+ pos[i].x_offset += _hb_roundf (font->slant_xy * pos[i].y_offset);
+ }
}
-struct GPOS_accelerator_t : GPOS::accelerator_t {};
+struct GPOS_accelerator_t : GPOS::accelerator_t {
+ GPOS_accelerator_t (hb_face_t *face) : GPOS::accelerator_t (face) {}
+};
/* Out-of-class implementation for methods recursing */
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh
index b7ce30135e..0b0bc547bd 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh
@@ -826,22 +826,25 @@ struct Ligature
unsigned int total_component_count = 0;
- unsigned int match_length = 0;
+ unsigned int match_end = 0;
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
if (likely (!match_input (c, count,
&component[1],
match_glyph,
nullptr,
- &match_length,
+ &match_end,
match_positions,
&total_component_count)))
+ {
+ c->buffer->unsafe_to_concat (c->buffer->idx, match_end);
return_trace (false);
+ }
ligate_input (c,
count,
match_positions,
- match_length,
+ match_end,
ligGlyph,
total_component_count);
@@ -1296,7 +1299,7 @@ struct ReverseChainSingleSubstFormat1
match_lookahead (c,
lookahead.len, (HBUINT16 *) lookahead.arrayZ,
match_coverage, this,
- 1, &end_index))
+ c->buffer->idx + 1, &end_index))
{
c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
c->replace_glyph_inplace (substitute[index]);
@@ -1305,8 +1308,11 @@ struct ReverseChainSingleSubstFormat1
* calls us through a Context lookup. */
return_trace (true);
}
-
- return_trace (false);
+ else
+ {
+ c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
+ return_trace (false);
+ }
}
template<typename Iterator,
@@ -1739,7 +1745,9 @@ struct GSUB : GSUBGPOS
};
-struct GSUB_accelerator_t : GSUB::accelerator_t {};
+struct GSUB_accelerator_t : GSUB::accelerator_t {
+ GSUB_accelerator_t (hb_face_t *face) : GSUB::accelerator_t (face) {}
+};
/* Out-of-class implementation for methods recursing */
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
index 191d3bebc5..65de131f85 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
@@ -125,24 +125,31 @@ struct hb_closure_context_t :
hb_set_t *covered_glyph_set = done_lookups_glyph_set->get (lookup_index);
if (unlikely (covered_glyph_set->in_error ()))
return true;
- if (parent_active_glyphs ()->is_subset (*covered_glyph_set))
+ if (parent_active_glyphs ().is_subset (*covered_glyph_set))
return true;
- hb_set_union (covered_glyph_set, parent_active_glyphs ());
+ covered_glyph_set->union_ (parent_active_glyphs ());
return false;
}
- hb_set_t* parent_active_glyphs ()
+ const hb_set_t& previous_parent_active_glyphs () {
+ if (active_glyphs_stack.length <= 1)
+ return *glyphs;
+
+ return active_glyphs_stack[active_glyphs_stack.length - 2];
+ }
+
+ const hb_set_t& parent_active_glyphs ()
{
- if (active_glyphs_stack.length < 1)
- return glyphs;
+ if (!active_glyphs_stack)
+ return *glyphs;
return active_glyphs_stack.tail ();
}
- void push_cur_active_glyphs (hb_set_t* cur_active_glyph_set)
+ hb_set_t& push_cur_active_glyphs ()
{
- active_glyphs_stack.push (cur_active_glyph_set);
+ return *active_glyphs_stack.push ();
}
bool pop_cur_done_glyphs ()
@@ -156,29 +163,24 @@ struct hb_closure_context_t :
hb_face_t *face;
hb_set_t *glyphs;
- hb_set_t *cur_intersected_glyphs;
hb_set_t output[1];
- hb_vector_t<hb_set_t *> active_glyphs_stack;
+ hb_vector_t<hb_set_t> active_glyphs_stack;
recurse_func_t recurse_func;
unsigned int nesting_level_left;
hb_closure_context_t (hb_face_t *face_,
hb_set_t *glyphs_,
- hb_set_t *cur_intersected_glyphs_,
hb_map_t *done_lookups_glyph_count_,
hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set_,
unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
face (face_),
glyphs (glyphs_),
- cur_intersected_glyphs (cur_intersected_glyphs_),
recurse_func (nullptr),
nesting_level_left (nesting_level_left_),
done_lookups_glyph_count (done_lookups_glyph_count_),
done_lookups_glyph_set (done_lookups_glyph_set_),
lookup_count (0)
- {
- push_cur_active_glyphs (glyphs_);
- }
+ {}
~hb_closure_context_t () { flush (); }
@@ -186,11 +188,11 @@ struct hb_closure_context_t :
void flush ()
{
- hb_set_del_range (output, face->get_num_glyphs (), HB_SET_VALUE_INVALID); /* Remove invalid glyphs. */
- hb_set_union (glyphs, output);
- hb_set_clear (output);
+ output->del_range (face->get_num_glyphs (), HB_SET_VALUE_INVALID); /* Remove invalid glyphs. */
+ glyphs->union_ (*output);
+ output->clear ();
active_glyphs_stack.pop ();
- active_glyphs_stack.fini ();
+ active_glyphs_stack.reset ();
}
private:
@@ -520,7 +522,7 @@ struct hb_ot_apply_context_t :
may_skip (const hb_glyph_info_t &info) const
{ return matcher.may_skip (c, info); }
- bool next ()
+ bool next (unsigned *unsafe_to = nullptr)
{
assert (num_items > 0);
while (idx + num_items < end)
@@ -543,11 +545,17 @@ struct hb_ot_apply_context_t :
}
if (skip == matcher_t::SKIP_NO)
+ {
+ if (unsafe_to)
+ *unsafe_to = idx + 1;
return false;
+ }
}
+ if (unsafe_to)
+ *unsafe_to = end;
return false;
}
- bool prev ()
+ bool prev (unsigned *unsafe_from = nullptr)
{
assert (num_items > 0);
while (idx > num_items - 1)
@@ -570,8 +578,14 @@ struct hb_ot_apply_context_t :
}
if (skip == matcher_t::SKIP_NO)
+ {
+ if (unsafe_from)
+ *unsafe_from = hb_max (1u, idx) - 1u;
return false;
+ }
}
+ if (unsafe_from)
+ *unsafe_from = 0;
return false;
}
@@ -712,53 +726,60 @@ struct hb_ot_apply_context_t :
return true;
}
- void _set_glyph_props (hb_codepoint_t glyph_index,
+ void _set_glyph_class (hb_codepoint_t glyph_index,
unsigned int class_guess = 0,
bool ligature = false,
bool component = false) const
{
- unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
- HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
- add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
+ unsigned int props = _hb_glyph_info_get_glyph_props (&buffer->cur());
+ props |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
if (ligature)
{
- add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
+ props |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
/* In the only place that the MULTIPLIED bit is used, Uniscribe
* seems to only care about the "last" transformation between
* Ligature and Multiple substitutions. Ie. if you ligate, expand,
* and ligate again, it forgives the multiplication and acts as
* if only ligation happened. As such, clear MULTIPLIED bit.
*/
- add_in &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
+ props &= ~HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
}
if (component)
- add_in |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
+ props |= HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
if (likely (has_glyph_classes))
- _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index));
+ {
+ props &= HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
+ _hb_glyph_info_set_glyph_props (&buffer->cur(), props | gdef.get_glyph_props (glyph_index));
+ }
else if (class_guess)
- _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess);
+ {
+ props &= HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
+ _hb_glyph_info_set_glyph_props (&buffer->cur(), props | class_guess);
+ }
+ else
+ _hb_glyph_info_set_glyph_props (&buffer->cur(), props);
}
void replace_glyph (hb_codepoint_t glyph_index) const
{
- _set_glyph_props (glyph_index);
+ _set_glyph_class (glyph_index);
(void) buffer->replace_glyph (glyph_index);
}
void replace_glyph_inplace (hb_codepoint_t glyph_index) const
{
- _set_glyph_props (glyph_index);
+ _set_glyph_class (glyph_index);
buffer->cur().codepoint = glyph_index;
}
void replace_glyph_with_ligature (hb_codepoint_t glyph_index,
unsigned int class_guess) const
{
- _set_glyph_props (glyph_index, class_guess, true);
+ _set_glyph_class (glyph_index, class_guess, true);
(void) buffer->replace_glyph (glyph_index);
}
void output_glyph_for_component (hb_codepoint_t glyph_index,
unsigned int class_guess) const
{
- _set_glyph_props (glyph_index, class_guess, false, true);
+ _set_glyph_class (glyph_index, class_guess, false, true);
(void) buffer->output_glyph (glyph_index);
}
};
@@ -948,7 +969,7 @@ static inline bool match_input (hb_ot_apply_context_t *c,
const HBUINT16 input[], /* Array of input values--start with second glyph */
match_func_t match_func,
const void *match_data,
- unsigned int *end_offset,
+ unsigned int *end_position,
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH],
unsigned int *p_total_component_count = nullptr)
{
@@ -1001,7 +1022,12 @@ static inline bool match_input (hb_ot_apply_context_t *c,
match_positions[0] = buffer->idx;
for (unsigned int i = 1; i < count; i++)
{
- if (!skippy_iter.next ()) return_trace (false);
+ unsigned unsafe_to;
+ if (!skippy_iter.next (&unsafe_to))
+ {
+ *end_position = unsafe_to;
+ return_trace (false);
+ }
match_positions[i] = skippy_iter.idx;
@@ -1055,7 +1081,7 @@ static inline bool match_input (hb_ot_apply_context_t *c,
total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]);
}
- *end_offset = skippy_iter.idx - buffer->idx + 1;
+ *end_position = skippy_iter.idx + 1;
if (p_total_component_count)
*p_total_component_count = total_component_count;
@@ -1065,7 +1091,7 @@ static inline bool match_input (hb_ot_apply_context_t *c,
static inline bool ligate_input (hb_ot_apply_context_t *c,
unsigned int count, /* Including the first glyph */
const unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
- unsigned int match_length,
+ unsigned int match_end,
hb_codepoint_t lig_glyph,
unsigned int total_component_count)
{
@@ -1073,7 +1099,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c,
hb_buffer_t *buffer = c->buffer;
- buffer->merge_clusters (buffer->idx, buffer->idx + match_length);
+ buffer->merge_clusters (buffer->idx, match_end);
/* - If a base and one or more marks ligate, consider that as a base, NOT
* ligature, such that all following marks can still attach to it.
@@ -1190,11 +1216,16 @@ static inline bool match_backtrack (hb_ot_apply_context_t *c,
skippy_iter.set_match_func (match_func, match_data, backtrack);
for (unsigned int i = 0; i < count; i++)
- if (!skippy_iter.prev ())
+ {
+ unsigned unsafe_from;
+ if (!skippy_iter.prev (&unsafe_from))
+ {
+ *match_start = unsafe_from;
return_trace (false);
+ }
+ }
*match_start = skippy_iter.idx;
-
return_trace (true);
}
@@ -1203,21 +1234,26 @@ static inline bool match_lookahead (hb_ot_apply_context_t *c,
const HBUINT16 lookahead[],
match_func_t match_func,
const void *match_data,
- unsigned int offset,
+ unsigned int start_index,
unsigned int *end_index)
{
TRACE_APPLY (nullptr);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
- skippy_iter.reset (c->buffer->idx + offset - 1, count);
+ skippy_iter.reset (start_index - 1, count);
skippy_iter.set_match_func (match_func, match_data, lookahead);
for (unsigned int i = 0; i < count; i++)
- if (!skippy_iter.next ())
+ {
+ unsigned unsafe_to;
+ if (!skippy_iter.next (&unsafe_to))
+ {
+ *end_index = unsafe_to;
return_trace (false);
+ }
+ }
*end_index = skippy_iter.idx + 1;
-
return_trace (true);
}
@@ -1284,22 +1320,23 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c,
unsigned seqIndex = lookupRecord[i].sequenceIndex;
if (seqIndex >= inputCount) continue;
- hb_set_t *pos_glyphs = nullptr;
+ bool has_pos_glyphs = false;
+ hb_set_t pos_glyphs;
if (hb_set_is_empty (covered_seq_indicies) || !hb_set_has (covered_seq_indicies, seqIndex))
{
- pos_glyphs = hb_set_create ();
+ has_pos_glyphs = true;
if (seqIndex == 0)
{
switch (context_format) {
case ContextFormat::SimpleContext:
- pos_glyphs->add (value);
+ pos_glyphs.add (value);
break;
case ContextFormat::ClassBasedContext:
- intersected_glyphs_func (c->cur_intersected_glyphs, data, value, pos_glyphs);
+ intersected_glyphs_func (&c->parent_active_glyphs (), data, value, &pos_glyphs);
break;
case ContextFormat::CoverageBasedContext:
- hb_set_set (pos_glyphs, c->cur_intersected_glyphs);
+ pos_glyphs.set (c->parent_active_glyphs ());
break;
}
}
@@ -1313,12 +1350,16 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c,
input_value = input[seqIndex - 1];
}
- intersected_glyphs_func (c->glyphs, input_data, input_value, pos_glyphs);
+ intersected_glyphs_func (c->glyphs, input_data, input_value, &pos_glyphs);
}
}
- hb_set_add (covered_seq_indicies, seqIndex);
- c->push_cur_active_glyphs (pos_glyphs ? pos_glyphs : c->glyphs);
+ covered_seq_indicies->add (seqIndex);
+ if (has_pos_glyphs) {
+ c->push_cur_active_glyphs () = pos_glyphs;
+ } else {
+ c->push_cur_active_glyphs ().set (*c->glyphs);
+ }
unsigned endIndex = inputCount;
if (context_format == ContextFormat::CoverageBasedContext)
@@ -1327,8 +1368,6 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c,
c->recurse (lookupRecord[i].lookupListIndex, covered_seq_indicies, seqIndex, endIndex);
c->pop_cur_done_glyphs ();
- if (pos_glyphs)
- hb_set_destroy (pos_glyphs);
}
hb_set_destroy (covered_seq_indicies);
@@ -1343,15 +1382,13 @@ static inline void recurse_lookups (context_t *c,
c->recurse (lookupRecord[i].lookupListIndex);
}
-static inline bool apply_lookup (hb_ot_apply_context_t *c,
+static inline void apply_lookup (hb_ot_apply_context_t *c,
unsigned int count, /* Including the first glyph */
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
unsigned int lookupCount,
const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
- unsigned int match_length)
+ unsigned int match_end)
{
- TRACE_APPLY (nullptr);
-
hb_buffer_t *buffer = c->buffer;
int end;
@@ -1359,7 +1396,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
* Adjust. */
{
unsigned int bl = buffer->backtrack_len ();
- end = bl + match_length;
+ end = bl + match_end - buffer->idx;
int delta = bl - buffer->idx;
/* Convert positions to new indexing. */
@@ -1461,8 +1498,6 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
}
(void) buffer->move_to (end);
-
- return_trace (true);
}
@@ -1550,17 +1585,25 @@ static inline bool context_apply_lookup (hb_ot_apply_context_t *c,
const LookupRecord lookupRecord[],
ContextApplyLookupContext &lookup_context)
{
- unsigned int match_length = 0;
- unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
- return match_input (c,
- inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data,
- &match_length, match_positions)
- && (c->buffer->unsafe_to_break (c->buffer->idx, c->buffer->idx + match_length),
- apply_lookup (c,
- inputCount, match_positions,
- lookupCount, lookupRecord,
- match_length));
+ unsigned match_end = 0;
+ unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
+ if (match_input (c,
+ inputCount, input,
+ lookup_context.funcs.match, lookup_context.match_data,
+ &match_end, match_positions))
+ {
+ c->buffer->unsafe_to_break (c->buffer->idx, match_end);
+ apply_lookup (c,
+ inputCount, match_positions,
+ lookupCount, lookupRecord,
+ match_end);
+ return true;
+ }
+ else
+ {
+ c->buffer->unsafe_to_concat (c->buffer->idx, match_end);
+ return false;
+ }
}
struct Rule
@@ -1828,8 +1871,9 @@ struct ContextFormat1
void closure (hb_closure_context_t *c) const
{
- c->cur_intersected_glyphs->clear ();
- get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
+ hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
+ get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
+ cur_active_glyphs);
struct ContextClosureLookupContext lookup_context = {
{intersects_glyph, intersected_glyph},
@@ -1838,10 +1882,14 @@ struct ContextFormat1
};
+ hb_zip (this+coverage, hb_range ((unsigned) ruleSet.len))
- | hb_filter (c->parent_active_glyphs (), hb_first)
+ | hb_filter ([&] (hb_codepoint_t _) {
+ return c->previous_parent_active_glyphs ().has (_);
+ }, hb_first)
| hb_map ([&](const hb_pair_t<hb_codepoint_t, unsigned> _) { return hb_pair_t<unsigned, const RuleSet&> (_.first, this+ruleSet[_.second]); })
| hb_apply ([&] (const hb_pair_t<unsigned, const RuleSet&>& _) { _.second.closure (c, _.first, lookup_context); })
;
+
+ c->pop_cur_done_glyphs ();
}
void closure_lookups (hb_closure_lookups_context_t *c) const
@@ -1989,8 +2037,9 @@ struct ContextFormat2
if (!(this+coverage).intersects (c->glyphs))
return;
- c->cur_intersected_glyphs->clear ();
- get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
+ hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
+ get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
+ cur_active_glyphs);
const ClassDef &class_def = this+classDef;
@@ -2000,10 +2049,9 @@ struct ContextFormat2
&class_def
};
- return
+ hb_enumerate (ruleSet)
| hb_filter ([&] (unsigned _)
- { return class_def.intersects_class (c->cur_intersected_glyphs, _); },
+ { return class_def.intersects_class (&c->parent_active_glyphs (), _); },
hb_first)
| hb_apply ([&] (const hb_pair_t<unsigned, const Offset16To<RuleSet>&> _)
{
@@ -2011,6 +2059,8 @@ struct ContextFormat2
rule_set.closure (c, _.first, lookup_context);
})
;
+
+ c->pop_cur_done_glyphs ();
}
void closure_lookups (hb_closure_lookups_context_t *c) const
@@ -2183,8 +2233,10 @@ struct ContextFormat3
if (!(this+coverageZ[0]).intersects (c->glyphs))
return;
- c->cur_intersected_glyphs->clear ();
- get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
+ hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
+ get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
+ cur_active_glyphs);
+
const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
struct ContextClosureLookupContext lookup_context = {
@@ -2196,6 +2248,8 @@ struct ContextFormat3
glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
lookupCount, lookupRecord,
0, lookup_context);
+
+ c->pop_cur_done_glyphs ();
}
void closure_lookups (hb_closure_lookups_context_t *c) const
@@ -2452,25 +2506,38 @@ static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
const LookupRecord lookupRecord[],
ChainContextApplyLookupContext &lookup_context)
{
- unsigned int start_index = 0, match_length = 0, end_index = 0;
- unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
- return match_input (c,
- inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data[1],
- &match_length, match_positions)
- && match_backtrack (c,
- backtrackCount, backtrack,
- lookup_context.funcs.match, lookup_context.match_data[0],
- &start_index)
- && match_lookahead (c,
- lookaheadCount, lookahead,
- lookup_context.funcs.match, lookup_context.match_data[2],
- match_length, &end_index)
- && (c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index),
- apply_lookup (c,
- inputCount, match_positions,
- lookupCount, lookupRecord,
- match_length));
+ unsigned end_index = c->buffer->idx;
+ unsigned match_end = 0;
+ unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
+ if (!(match_input (c,
+ inputCount, input,
+ lookup_context.funcs.match, lookup_context.match_data[1],
+ &match_end, match_positions) && (end_index = match_end)
+ && match_lookahead (c,
+ lookaheadCount, lookahead,
+ lookup_context.funcs.match, lookup_context.match_data[2],
+ match_end, &end_index)))
+ {
+ c->buffer->unsafe_to_concat (c->buffer->idx, end_index);
+ return false;
+ }
+
+ unsigned start_index = c->buffer->out_len;
+ if (!match_backtrack (c,
+ backtrackCount, backtrack,
+ lookup_context.funcs.match, lookup_context.match_data[0],
+ &start_index))
+ {
+ c->buffer->unsafe_to_concat_from_outbuffer (start_index, end_index);
+ return false;
+ }
+
+ c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
+ apply_lookup (c,
+ inputCount, match_positions,
+ lookupCount, lookupRecord,
+ match_end);
+ return true;
}
struct ChainRule
@@ -2802,8 +2869,9 @@ struct ChainContextFormat1
void closure (hb_closure_context_t *c) const
{
- c->cur_intersected_glyphs->clear ();
- get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
+ hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
+ get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
+ cur_active_glyphs);
struct ChainContextClosureLookupContext lookup_context = {
{intersects_glyph, intersected_glyph},
@@ -2812,10 +2880,14 @@ struct ChainContextFormat1
};
+ hb_zip (this+coverage, hb_range ((unsigned) ruleSet.len))
- | hb_filter (c->parent_active_glyphs (), hb_first)
+ | hb_filter ([&] (hb_codepoint_t _) {
+ return c->previous_parent_active_glyphs ().has (_);
+ }, hb_first)
| hb_map ([&](const hb_pair_t<hb_codepoint_t, unsigned> _) { return hb_pair_t<unsigned, const ChainRuleSet&> (_.first, this+ruleSet[_.second]); })
| hb_apply ([&] (const hb_pair_t<unsigned, const ChainRuleSet&>& _) { _.second.closure (c, _.first, lookup_context); })
;
+
+ c->pop_cur_done_glyphs ();
}
void closure_lookups (hb_closure_lookups_context_t *c) const
@@ -2964,8 +3036,10 @@ struct ChainContextFormat2
if (!(this+coverage).intersects (c->glyphs))
return;
- c->cur_intersected_glyphs->clear ();
- get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
+ hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
+ get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
+ cur_active_glyphs);
+
const ClassDef &backtrack_class_def = this+backtrackClassDef;
const ClassDef &input_class_def = this+inputClassDef;
@@ -2979,10 +3053,9 @@ struct ChainContextFormat2
&lookahead_class_def}
};
- return
+ hb_enumerate (ruleSet)
| hb_filter ([&] (unsigned _)
- { return input_class_def.intersects_class (c->cur_intersected_glyphs, _); },
+ { return input_class_def.intersects_class (&c->parent_active_glyphs (), _); },
hb_first)
| hb_apply ([&] (const hb_pair_t<unsigned, const Offset16To<ChainRuleSet>&> _)
{
@@ -2990,6 +3063,8 @@ struct ChainContextFormat2
chainrule_set.closure (c, _.first, lookup_context);
})
;
+
+ c->pop_cur_done_glyphs ();
}
void closure_lookups (hb_closure_lookups_context_t *c) const
@@ -3216,8 +3291,10 @@ struct ChainContextFormat3
if (!(this+input[0]).intersects (c->glyphs))
return;
- c->cur_intersected_glyphs->clear ();
- get_coverage ().intersected_coverage_glyphs (c->parent_active_glyphs (), c->cur_intersected_glyphs);
+ hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs ();
+ get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (),
+ cur_active_glyphs);
+
const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input);
const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead);
@@ -3232,6 +3309,8 @@ struct ChainContextFormat3
lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
lookup.len, lookup.arrayZ,
0, lookup_context);
+
+ c->pop_cur_done_glyphs ();
}
void closure_lookups (hb_closure_lookups_context_t *c) const
@@ -3706,7 +3785,7 @@ struct GSUBGPOS
for (unsigned i : feature_indices->iter ())
{
hb_tag_t t = get_feature_tag (i);
- if (t == unique_features.INVALID_KEY) continue;
+ if (t == HB_MAP_VALUE_INVALID) continue;
if (!unique_features.has (t))
{
hb_set_t* indices = hb_set_create ();
@@ -3839,7 +3918,7 @@ struct GSUBGPOS
template <typename T>
struct accelerator_t
{
- void init (hb_face_t *face)
+ accelerator_t (hb_face_t *face)
{
this->table = hb_sanitize_context_t ().reference_table<T> (face);
if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face)))
@@ -3861,8 +3940,7 @@ struct GSUBGPOS
for (unsigned int i = 0; i < this->lookup_count; i++)
this->accels[i].init (table->get_lookup (i));
}
-
- void fini ()
+ ~accelerator_t ()
{
for (unsigned int i = 0; i < this->lookup_count; i++)
this->accels[i].fini ();
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc
index 60733648c1..a599eea6e9 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc
@@ -1491,10 +1491,9 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
unsigned int lookup_index,
hb_set_t *glyphs /* OUT */)
{
- hb_set_t cur_intersected_glyphs;
hb_map_t done_lookups_glyph_count;
hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
- OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
+ OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index);
@@ -1520,10 +1519,9 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
const hb_set_t *lookups,
hb_set_t *glyphs /* OUT */)
{
- hb_set_t cur_intersected_glyphs;
hb_map_t done_lookups_glyph_count;
hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
- OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
+ OT::hb_closure_context_t c (face, glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
const OT::GSUB& gsub = *face->table.GSUB->table;
unsigned int iteration_count = 0;
@@ -1890,7 +1888,7 @@ apply_string (OT::hb_ot_apply_context_t *c,
apply_forward (c, accel);
if (!Proxy::inplace)
- buffer->swap_buffers ();
+ buffer->sync ();
}
else
{
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.hh b/thirdparty/harfbuzz/src/hb-ot-layout.hh
index 2c825e0c81..ede8f007db 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout.hh
@@ -482,10 +482,9 @@ _hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info)
}
static inline uint8_t
-_hb_allocate_lig_id (hb_buffer_t *buffer) {
+_hb_allocate_lig_id (hb_buffer_t *buffer)
+{
uint8_t lig_id = buffer->next_serial () & 0x07;
- if (unlikely (!lig_id))
- lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */
return lig_id;
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-meta-table.hh b/thirdparty/harfbuzz/src/hb-ot-meta-table.hh
index e31447f8fc..93e64c5327 100644
--- a/thirdparty/harfbuzz/src/hb-ot-meta-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-meta-table.hh
@@ -71,9 +71,9 @@ struct meta
struct accelerator_t
{
- void init (hb_face_t *face)
+ accelerator_t (hb_face_t *face)
{ table = hb_sanitize_context_t ().reference_table<meta> (face); }
- void fini () { table.destroy (); }
+ ~accelerator_t () { table.destroy (); }
hb_blob_t *reference_entry (hb_tag_t tag) const
{ return table->dataMaps.lsearch (tag).reference_entry (table.get_blob ()); }
@@ -119,7 +119,9 @@ struct meta
DEFINE_SIZE_ARRAY (16, dataMaps);
};
-struct meta_accelerator_t : meta::accelerator_t {};
+struct meta_accelerator_t : meta::accelerator_t {
+ meta_accelerator_t (hb_face_t *face) : meta::accelerator_t (face) {}
+};
} /* namespace OT */
diff --git a/thirdparty/harfbuzz/src/hb-ot-metrics.cc b/thirdparty/harfbuzz/src/hb-ot-metrics.cc
index dbd4a1ffbe..103808cf91 100644
--- a/thirdparty/harfbuzz/src/hb-ot-metrics.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-metrics.cc
@@ -160,9 +160,50 @@ hb_ot_metrics_get_position (hb_font_t *font,
(position && (*position = font->em_scalef_y (face->table.TABLE->ATTR + GET_VAR)), true))
case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT: return GET_METRIC_Y (OS2, usWinAscent);
case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT: return GET_METRIC_Y (OS2, usWinDescent);
- case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE: return GET_METRIC_Y (hhea, caretSlopeRise);
- case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN: return GET_METRIC_X (hhea, caretSlopeRun);
+
+ case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE:
+ case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN:
+ {
+ unsigned mult = 1u;
+
+ if (font->slant)
+ {
+ unsigned rise = face->table.hhea->caretSlopeRise;
+ unsigned upem = face->get_upem ();
+ mult = (rise && rise < upem) ? hb_min (upem / rise, 256u) : 1u;
+ }
+
+ if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE)
+ {
+ bool ret = GET_METRIC_Y (hhea, caretSlopeRise);
+
+ if (position)
+ *position *= mult;
+
+ return ret;
+ }
+ else
+ {
+ hb_position_t rise = 0;
+
+ if (font->slant && position && GET_METRIC_Y (hhea, caretSlopeRise))
+ rise = *position;
+
+ bool ret = GET_METRIC_X (hhea, caretSlopeRun);
+
+ if (position)
+ {
+ *position *= mult;
+
+ if (font->slant)
+ *position += _hb_roundf (mult * font->slant_xy * rise);
+ }
+
+ return ret;
+ }
+ }
case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET: return GET_METRIC_X (hhea, caretOffset);
+
#ifndef HB_NO_VERTICAL
case HB_OT_METRICS_TAG_VERTICAL_CARET_RISE: return GET_METRIC_X (vhea, caretSlopeRise);
case HB_OT_METRICS_TAG_VERTICAL_CARET_RUN: return GET_METRIC_Y (vhea, caretSlopeRun);
diff --git a/thirdparty/harfbuzz/src/hb-ot-name-table.hh b/thirdparty/harfbuzz/src/hb-ot-name-table.hh
index c17bb4abb8..d52367e9b1 100644
--- a/thirdparty/harfbuzz/src/hb-ot-name-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-name-table.hh
@@ -256,7 +256,7 @@ struct name
})
;
- name_prime->serialize (c->serializer, it, hb_addressof (this + stringOffset));
+ name_prime->serialize (c->serializer, it, std::addressof (this + stringOffset));
return_trace (name_prime->count);
}
@@ -279,7 +279,7 @@ struct name
struct accelerator_t
{
- void init (hb_face_t *face)
+ accelerator_t (hb_face_t *face)
{
this->table = hb_sanitize_context_t ().reference_table<name> (face);
assert (this->table.get_length () >= this->table->stringOffset);
@@ -288,7 +288,6 @@ struct name
const hb_array_t<const NameRecord> all_names (this->table->nameRecordZ.arrayZ,
this->table->count);
- this->names.init ();
this->names.alloc (all_names.length);
for (unsigned int i = 0; i < all_names.length; i++)
@@ -318,10 +317,8 @@ struct name
}
this->names.resize (j);
}
-
- void fini ()
+ ~accelerator_t ()
{
- this->names.fini ();
this->table.destroy ();
}
@@ -373,7 +370,9 @@ struct name
#undef entry_index
#undef entry_score
-struct name_accelerator_t : name::accelerator_t {};
+struct name_accelerator_t : name::accelerator_t {
+ name_accelerator_t (hb_face_t *face) : name::accelerator_t (face) {}
+};
} /* namespace OT */
diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh
index 504de2de74..0f3cd8e24f 100644
--- a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh
@@ -76,8 +76,7 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
hb_map_t old_new_index_map, old_gid_new_index_map;
unsigned i = 0;
- post::accelerator_t _post;
- _post.init (c->plan->source);
+ post::accelerator_t _post (c->plan->source);
hb_hashmap_t<hb_bytes_t, unsigned, std::nullptr_t, unsigned, nullptr, (unsigned)-1> glyph_name_to_new_index;
for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
@@ -128,9 +127,7 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
})
;
- bool ret = serialize (c->serializer, index_iter, &_post);
- _post.fini ();
- return_trace (ret);
+ return_trace (serialize (c->serializer, index_iter, &_post));
}
} /* namespace OT */
diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table.hh b/thirdparty/harfbuzz/src/hb-ot-post-table.hh
index 39de671707..a4844e94bc 100644
--- a/thirdparty/harfbuzz/src/hb-ot-post-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-post-table.hh
@@ -111,10 +111,9 @@ struct post
struct accelerator_t
{
friend struct postV2Tail;
- void init (hb_face_t *face)
- {
- index_to_offset.init ();
+ accelerator_t (hb_face_t *face)
+ {
table = hb_sanitize_context_t ().reference_table<post> (face);
unsigned int table_length = table.get_length ();
@@ -132,9 +131,8 @@ struct post
data += 1 + *data)
index_to_offset.push (data - pool);
}
- void fini ()
+ ~accelerator_t ()
{
- index_to_offset.fini ();
hb_free (gids_sorted_by_name.get ());
table.destroy ();
}
@@ -254,9 +252,9 @@ struct post
private:
uint32_t version;
- const Array16Of<HBUINT16> *glyphNameIndex;
+ const Array16Of<HBUINT16> *glyphNameIndex = nullptr;
hb_vector_t<uint32_t> index_to_offset;
- const uint8_t *pool;
+ const uint8_t *pool = nullptr;
hb_atomic_ptr_t<uint16_t *> gids_sorted_by_name;
};
@@ -307,7 +305,10 @@ struct post
DEFINE_SIZE_MIN (32);
};
-struct post_accelerator_t : post::accelerator_t {};
+struct post_accelerator_t : post::accelerator_t {
+ post_accelerator_t (hb_face_t *face) : post::accelerator_t (face) {}
+};
+
} /* namespace OT */
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh
index 41e3dd38ab..429974d05b 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh
@@ -87,6 +87,8 @@
#define OT_GLYPHID /* GlyphID */ \
OT_UINT16
+/* Shorthand. */
+#define G OT_GLYPHID
#define OT_UARRAY(Name, Items) \
OT_LABEL_START(Name) \
@@ -183,8 +185,6 @@
Tag \
OT_OFFSET(manifest, Name)
-/* Shorthand. */
-#define G OT_GLYPHID
/*
* Table Start
@@ -300,14 +300,40 @@ OT_TABLE_END
/*
* Clean up
*/
+
+#undef MANIFEST
+#undef MANIFEST_LOOKUP
+
#undef OT_TABLE_START
#undef OT_TABLE_END
#undef OT_LABEL_START
#undef OT_LABEL_END
#undef OT_UINT8
#undef OT_UINT16
-#undef OT_DISTANCE
#undef OT_COUNT
+#undef OT_DISTANCE
+
+#undef OT_LABEL
+#undef OT_LIST
+
+#undef OT_TAG
+#undef OT_OFFSET
+#undef OT_GLYPHID
+#undef G
+#undef OT_UARRAY
+#undef OT_UHEADLESSARRAY
+
+#undef OT_LOOKUP_FLAG_IGNORE_MARKS
+#undef OT_LOOKUP
+#undef OT_SUBLOOKUP
+#undef OT_COVERAGE1
+#undef OT_LOOKUP_TYPE_SUBST_SINGLE
+#undef OT_LOOKUP_TYPE_SUBST_LIGATURE
+#undef OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2
+#undef OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1
+#undef OT_LIGATURE_SET
+#undef OT_LIGATURE
+
/*
* Include a second time to get the table data...
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc
index 222c5d6b71..2298aa92f2 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-arabic.cc
@@ -321,6 +321,20 @@ arabic_joining (hb_buffer_t *buffer)
info[prev].arabic_shaping_action() = entry->prev_action;
buffer->unsafe_to_break (prev, i + 1);
}
+ else
+ {
+ if (prev == UINT_MAX)
+ {
+ if (this_type >= JOINING_TYPE_R)
+ buffer->unsafe_to_concat_from_outbuffer (0, i + 1);
+ }
+ else
+ {
+ if (this_type >= JOINING_TYPE_R ||
+ (2 <= state && state <= 5) /* States that have a possible prev_action. */)
+ buffer->unsafe_to_concat (prev, i + 1);
+ }
+ }
info[i].arabic_shaping_action() = entry->curr_action;
@@ -337,7 +351,14 @@ arabic_joining (hb_buffer_t *buffer)
const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
if (entry->prev_action != NONE && prev != UINT_MAX)
+ {
info[prev].arabic_shaping_action() = entry->prev_action;
+ buffer->unsafe_to_break (prev, buffer->len);
+ }
+ else if (2 <= state && state <= 5) /* States that have a possible prev_action. */
+ {
+ buffer->unsafe_to_concat (prev, buffer->len);
+ }
break;
}
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc
index 0d84a76b85..3bc9e9b961 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-hangul.cc
@@ -140,7 +140,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
*
* - LV can be precomposed, or decomposed. Lets call those
* <LV> and <L,V>,
- * - LVT can be fully precomposed, partically precomposed, or
+ * - LVT can be fully precomposed, partially precomposed, or
* fully decomposed. Ie. <LVT>, <LV,T>, or <L,V,T>.
*
* The composition / decomposition is mechanical. However, not
@@ -392,7 +392,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
*/
(void) buffer->next_glyph ();
}
- buffer->swap_buffers ();
+ buffer->sync ();
}
static void
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.cc
index 5a08f878dc..76092c7f38 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-syllabic.cc
@@ -96,7 +96,7 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font,
else
(void) buffer->next_glyph ();
}
- buffer->swap_buffers ();
+ buffer->sync ();
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-thai.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-thai.cc
index 4c3068173b..a1e27a83be 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-thai.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-thai.cc
@@ -364,7 +364,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
buffer->merge_out_clusters (start - 1, end);
}
}
- buffer->swap_buffers ();
+ buffer->sync ();
/* If font has Thai GSUB, we are done. */
if (plan->props.script == HB_SCRIPT_THAI && !plan->map.found_script[0])
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc b/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc
index 045731dfb4..d2cca105a4 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-complex-vowel-constraints.cc
@@ -435,7 +435,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
default:
break;
}
- buffer->swap_buffers ();
+ buffer->sync ();
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc b/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc
index eb1bc79768..671f30327f 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-fallback.cc
@@ -446,6 +446,9 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
return;
#endif
+ if (!buffer->message (font, "start fallback mark"))
+ return;
+
_hb_buffer_assert_gsubgpos_vars (buffer);
unsigned int start = 0;
@@ -457,6 +460,8 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
start = i;
}
position_cluster (plan, font, buffer, start, count, adjust_offsets_when_zeroing);
+
+ (void) buffer->message (font, "end fallback mark");
}
@@ -492,6 +497,9 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
#endif
#ifndef HB_DISABLE_DEPRECATED
+ if (!buffer->message (font, "start fallback kern"))
+ return;
+
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
!font->has_glyph_h_kerning_func () :
!font->has_glyph_v_kerning_func ())
@@ -508,6 +516,8 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
if (reverse)
buffer->reverse ();
+
+ (void) buffer->message (font, "end fallback kern");
#endif
}
@@ -525,6 +535,15 @@ _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan HB_UNUSED,
for (unsigned int i = 0; i < count; i++)
if (_hb_glyph_info_is_unicode_space (&info[i]) && !_hb_glyph_info_ligated (&info[i]))
{
+ /* If font had no ASCII space and we used the invisible glyph, give it a 1/4 EM default advance. */
+ if (buffer->invisible && info[i].codepoint == buffer->invisible)
+ {
+ if (horizontal)
+ pos[i].x_advance = +font->x_scale / 4;
+ else
+ pos[i].y_advance = -font->y_scale / 4;
+ }
+
hb_unicode_funcs_t::space_t space_type = _hb_glyph_info_get_unicode_space_fallback_type (&info[i]);
hb_codepoint_t glyph;
typedef hb_unicode_funcs_t t;
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc
index 839cc9122c..aa5a8eeaa3 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape-normalize.cc
@@ -193,7 +193,8 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor
{
hb_codepoint_t space_glyph;
hb_unicode_funcs_t::space_t space_type = buffer->unicode->space_fallback_type (u);
- if (space_type != hb_unicode_funcs_t::NOT_SPACE && c->font->get_nominal_glyph (0x0020u, &space_glyph))
+ if (space_type != hb_unicode_funcs_t::NOT_SPACE &&
+ (c->font->get_nominal_glyph (0x0020, &space_glyph) || (space_glyph = buffer->invisible)))
{
_hb_glyph_info_set_unicode_space_fallback_type (&buffer->cur(), space_type);
next_char (buffer, space_glyph);
@@ -374,7 +375,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
decompose_multi_char_cluster (&c, end, always_short_circuit);
}
while (buffer->idx < count && buffer->successful);
- buffer->swap_buffers ();
+ buffer->sync ();
}
@@ -477,7 +478,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
if (info_cc (buffer->prev()) == 0)
starter = buffer->out_len - 1;
}
- buffer->swap_buffers ();
+ buffer->sync ();
}
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc
index 4dde3520d8..4bd8aaf03b 100644
--- a/thirdparty/harfbuzz/src/hb-ot-shape.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc
@@ -566,7 +566,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
info.mask = buffer->cur().mask;
(void) buffer->output_info (info);
- buffer->swap_buffers ();
+ buffer->sync ();
}
static void
@@ -1034,7 +1034,7 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
* hanging over the next glyph after the final reordering.
*
* Note: If fallback positinoing happens, we don't care about
- * this as it will be overriden.
+ * this as it will be overridden.
*/
bool adjust_offsets_when_zeroing = c->plan->adjust_mark_positioning_when_zeroing &&
HB_DIRECTION_IS_FORWARD (c->buffer->props.direction);
@@ -1120,7 +1120,7 @@ hb_propagate_flags (hb_buffer_t *buffer)
/* Propagate cluster-level glyph flags to be the same on all cluster glyphs.
* Simplifies using them. */
- if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK))
+ if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GLYPH_FLAGS))
return;
hb_glyph_info_t *info = buffer->info;
@@ -1129,11 +1129,7 @@ hb_propagate_flags (hb_buffer_t *buffer)
{
unsigned int mask = 0;
for (unsigned int i = start; i < end; i++)
- if (info[i].mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
- {
- mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
- break;
- }
+ mask |= info[i].mask & HB_GLYPH_FLAG_DEFINED;
if (mask)
for (unsigned int i = start; i < end; i++)
info[i].mask |= mask;
@@ -1145,18 +1141,7 @@ hb_propagate_flags (hb_buffer_t *buffer)
static void
hb_ot_shape_internal (hb_ot_shape_context_t *c)
{
- c->buffer->deallocate_var_all ();
- c->buffer->scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
- if (likely (!hb_unsigned_mul_overflows (c->buffer->len, HB_BUFFER_MAX_LEN_FACTOR)))
- {
- c->buffer->max_len = hb_max (c->buffer->len * HB_BUFFER_MAX_LEN_FACTOR,
- (unsigned) HB_BUFFER_MAX_LEN_MIN);
- }
- if (likely (!hb_unsigned_mul_overflows (c->buffer->len, HB_BUFFER_MAX_OPS_FACTOR)))
- {
- c->buffer->max_ops = hb_max (c->buffer->len * HB_BUFFER_MAX_OPS_FACTOR,
- (unsigned) HB_BUFFER_MAX_OPS_MIN);
- }
+ c->buffer->enter ();
/* Save the original direction, we use it later. */
c->target_direction = c->buffer->props.direction;
@@ -1188,9 +1173,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
c->buffer->props.direction = c->target_direction;
- c->buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT;
- c->buffer->max_ops = HB_BUFFER_MAX_OPS_DEFAULT;
- c->buffer->deallocate_var_all ();
+ c->buffer->leave ();
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh
index 2c6316df4f..61d2814e93 100644
--- a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh
@@ -6,8 +6,8 @@
*
* on files with these headers:
*
- * <meta name="updated_at" content="2021-12-09 12:01 AM" />
- * File-Date: 2021-08-06
+ * <meta name="updated_at" content="2022-01-28 10:00 PM" />
+ * File-Date: 2021-12-29
*/
#ifndef HB_OT_TAG_TABLE_HH
@@ -66,7 +66,7 @@ static const LangTag ot_languages[] = {
{"an", HB_TAG('A','R','G',' ')}, /* Aragonese */
/*{"ang", HB_TAG('A','N','G',' ')},*/ /* Old English (ca. 450-1100) -> Anglo-Saxon */
{"aoa", HB_TAG('C','P','P',' ')}, /* Angolar -> Creoles */
- {"apa", HB_TAG('A','T','H',' ')}, /* Apache [family] -> Athapaskan */
+ {"apa", HB_TAG('A','T','H',' ')}, /* Apache [collection] -> Athapaskan */
{"apc", HB_TAG('A','R','A',' ')}, /* North Levantine Arabic -> Arabic */
{"apd", HB_TAG('A','R','A',' ')}, /* Sudanese Arabic -> Arabic */
{"apj", HB_TAG('A','T','H',' ')}, /* Jicarilla Apache -> Athapaskan */
@@ -86,7 +86,7 @@ static const LangTag ot_languages[] = {
{"arz", HB_TAG('A','R','A',' ')}, /* Egyptian Arabic -> Arabic */
{"as", HB_TAG('A','S','M',' ')}, /* Assamese */
/*{"ast", HB_TAG('A','S','T',' ')},*/ /* Asturian */
-/*{"ath", HB_TAG('A','T','H',' ')},*/ /* Athapascan [family] -> Athapaskan */
+/*{"ath", HB_TAG('A','T','H',' ')},*/ /* Athapascan [collection] -> Athapaskan */
{"atj", HB_TAG('R','C','R',' ')}, /* Atikamekw -> R-Cree */
{"atv", HB_TAG('A','L','T',' ')}, /* Northern Altai -> Altai */
{"auj", HB_TAG('B','B','R',' ')}, /* Awjilah -> Berber */
@@ -110,10 +110,10 @@ static const LangTag ot_languages[] = {
{"azn", HB_TAG('N','A','H',' ')}, /* Western Durango Nahuatl -> Nahuatl */
{"azz", HB_TAG('N','A','H',' ')}, /* Highland Puebla Nahuatl -> Nahuatl */
{"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */
- {"bad", HB_TAG('B','A','D','0')}, /* Banda [family] */
+ {"bad", HB_TAG('B','A','D','0')}, /* Banda [collection] */
{"bag", HB_TAG_NONE }, /* Tuki != Baghelkhandi */
{"bah", HB_TAG('C','P','P',' ')}, /* Bahamas Creole English -> Creoles */
- {"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */
+ {"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [collection] */
{"bal", HB_TAG('B','L','I',' ')}, /* Baluchi [macrolanguage] */
/*{"ban", HB_TAG('B','A','N',' ')},*/ /* Balinese */
/*{"bar", HB_TAG('B','A','R',' ')},*/ /* Bavarian */
@@ -135,7 +135,7 @@ static const LangTag ot_languages[] = {
{"bea", HB_TAG('A','T','H',' ')}, /* Beaver -> Athapaskan */
{"beb", HB_TAG('B','T','I',' ')}, /* Bebele -> Beti */
/*{"bem", HB_TAG('B','E','M',' ')},*/ /* Bemba (Zambia) */
- {"ber", HB_TAG('B','B','R',' ')}, /* Berber [family] */
+ {"ber", HB_TAG('B','B','R',' ')}, /* Berber [collection] */
{"bew", HB_TAG('C','P','P',' ')}, /* Betawi -> Creoles */
{"bfl", HB_TAG('B','A','D','0')}, /* Banda-Ndélé -> Banda */
{"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */
@@ -203,7 +203,7 @@ static const LangTag ot_languages[] = {
{"btd", HB_TAG('B','T','K',' ')}, /* Batak Dairi -> Batak */
{"bti", HB_TAG_NONE }, /* Burate != Beti */
{"btj", HB_TAG('M','L','Y',' ')}, /* Bacanese Malay -> Malay */
-/*{"btk", HB_TAG('B','T','K',' ')},*/ /* Batak [family] */
+/*{"btk", HB_TAG('B','T','K',' ')},*/ /* Batak [collection] */
{"btm", HB_TAG('B','T','M',' ')}, /* Batak Mandailing */
{"btm", HB_TAG('B','T','K',' ')}, /* Batak Mandailing -> Batak */
{"bto", HB_TAG('B','I','K',' ')}, /* Rinconada Bikol -> Bikol */
@@ -256,6 +256,8 @@ static const LangTag ot_languages[] = {
{"chh", HB_TAG_NONE }, /* Chinook != Chattisgarhi */
{"chj", HB_TAG('C','C','H','N')}, /* OjitlĂ¡n Chinantec -> Chinantec */
{"chk", HB_TAG('C','H','K','0')}, /* Chuukese */
+ {"chm", HB_TAG('H','M','A',' ')}, /* Mari (Russia) [macrolanguage] -> High Mari */
+ {"chm", HB_TAG('L','M','A',' ')}, /* Mari (Russia) [macrolanguage] -> Low Mari */
{"chn", HB_TAG('C','P','P',' ')}, /* Chinook jargon -> Creoles */
/*{"cho", HB_TAG('C','H','O',' ')},*/ /* Choctaw */
{"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */
@@ -297,10 +299,10 @@ static const LangTag ot_languages[] = {
/*{"cop", HB_TAG('C','O','P',' ')},*/ /* Coptic */
{"coq", HB_TAG('A','T','H',' ')}, /* Coquille -> Athapaskan */
{"cpa", HB_TAG('C','C','H','N')}, /* Palantla Chinantec -> Chinantec */
- {"cpe", HB_TAG('C','P','P',' ')}, /* English-based creoles and pidgins [family] -> Creoles */
- {"cpf", HB_TAG('C','P','P',' ')}, /* French-based creoles and pidgins [family] -> Creoles */
+ {"cpe", HB_TAG('C','P','P',' ')}, /* English-based creoles and pidgins [collection] -> Creoles */
+ {"cpf", HB_TAG('C','P','P',' ')}, /* French-based creoles and pidgins [collection] -> Creoles */
{"cpi", HB_TAG('C','P','P',' ')}, /* Chinese Pidgin English -> Creoles */
-/*{"cpp", HB_TAG('C','P','P',' ')},*/ /* Portuguese-based creoles and pidgins [family] -> Creoles */
+/*{"cpp", HB_TAG('C','P','P',' ')},*/ /* Portuguese-based creoles and pidgins [collection] -> Creoles */
{"cpx", HB_TAG('Z','H','S',' ')}, /* Pu-Xian Chinese -> Chinese, Simplified */
{"cqd", HB_TAG('H','M','N',' ')}, /* Chuanqiandian Cluster Miao -> Hmong */
{"cqu", HB_TAG('Q','U','H',' ')}, /* Chilean Quechua (retired code) -> Quechua (Bolivia) */
@@ -320,7 +322,7 @@ static const LangTag ot_languages[] = {
{"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */
{"crm", HB_TAG('L','C','R',' ')}, /* Moose Cree -> L-Cree */
{"crm", HB_TAG('C','R','E',' ')}, /* Moose Cree -> Cree */
- {"crp", HB_TAG('C','P','P',' ')}, /* Creoles and pidgins [family] -> Creoles */
+ {"crp", HB_TAG('C','P','P',' ')}, /* Creoles and pidgins [collection] -> Creoles */
{"crr", HB_TAG_NONE }, /* Carolina Algonquian != Carrier */
{"crs", HB_TAG('C','P','P',' ')}, /* Seselwa Creole French -> Creoles */
{"crt", HB_TAG_NONE }, /* Iyojwa'ja Chorote != Crimean Tatar */
@@ -431,7 +433,7 @@ static const LangTag ot_languages[] = {
{"et", HB_TAG('E','T','I',' ')}, /* Estonian [macrolanguage] */
{"eto", HB_TAG('B','T','I',' ')}, /* Eton (Cameroon) -> Beti */
{"eu", HB_TAG('E','U','Q',' ')}, /* Basque */
- {"euq", HB_TAG_NONE }, /* Basque [family] != Basque */
+ {"euq", HB_TAG_NONE }, /* Basque [collection] != Basque */
{"eve", HB_TAG('E','V','N',' ')}, /* Even */
{"evn", HB_TAG('E','V','K',' ')}, /* Evenki */
{"ewo", HB_TAG('B','T','I',' ')}, /* Ewondo -> Beti */
@@ -620,10 +622,11 @@ static const LangTag ot_languages[] = {
{"ijc", HB_TAG('I','J','O',' ')}, /* Izon -> Ijo */
{"ije", HB_TAG('I','J','O',' ')}, /* Biseni -> Ijo */
{"ijn", HB_TAG('I','J','O',' ')}, /* Kalabari -> Ijo */
-/*{"ijo", HB_TAG('I','J','O',' ')},*/ /* Ijo [family] */
+/*{"ijo", HB_TAG('I','J','O',' ')},*/ /* Ijo [collection] */
{"ijs", HB_TAG('I','J','O',' ')}, /* Southeast Ijo -> Ijo */
{"ik", HB_TAG('I','P','K',' ')}, /* Inupiaq [macrolanguage] -> Inupiat */
{"ike", HB_TAG('I','N','U',' ')}, /* Eastern Canadian Inuktitut -> Inuktitut */
+ {"ike", HB_TAG('I','N','U','K')}, /* Eastern Canadian Inuktitut -> Nunavik Inuktitut */
{"ikt", HB_TAG('I','N','U',' ')}, /* Inuinnaqtun -> Inuktitut */
/*{"ilo", HB_TAG('I','L','O',' ')},*/ /* Iloko -> Ilokano */
{"in", HB_TAG('I','N','D',' ')}, /* Indonesian (retired code) */
@@ -638,6 +641,7 @@ static const LangTag ot_languages[] = {
{"it", HB_TAG('I','T','A',' ')}, /* Italian */
{"itz", HB_TAG('M','Y','N',' ')}, /* ItzĂ¡ -> Mayan */
{"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut [macrolanguage] */
+ {"iu", HB_TAG('I','N','U','K')}, /* Inuktitut [macrolanguage] -> Nunavik Inuktitut */
{"iw", HB_TAG('I','W','R',' ')}, /* Hebrew (retired code) */
{"ixl", HB_TAG('M','Y','N',' ')}, /* Ixil -> Mayan */
{"ja", HB_TAG('J','A','N',' ')}, /* Japanese */
@@ -667,7 +671,7 @@ static const LangTag ot_languages[] = {
{"kab", HB_TAG('B','B','R',' ')}, /* Kabyle -> Berber */
{"kac", HB_TAG_NONE }, /* Kachin != Kachchi */
{"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */
- {"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */
+ {"kar", HB_TAG('K','R','N',' ')}, /* Karen [collection] */
/*{"kaw", HB_TAG('K','A','W',' ')},*/ /* Kawi (Old Javanese) */
{"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */
{"kby", HB_TAG('K','N','R',' ')}, /* Manga Kanuri -> Kanuri */
@@ -876,7 +880,7 @@ static const LangTag ot_languages[] = {
{"mam", HB_TAG('M','A','M',' ')}, /* Mam */
{"mam", HB_TAG('M','Y','N',' ')}, /* Mam -> Mayan */
{"man", HB_TAG('M','N','K',' ')}, /* Mandingo [macrolanguage] -> Maninka */
- {"map", HB_TAG_NONE }, /* Austronesian [family] != Mapudungun */
+ {"map", HB_TAG_NONE }, /* Austronesian [collection] != Mapudungun */
{"maw", HB_TAG_NONE }, /* Mampruli != Marwari */
{"max", HB_TAG('M','L','Y',' ')}, /* North Moluccan Malay -> Malay */
{"max", HB_TAG('C','P','P',' ')}, /* North Moluccan Malay -> Creoles */
@@ -936,6 +940,7 @@ static const LangTag ot_languages[] = {
{"mnw", HB_TAG('M','O','N','T')}, /* Mon -> Thailand Mon */
{"mnx", HB_TAG_NONE }, /* Manikion != Manx */
{"mo", HB_TAG('M','O','L',' ')}, /* Moldavian (retired code) */
+ {"mo", HB_TAG('R','O','M',' ')}, /* Moldavian (retired code) -> Romanian */
{"mod", HB_TAG('C','P','P',' ')}, /* Mobilian -> Creoles */
/*{"moh", HB_TAG('M','O','H',' ')},*/ /* Mohawk */
{"mok", HB_TAG_NONE }, /* Morori != Moksha */
@@ -958,7 +963,7 @@ static const LangTag ot_languages[] = {
{"mts", HB_TAG_NONE }, /* Yora != Maltese */
{"mud", HB_TAG('C','P','P',' ')}, /* Mednyj Aleut -> Creoles */
{"mui", HB_TAG('M','L','Y',' ')}, /* Musi -> Malay */
- {"mun", HB_TAG_NONE }, /* Munda [family] != Mundari */
+ {"mun", HB_TAG_NONE }, /* Munda [collection] != Mundari */
{"mup", HB_TAG('R','A','J',' ')}, /* Malvi -> Rajasthani */
{"muq", HB_TAG('H','M','N',' ')}, /* Eastern Xiangxi Miao -> Hmong */
/*{"mus", HB_TAG('M','U','S',' ')},*/ /* Creek -> Muscogee */
@@ -973,7 +978,7 @@ static const LangTag ot_languages[] = {
{"mww", HB_TAG('H','M','N',' ')}, /* Hmong Daw -> Hmong */
{"my", HB_TAG('B','R','M',' ')}, /* Burmese */
{"mym", HB_TAG('M','E','N',' ')}, /* Me’en */
-/*{"myn", HB_TAG('M','Y','N',' ')},*/ /* Mayan [family] */
+/*{"myn", HB_TAG('M','Y','N',' ')},*/ /* Mayan [collection] */
{"myq", HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) -> Maninka */
{"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */
{"mzb", HB_TAG('B','B','R',' ')}, /* Tumzabt -> Berber */
@@ -982,7 +987,7 @@ static const LangTag ot_languages[] = {
{"na", HB_TAG('N','A','U',' ')}, /* Nauru -> Nauruan */
{"nag", HB_TAG('N','A','G',' ')}, /* Naga Pidgin -> Naga-Assamese */
{"nag", HB_TAG('C','P','P',' ')}, /* Naga Pidgin -> Creoles */
-/*{"nah", HB_TAG('N','A','H',' ')},*/ /* Nahuatl [family] */
+/*{"nah", HB_TAG('N','A','H',' ')},*/ /* Nahuatl [collection] */
{"nan", HB_TAG('Z','H','S',' ')}, /* Min Nan Chinese -> Chinese, Simplified */
/*{"nap", HB_TAG('N','A','P',' ')},*/ /* Neapolitan */
{"nas", HB_TAG_NONE }, /* Naasioi != Naskapi */
@@ -1039,7 +1044,6 @@ static const LangTag ot_languages[] = {
{"nln", HB_TAG('N','A','H',' ')}, /* Durango Nahuatl (retired code) -> Nahuatl */
{"nlv", HB_TAG('N','A','H',' ')}, /* Orizaba Nahuatl -> Nahuatl */
{"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk (Nynorsk, Norwegian) */
- {"nn", HB_TAG('N','O','R',' ')}, /* Norwegian Nynorsk -> Norwegian */
{"nnh", HB_TAG('B','M','L',' ')}, /* Ngiemboon -> Bamileke */
{"nnz", HB_TAG('B','M','L',' ')}, /* Nda'nda' -> Bamileke */
{"no", HB_TAG('N','O','R',' ')}, /* Norwegian [macrolanguage] */
@@ -1093,7 +1097,7 @@ static const LangTag ot_languages[] = {
{"otw", HB_TAG('O','J','B',' ')}, /* Ottawa -> Ojibway */
{"oua", HB_TAG('B','B','R',' ')}, /* Tagargrent -> Berber */
{"pa", HB_TAG('P','A','N',' ')}, /* Punjabi */
- {"paa", HB_TAG_NONE }, /* Papuan [family] != Palestinian Aramaic */
+ {"paa", HB_TAG_NONE }, /* Papuan [collection] != Palestinian Aramaic */
/*{"pag", HB_TAG('P','A','G',' ')},*/ /* Pangasinan */
{"pal", HB_TAG_NONE }, /* Pahlavi != Pali */
/*{"pam", HB_TAG('P','A','M',' ')},*/ /* Pampanga -> Pampangan */
@@ -1308,6 +1312,9 @@ static const LangTag ot_languages[] = {
{"sgo", HB_TAG_NONE }, /* Songa (retired code) != Sango */
/*{"sgs", HB_TAG('S','G','S',' ')},*/ /* Samogitian */
{"sgw", HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage -> Chaha Gurage */
+ {"sh", HB_TAG('B','O','S',' ')}, /* Serbo-Croatian [macrolanguage] -> Bosnian */
+ {"sh", HB_TAG('H','R','V',' ')}, /* Serbo-Croatian [macrolanguage] -> Croatian */
+ {"sh", HB_TAG('S','R','B',' ')}, /* Serbo-Croatian [macrolanguage] -> Serbian */
{"shi", HB_TAG('S','H','I',' ')}, /* Tachelhit */
{"shi", HB_TAG('B','B','R',' ')}, /* Tachelhit -> Berber */
{"shl", HB_TAG('Q','I','N',' ')}, /* Shendu -> Chin */
@@ -1329,7 +1336,7 @@ static const LangTag ot_languages[] = {
{"skw", HB_TAG('C','P','P',' ')}, /* Skepi Creole Dutch -> Creoles */
{"sky", HB_TAG_NONE }, /* Sikaiana != Slovak */
{"sl", HB_TAG('S','L','V',' ')}, /* Slovenian */
- {"sla", HB_TAG_NONE }, /* Slavic [family] != Slavey */
+ {"sla", HB_TAG_NONE }, /* Slavic [collection] != Slavey */
{"sm", HB_TAG('S','M','O',' ')}, /* Samoan */
{"sma", HB_TAG('S','S','M',' ')}, /* Southern Sami */
{"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */
@@ -1451,7 +1458,7 @@ static const LangTag ot_languages[] = {
{"tpi", HB_TAG('C','P','P',' ')}, /* Tok Pisin -> Creoles */
{"tr", HB_TAG('T','R','K',' ')}, /* Turkish */
{"trf", HB_TAG('C','P','P',' ')}, /* Trinidadian Creole English -> Creoles */
- {"trk", HB_TAG_NONE }, /* Turkic [family] != Turkish */
+ {"trk", HB_TAG_NONE }, /* Turkic [collection] != Turkish */
{"tru", HB_TAG('T','U','A',' ')}, /* Turoyo -> Turoyo Aramaic */
{"tru", HB_TAG('S','Y','R',' ')}, /* Turoyo -> Syriac */
{"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */
@@ -1593,7 +1600,7 @@ static const LangTag ot_languages[] = {
{"zlq", HB_TAG('Z','H','A',' ')}, /* Liuqian Zhuang -> Zhuang */
{"zmi", HB_TAG('M','L','Y',' ')}, /* Negeri Sembilan Malay -> Malay */
{"zmz", HB_TAG('B','A','D','0')}, /* Mbandja -> Banda */
- {"znd", HB_TAG_NONE }, /* Zande [family] != Zande */
+ {"znd", HB_TAG_NONE }, /* Zande [collection] != Zande */
{"zne", HB_TAG('Z','N','D',' ')}, /* Zande */
{"zom", HB_TAG('Q','I','N',' ')}, /* Zou -> Chin */
{"zqe", HB_TAG('Z','H','A',' ')}, /* Qiubei Zhuang -> Zhuang */
@@ -2607,14 +2614,8 @@ hb_ot_tags_from_complex_language (const char *lang_str,
if (0 == strcmp (&lang_str[1], "o-nyn"))
{
/* Norwegian Nynorsk (retired code) */
- unsigned int i;
- hb_tag_t possible_tags[] = {
- HB_TAG('N','Y','N',' '), /* Norwegian Nynorsk (Nynorsk, Norwegian) */
- HB_TAG('N','O','R',' '), /* Norwegian */
- };
- for (i = 0; i < 2 && i < *count; i++)
- tags[i] = possible_tags[i];
- *count = i;
+ tags[0] = HB_TAG('N','Y','N',' '); /* Norwegian Nynorsk (Nynorsk, Norwegian) */
+ *count = 1;
return true;
}
break;
@@ -2623,8 +2624,14 @@ hb_ot_tags_from_complex_language (const char *lang_str,
&& subtag_matches (lang_str, limit, "-md"))
{
/* Romanian; Moldova */
- tags[0] = HB_TAG('M','O','L',' '); /* Moldavian */
- *count = 1;
+ unsigned int i;
+ hb_tag_t possible_tags[] = {
+ HB_TAG('M','O','L',' '), /* Moldavian */
+ HB_TAG('R','O','M',' '), /* Romanian */
+ };
+ for (i = 0; i < 2 && i < *count; i++)
+ tags[i] = possible_tags[i];
+ *count = i;
return true;
}
break;
@@ -2813,15 +2820,15 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
case HB_TAG('A','R','K',' '): /* Rakhine */
return hb_language_from_string ("rki", -1); /* Rakhine */
case HB_TAG('A','T','H',' '): /* Athapaskan */
- return hb_language_from_string ("ath", -1); /* Athapascan [family] */
+ return hb_language_from_string ("ath", -1); /* Athapascan [collection] */
case HB_TAG('B','B','R',' '): /* Berber */
- return hb_language_from_string ("ber", -1); /* Berber [family] */
+ return hb_language_from_string ("ber", -1); /* Berber [collection] */
case HB_TAG('B','I','K',' '): /* Bikol */
return hb_language_from_string ("bik", -1); /* Bikol [macrolanguage] */
case HB_TAG('B','T','K',' '): /* Batak */
- return hb_language_from_string ("btk", -1); /* Batak [family] */
+ return hb_language_from_string ("btk", -1); /* Batak [collection] */
case HB_TAG('C','P','P',' '): /* Creoles */
- return hb_language_from_string ("crp", -1); /* Creoles and pidgins [family] */
+ return hb_language_from_string ("crp", -1); /* Creoles and pidgins [collection] */
case HB_TAG('C','R','R',' '): /* Carrier */
return hb_language_from_string ("crx", -1); /* Carrier */
case HB_TAG('D','G','R',' '): /* Dogri (macrolanguage) */
@@ -2838,6 +2845,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
return hb_language_from_string ("fa", -1); /* Persian [macrolanguage] */
case HB_TAG('G','O','N',' '): /* Gondi */
return hb_language_from_string ("gon", -1); /* Gondi [macrolanguage] */
+ case HB_TAG('H','M','A',' '): /* High Mari */
+ return hb_language_from_string ("mrj", -1); /* Western Mari */
case HB_TAG('H','M','N',' '): /* Hmong */
return hb_language_from_string ("hmn", -1); /* Hmong [macrolanguage] */
case HB_TAG('H','N','D',' '): /* Hindko */
@@ -2847,7 +2856,7 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
case HB_TAG('I','B','A',' '): /* Iban */
return hb_language_from_string ("iba", -1); /* Iban */
case HB_TAG('I','J','O',' '): /* Ijo */
- return hb_language_from_string ("ijo", -1); /* Ijo [family] */
+ return hb_language_from_string ("ijo", -1); /* Ijo [collection] */
case HB_TAG('I','N','U',' '): /* Inuktitut */
return hb_language_from_string ("iu", -1); /* Inuktitut [macrolanguage] */
case HB_TAG('I','P','K',' '): /* Inupiat */
@@ -2873,11 +2882,13 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
case HB_TAG('K','P','L',' '): /* Kpelle */
return hb_language_from_string ("kpe", -1); /* Kpelle [macrolanguage] */
case HB_TAG('K','R','N',' '): /* Karen */
- return hb_language_from_string ("kar", -1); /* Karen [family] */
+ return hb_language_from_string ("kar", -1); /* Karen [collection] */
case HB_TAG('K','U','I',' '): /* Kui */
return hb_language_from_string ("uki", -1); /* Kui (India) */
case HB_TAG('K','U','R',' '): /* Kurdish */
return hb_language_from_string ("ku", -1); /* Kurdish [macrolanguage] */
+ case HB_TAG('L','M','A',' '): /* Low Mari */
+ return hb_language_from_string ("mhr", -1); /* Eastern Mari */
case HB_TAG('L','U','H',' '): /* Luyia */
return hb_language_from_string ("luy", -1); /* Luyia [macrolanguage] */
case HB_TAG('L','V','I',' '): /* Latvian */
@@ -2897,9 +2908,9 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
case HB_TAG('M','O','N','T'): /* Thailand Mon */
return hb_language_from_string ("mnw-TH", -1); /* Mon; Thailand */
case HB_TAG('M','Y','N',' '): /* Mayan */
- return hb_language_from_string ("myn", -1); /* Mayan [family] */
+ return hb_language_from_string ("myn", -1); /* Mayan [collection] */
case HB_TAG('N','A','H',' '): /* Nahuatl */
- return hb_language_from_string ("nah", -1); /* Nahuatl [family] */
+ return hb_language_from_string ("nah", -1); /* Nahuatl [collection] */
case HB_TAG('N','E','P',' '): /* Nepali */
return hb_language_from_string ("ne", -1); /* Nepali [macrolanguage] */
case HB_TAG('N','I','S',' '): /* Nisi */
@@ -2926,6 +2937,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
return hb_language_from_string ("qwh", -1); /* Huaylas Ancash Quechua */
case HB_TAG('R','A','J',' '): /* Rajasthani */
return hb_language_from_string ("raj", -1); /* Rajasthani [macrolanguage] */
+ case HB_TAG('R','O','M',' '): /* Romanian */
+ return hb_language_from_string ("ro", -1); /* Romanian */
case HB_TAG('R','O','Y',' '): /* Romany */
return hb_language_from_string ("rom", -1); /* Romany [macrolanguage] */
case HB_TAG('S','Q','I',' '): /* Albanian */
diff --git a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh
index 05f289db26..e066558683 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh
@@ -263,7 +263,7 @@ struct fvar
if (coords_length && *coords_length)
{
hb_array_t<const HBFixed> instanceCoords = instance->get_coordinates (axisCount)
- .sub_array (0, *coords_length);
+ .sub_array (0, coords_length);
for (unsigned int i = 0; i < instanceCoords.length; i++)
coords[i] = instanceCoords.arrayZ[i].to_float ();
}
diff --git a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh
index 49b5532d40..539213c339 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh
@@ -399,7 +399,7 @@ struct gvar
get_offset (glyphCount) - get_offset (0)));
}
- /* GlyphVariationData not sanitized here; must be checked while accessing each glyph varation data */
+ /* GlyphVariationData not sanitized here; must be checked while accessing each glyph variation data */
bool sanitize (hb_sanitize_context_t *c) const
{ return sanitize_shallow (c); }
@@ -498,9 +498,9 @@ struct gvar
public:
struct accelerator_t
{
- void init (hb_face_t *face)
+ accelerator_t (hb_face_t *face)
{ table = hb_sanitize_context_t ().reference_table<gvar> (face); }
- void fini () { table.destroy (); }
+ ~accelerator_t () { table.destroy (); }
private:
struct x_getter { static float get (const contour_point_t &p) { return p.x; } };
@@ -698,7 +698,9 @@ no_more_gaps:
DEFINE_SIZE_MIN (20);
};
-struct gvar_accelerator_t : gvar::accelerator_t {};
+struct gvar_accelerator_t : gvar::accelerator_t {
+ gvar_accelerator_t (hb_face_t *face) : gvar::accelerator_t (face) {}
+};
} /* namespace OT */
diff --git a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh
index 074b6a3785..e9d90352f0 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh
@@ -177,9 +177,6 @@ struct hvarvvar_subset_plan_t
inner_maps.resize (var_store->get_sub_table_count ());
- for (unsigned int i = 0; i < inner_maps.length; i++)
- inner_maps[i].init ();
-
if (unlikely (!index_map_plans.length || !inner_sets.length || !inner_maps.length)) return;
bool retain_adv_map = false;
@@ -229,8 +226,8 @@ struct hvarvvar_subset_plan_t
for (unsigned int i = 0; i < inner_sets.length; i++)
hb_set_destroy (inner_sets[i]);
hb_set_destroy (adv_set);
- inner_maps.fini_deep ();
- index_map_plans.fini_deep ();
+ inner_maps.fini ();
+ index_map_plans.fini ();
}
hb_inc_bimap_t outer_map;
diff --git a/thirdparty/harfbuzz/src/hb-ot-var.cc b/thirdparty/harfbuzz/src/hb-ot-var.cc
index 6b42b45cd9..0376e26b4a 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-var.cc
@@ -303,6 +303,9 @@ hb_ot_var_normalize_variations (hb_face_t *face,
* values for the axis are mapped to the interval [-1,1], with the default
* axis value mapped to 0.
*
+ * The normalized values have 14 bits of fixed-point sub-integer precision as per
+ * OpenType specification.
+ *
* Any additional scaling defined in the face's `avar` table is also
* applied, as described at https://docs.microsoft.com/en-us/typography/opentype/spec/avar
*
diff --git a/thirdparty/harfbuzz/src/hb-ot-var.h b/thirdparty/harfbuzz/src/hb-ot-var.h
index ce201d3b4f..05147cc25e 100644
--- a/thirdparty/harfbuzz/src/hb-ot-var.h
+++ b/thirdparty/harfbuzz/src/hb-ot-var.h
@@ -109,7 +109,7 @@ typedef enum { /*< flags >*/
* @tag: The #hb_tag_t tag identifying the design variation of the axis
* @name_id: The `name` table Name ID that provides display names for the axis
* @flags: The #hb_ot_var_axis_flags_t flags for the axis
- * @min_value: The mininum value on the variation axis that the font covers
+ * @min_value: The minimum value on the variation axis that the font covers
* @default_value: The position on the variation axis corresponding to the font's defaults
* @max_value: The maximum value on the variation axis that the font covers
*
diff --git a/thirdparty/harfbuzz/src/hb-repacker.hh b/thirdparty/harfbuzz/src/hb-repacker.hh
index 5c46b4cccc..b1726d8beb 100644
--- a/thirdparty/harfbuzz/src/hb-repacker.hh
+++ b/thirdparty/harfbuzz/src/hb-repacker.hh
@@ -42,26 +42,13 @@ struct graph_t
{
struct vertex_t
{
- vertex_t () :
- distance (0),
- space (0),
- parents (),
- start (0),
- end (0),
- priority(0) {}
-
- void fini () {
- obj.fini ();
- parents.fini ();
- }
-
hb_serialize_context_t::object_t obj;
- int64_t distance;
- int64_t space;
+ int64_t distance = 0 ;
+ int64_t space = 0 ;
hb_vector_t<unsigned> parents;
- unsigned start;
- unsigned end;
- unsigned priority;
+ unsigned start = 0;
+ unsigned end = 0;
+ unsigned priority = 0;
bool is_shared () const
{
@@ -186,7 +173,7 @@ struct graph_t
~graph_t ()
{
- vertices_.fini_deep ();
+ vertices_.fini ();
}
bool in_error () const
@@ -309,7 +296,7 @@ struct graph_t
remap_all_obj_indices (id_map, &sorted_graph);
hb_swap (vertices_, sorted_graph);
- sorted_graph.fini_deep ();
+ sorted_graph.fini ();
}
/*
@@ -369,7 +356,7 @@ struct graph_t
remap_all_obj_indices (id_map, &sorted_graph);
hb_swap (vertices_, sorted_graph);
- sorted_graph.fini_deep ();
+ sorted_graph.fini ();
}
/*
@@ -402,11 +389,15 @@ struct graph_t
while (roots)
{
unsigned next = HB_SET_VALUE_INVALID;
+ if (unlikely (!check_success (!roots.in_error ()))) break;
if (!roots.next (&next)) break;
hb_set_t connected_roots;
find_connected_nodes (next, roots, visited, connected_roots);
+ if (unlikely (!check_success (!connected_roots.in_error ()))) break;
+
isolate_subgraph (connected_roots);
+ if (unlikely (!check_success (!connected_roots.in_error ()))) break;
unsigned next_space = this->next_space ();
num_roots_for_space_.push (0);
@@ -423,6 +414,8 @@ struct graph_t
// into the 32 bit space as needed, instead of using isolation.
}
+
+
return true;
}
@@ -865,7 +858,7 @@ struct graph_t
// Redundant ones are filtered out later on by the visited set.
// According to https://www3.cs.stonybrook.edu/~rezaul/papers/TR-07-54.pdf
// for practical performance this is faster then using a more advanced queue
- // (such as a fibonaacci queue) with a fast decrease priority.
+ // (such as a fibonacci queue) with a fast decrease priority.
for (unsigned i = 0; i < vertices_.length; i++)
{
if (i == vertices_.length - 1)
@@ -1074,6 +1067,7 @@ struct graph_t
hb_set_t& visited,
hb_set_t& connected)
{
+ if (unlikely (!check_success (!visited.in_error ()))) return;
if (visited.has (start_idx)) return;
visited.add (start_idx);
diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh
index 823c0be8b5..6615f033c5 100644
--- a/thirdparty/harfbuzz/src/hb-serialize.hh
+++ b/thirdparty/harfbuzz/src/hb-serialize.hh
@@ -279,7 +279,7 @@ struct hb_serialize_context_t
object_pool.release (obj);
}
- /* Set share to false when an object is unlikely sharable with others
+ /* Set share to false when an object is unlikely shareable with others
* so not worth an attempt, or a contiguous table is serialized as
* multiple consecutive objects in the reverse order so can't be shared.
*/
@@ -381,7 +381,7 @@ struct hb_serialize_context_t
// Adding a virtual link from object a to object b will ensure that object b is always packed after
// object a in the final serialized order.
//
- // This is useful in certain situtations where there needs to be a specific ordering in the
+ // This is useful in certain situations where there needs to be a specific ordering in the
// final serialization. Such as when platform bugs require certain orderings, or to provide
// guidance to the repacker for better offset overflow resolution.
void add_virtual_link (objidx_t objidx)
@@ -510,7 +510,7 @@ struct hb_serialize_context_t
{ return reinterpret_cast<Type *> (this->head); }
template <typename Type>
Type *start_embed (const Type &obj) const
- { return start_embed (hb_addressof (obj)); }
+ { return start_embed (std::addressof (obj)); }
bool err (hb_serialize_error_t err_type)
{
@@ -548,7 +548,7 @@ struct hb_serialize_context_t
}
template <typename Type>
Type *embed (const Type &obj)
- { return embed (hb_addressof (obj)); }
+ { return embed (std::addressof (obj)); }
template <typename Type, typename ...Ts> auto
_copy (const Type &src, hb_priority<1>, Ts&&... ds) HB_RETURN
@@ -595,19 +595,19 @@ struct hb_serialize_context_t
}
template <typename Type>
Type *extend_size (Type &obj, size_t size)
- { return extend_size (hb_addressof (obj), size); }
+ { return extend_size (std::addressof (obj), size); }
template <typename Type>
Type *extend_min (Type *obj) { return extend_size (obj, obj->min_size); }
template <typename Type>
- Type *extend_min (Type &obj) { return extend_min (hb_addressof (obj)); }
+ Type *extend_min (Type &obj) { return extend_min (std::addressof (obj)); }
template <typename Type, typename ...Ts>
Type *extend (Type *obj, Ts&&... ds)
{ return extend_size (obj, obj->get_size (std::forward<Ts> (ds)...)); }
template <typename Type, typename ...Ts>
Type *extend (Type &obj, Ts&&... ds)
- { return extend (hb_addressof (obj), std::forward<Ts> (ds)...); }
+ { return extend (std::addressof (obj), std::forward<Ts> (ds)...); }
/* Output routines. */
hb_bytes_t copy_bytes () const
diff --git a/thirdparty/harfbuzz/src/hb-style.cc b/thirdparty/harfbuzz/src/hb-style.cc
index f1b44cea53..c0c5c4832c 100644
--- a/thirdparty/harfbuzz/src/hb-style.cc
+++ b/thirdparty/harfbuzz/src/hb-style.cc
@@ -48,13 +48,12 @@ _hb_angle_to_ratio (float a)
{
return tanf (a * float (M_PI / 180.));
}
-#if 0
+
static inline float
_hb_ratio_to_angle (float r)
{
return atanf (r) * float (180. / M_PI);
}
-#endif
/**
* hb_style_get_value:
@@ -73,7 +72,8 @@ float
hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag)
{
if (unlikely (style_tag == HB_STYLE_TAG_SLANT_RATIO))
- return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE));
+ return _hb_angle_to_ratio (hb_style_get_value (font, HB_STYLE_TAG_SLANT_ANGLE))
+ + font->slant;
hb_face_t *face = font->face;
@@ -109,7 +109,14 @@ hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag)
: 12.f;
}
case HB_STYLE_TAG_SLANT_ANGLE:
- return face->table.post->table->italicAngle.to_float ();
+ {
+ float angle = face->table.post->table->italicAngle.to_float ();
+
+ if (font->slant)
+ angle = _hb_ratio_to_angle (font->slant + _hb_angle_to_ratio (angle));
+
+ return angle;
+ }
case HB_STYLE_TAG_WIDTH:
return face->table.OS2->has_data ()
? face->table.OS2->get_width ()
diff --git a/thirdparty/harfbuzz/src/hb-subset-cff-common.hh b/thirdparty/harfbuzz/src/hb-subset-cff-common.hh
index 7fd96ca86d..18657705fa 100644
--- a/thirdparty/harfbuzz/src/hb-subset-cff-common.hh
+++ b/thirdparty/harfbuzz/src/hb-subset-cff-common.hh
@@ -275,60 +275,36 @@ struct subr_flattener_t
struct subr_closures_t
{
- subr_closures_t () : valid (false), global_closure (nullptr)
- { local_closures.init (); }
-
- void init (unsigned int fd_count)
+ subr_closures_t (unsigned int fd_count) : valid (false), global_closure (), local_closures ()
{
valid = true;
- global_closure = hb_set_create ();
- if (global_closure == hb_set_get_empty ())
- valid = false;
if (!local_closures.resize (fd_count))
valid = false;
-
- for (unsigned int i = 0; i < local_closures.length; i++)
- {
- local_closures[i] = hb_set_create ();
- if (local_closures[i] == hb_set_get_empty ())
- valid = false;
- }
- }
-
- void fini ()
- {
- hb_set_destroy (global_closure);
- for (unsigned int i = 0; i < local_closures.length; i++)
- hb_set_destroy (local_closures[i]);
- local_closures.fini ();
}
void reset ()
{
- hb_set_clear (global_closure);
+ global_closure.clear();
for (unsigned int i = 0; i < local_closures.length; i++)
- hb_set_clear (local_closures[i]);
+ local_closures[i].clear();
}
bool is_valid () const { return valid; }
bool valid;
- hb_set_t *global_closure;
- hb_vector_t<hb_set_t *> local_closures;
+ hb_set_t global_closure;
+ hb_vector_t<hb_set_t> local_closures;
};
struct parsed_cs_op_t : op_str_t
{
void init (unsigned int subr_num_ = 0)
{
- op_str_t::init ();
subr_num = subr_num_;
drop_flag = false;
keep_flag = false;
skip_flag = false;
}
- void fini () { op_str_t::fini (); }
-
bool for_drop () const { return drop_flag; }
void set_drop () { if (!for_keep ()) drop_flag = true; }
@@ -416,16 +392,6 @@ struct parsed_cs_str_t : parsed_values_t<parsed_cs_op_t>
struct parsed_cs_str_vec_t : hb_vector_t<parsed_cs_str_t>
{
- void init (unsigned int len_ = 0)
- {
- SUPER::init ();
- if (unlikely (!resize (len_)))
- return;
- for (unsigned int i = 0; i < length; i++)
- (*this)[i].init ();
- }
- void fini () { SUPER::fini_deep (); }
-
private:
typedef hb_vector_t<parsed_cs_str_t> SUPER;
};
@@ -496,7 +462,7 @@ struct subr_subset_param_t
struct subr_remap_t : hb_inc_bimap_t
{
- void create (hb_set_t *closure)
+ void create (const hb_set_t *closure)
{
/* create a remapping of subroutine numbers from old to new.
* no optimization based on usage counts. fonttools doesn't appear doing that either.
@@ -526,19 +492,9 @@ struct subr_remap_t : hb_inc_bimap_t
struct subr_remaps_t
{
- subr_remaps_t ()
+ subr_remaps_t (unsigned int fdCount)
{
- global_remap.init ();
- local_remaps.init ();
- }
-
- ~subr_remaps_t () { fini (); }
-
- void init (unsigned int fdCount)
- {
- if (unlikely (!local_remaps.resize (fdCount))) return;
- for (unsigned int i = 0; i < fdCount; i++)
- local_remaps[i].init ();
+ local_remaps.resize (fdCount);
}
bool in_error()
@@ -548,15 +504,9 @@ struct subr_remaps_t
void create (subr_closures_t& closures)
{
- global_remap.create (closures.global_closure);
+ global_remap.create (&closures.global_closure);
for (unsigned int i = 0; i < local_remaps.length; i++)
- local_remaps[i].create (closures.local_closures[i]);
- }
-
- void fini ()
- {
- global_remap.fini ();
- local_remaps.fini_deep ();
+ local_remaps[i].create (&closures.local_closures[i]);
}
subr_remap_t global_remap;
@@ -567,21 +517,8 @@ template <typename SUBSETTER, typename SUBRS, typename ACC, typename ENV, typena
struct subr_subsetter_t
{
subr_subsetter_t (ACC &acc_, const hb_subset_plan_t *plan_)
- : acc (acc_), plan (plan_)
- {
- parsed_charstrings.init ();
- parsed_global_subrs.init ();
- parsed_local_subrs.init ();
- }
-
- ~subr_subsetter_t ()
- {
- closures.fini ();
- remaps.fini ();
- parsed_charstrings.fini_deep ();
- parsed_global_subrs.fini_deep ();
- parsed_local_subrs.fini_deep ();
- }
+ : acc (acc_), plan (plan_), closures(acc_.fdCount), remaps(acc_.fdCount)
+ {}
/* Subroutine subsetting with --no-desubroutinize runs in phases:
*
@@ -599,11 +536,8 @@ struct subr_subsetter_t
*/
bool subset (void)
{
- closures.init (acc.fdCount);
- remaps.init (acc.fdCount);
-
- parsed_charstrings.init (plan->num_output_glyphs ());
- parsed_global_subrs.init (acc.globalSubrs->count);
+ parsed_charstrings.resize (plan->num_output_glyphs ());
+ parsed_global_subrs.resize (acc.globalSubrs->count);
if (unlikely (remaps.in_error()
|| parsed_charstrings.in_error ()
@@ -615,7 +549,7 @@ struct subr_subsetter_t
for (unsigned int i = 0; i < acc.fdCount; i++)
{
- parsed_local_subrs[i].init (acc.privateDicts[i].localSubrs->count);
+ parsed_local_subrs[i].resize (acc.privateDicts[i].localSubrs->count);
if (unlikely (parsed_local_subrs[i].in_error ())) return false;
}
if (unlikely (!closures.valid))
@@ -638,7 +572,7 @@ struct subr_subsetter_t
subr_subset_param_t param;
param.init (&parsed_charstrings[i],
&parsed_global_subrs, &parsed_local_subrs[fd],
- closures.global_closure, closures.local_closures[fd],
+ &closures.global_closure, &closures.local_closures[fd],
plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
if (unlikely (!interp.interpret (param)))
@@ -662,7 +596,7 @@ struct subr_subsetter_t
subr_subset_param_t param;
param.init (&parsed_charstrings[i],
&parsed_global_subrs, &parsed_local_subrs[fd],
- closures.global_closure, closures.local_closures[fd],
+ &closures.global_closure, &closures.local_closures[fd],
plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
drop_hints_param_t drop;
@@ -687,7 +621,7 @@ struct subr_subsetter_t
subr_subset_param_t param;
param.init (&parsed_charstrings[i],
&parsed_global_subrs, &parsed_local_subrs[fd],
- closures.global_closure, closures.local_closures[fd],
+ &closures.global_closure, &closures.local_closures[fd],
plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
collect_subr_refs_in_str (parsed_charstrings[i], param);
}
diff --git a/thirdparty/harfbuzz/src/hb-subset-cff1.cc b/thirdparty/harfbuzz/src/hb-subset-cff1.cc
index b4e24122c9..35fecd67bc 100644
--- a/thirdparty/harfbuzz/src/hb-subset-cff1.cc
+++ b/thirdparty/harfbuzz/src/hb-subset-cff1.cc
@@ -362,43 +362,11 @@ struct cff1_subr_subsetter_t : subr_subsetter_t<cff1_subr_subsetter_t, CFF1Subrs
struct cff_subset_plan {
cff_subset_plan ()
- : info (),
- orig_fdcount (0),
- subset_fdcount (1),
- subset_fdselect_format (0),
- drop_hints (false),
- desubroutinize(false)
{
- topdict_mod.init ();
- subset_fdselect_ranges.init ();
- fdmap.init ();
- subset_charstrings.init ();
- subset_globalsubrs.init ();
- subset_localsubrs.init ();
- fontdicts_mod.init ();
- subset_enc_code_ranges.init ();
- subset_enc_supp_codes.init ();
- subset_charset_ranges.init ();
- sidmap.init ();
for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++)
topDictModSIDs[i] = CFF_UNDEF_SID;
}
- ~cff_subset_plan ()
- {
- topdict_mod.fini ();
- subset_fdselect_ranges.fini ();
- fdmap.fini ();
- subset_charstrings.fini_deep ();
- subset_globalsubrs.fini_deep ();
- subset_localsubrs.fini_deep ();
- fontdicts_mod.fini ();
- subset_enc_code_ranges.fini ();
- subset_enc_supp_codes.fini ();
- subset_charset_ranges.fini ();
- sidmap.fini ();
- }
-
void plan_subset_encoding (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan)
{
const Encoding *encoding = acc.encoding;
@@ -672,9 +640,9 @@ struct cff_subset_plan {
cff1_sub_table_info_t info;
unsigned int num_glyphs;
- unsigned int orig_fdcount;
- unsigned int subset_fdcount;
- unsigned int subset_fdselect_format;
+ unsigned int orig_fdcount = 0;
+ unsigned int subset_fdcount = 1;
+ unsigned int subset_fdselect_format = 0;
hb_vector_t<code_pair_t> subset_fdselect_ranges;
/* font dict index remap table from fullset FDArray to subset FDArray.
@@ -686,7 +654,7 @@ struct cff_subset_plan {
hb_vector_t<str_buff_vec_t> subset_localsubrs;
hb_vector_t<cff1_font_dict_values_mod_t> fontdicts_mod;
- bool drop_hints;
+ bool drop_hints = false;
bool gid_renum;
bool subset_encoding;
@@ -702,7 +670,7 @@ struct cff_subset_plan {
remap_sid_t sidmap;
unsigned int topDictModSIDs[name_dict_values_t::ValCount];
- bool desubroutinize;
+ bool desubroutinize = false;
};
static bool _serialize_cff1 (hb_serialize_context_t *c,
diff --git a/thirdparty/harfbuzz/src/hb-subset-cff2.cc b/thirdparty/harfbuzz/src/hb-subset-cff2.cc
index 896ae64016..92dd6b1d2c 100644
--- a/thirdparty/harfbuzz/src/hb-subset-cff2.cc
+++ b/thirdparty/harfbuzz/src/hb-subset-cff2.cc
@@ -233,29 +233,6 @@ struct cff2_subr_subsetter_t : subr_subsetter_t<cff2_subr_subsetter_t, CFF2Subrs
};
struct cff2_subset_plan {
- cff2_subset_plan ()
- : orig_fdcount (0),
- subset_fdcount(1),
- subset_fdselect_size (0),
- subset_fdselect_format (0),
- drop_hints (false),
- desubroutinize (false)
- {
- subset_fdselect_ranges.init ();
- fdmap.init ();
- subset_charstrings.init ();
- subset_globalsubrs.init ();
- subset_localsubrs.init ();
- }
-
- ~cff2_subset_plan ()
- {
- subset_fdselect_ranges.fini ();
- fdmap.fini ();
- subset_charstrings.fini_deep ();
- subset_globalsubrs.fini_deep ();
- subset_localsubrs.fini_deep ();
- }
bool create (const OT::cff2::accelerator_subset_t &acc,
hb_subset_plan_t *plan)
@@ -320,10 +297,10 @@ struct cff2_subset_plan {
cff2_sub_table_info_t info;
- unsigned int orig_fdcount;
- unsigned int subset_fdcount;
- unsigned int subset_fdselect_size;
- unsigned int subset_fdselect_format;
+ unsigned int orig_fdcount = 0;
+ unsigned int subset_fdcount = 1;
+ unsigned int subset_fdselect_size = 0;
+ unsigned int subset_fdselect_format = 0;
hb_vector_t<code_pair_t> subset_fdselect_ranges;
hb_inc_bimap_t fdmap;
@@ -332,8 +309,8 @@ struct cff2_subset_plan {
str_buff_vec_t subset_globalsubrs;
hb_vector_t<str_buff_vec_t> subset_localsubrs;
- bool drop_hints;
- bool desubroutinize;
+ bool drop_hints = false;
+ bool desubroutinize = false;
};
static bool _serialize_cff2 (hb_serialize_context_t *c,
@@ -473,12 +450,8 @@ _hb_subset_cff2 (const OT::cff2::accelerator_subset_t &acc,
bool
hb_subset_cff2 (hb_subset_context_t *c)
{
- OT::cff2::accelerator_subset_t acc;
- acc.init (c->plan->source);
- bool result = likely (acc.is_valid ()) && _hb_subset_cff2 (acc, c);
- acc.fini ();
-
- return result;
+ OT::cff2::accelerator_subset_t acc (c->plan->source);
+ return acc.is_valid () && _hb_subset_cff2 (acc, c);
}
#endif
diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc
index 883ab82093..af4fcb8137 100644
--- a/thirdparty/harfbuzz/src/hb-subset-plan.cc
+++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc
@@ -228,10 +228,8 @@ _cmap_closure (hb_face_t *face,
const hb_set_t *unicodes,
hb_set_t *glyphset)
{
- OT::cmap::accelerator_t cmap;
- cmap.init (face);
+ OT::cmap::accelerator_t cmap (face);
cmap.table->closure_glyphs (unicodes, glyphset);
- cmap.fini ();
}
static void _colr_closure (hb_face_t *face,
@@ -239,8 +237,7 @@ static void _colr_closure (hb_face_t *face,
hb_map_t *palettes_map,
hb_set_t *glyphs_colred)
{
- OT::COLR::accelerator_t colr;
- colr.init (face);
+ OT::COLR::accelerator_t colr (face);
if (!colr.is_valid ()) return;
unsigned iteration_count = 0;
@@ -263,7 +260,6 @@ static void _colr_closure (hb_face_t *face,
colr.closure_V0palette_indices (glyphs_colred, &palette_indices);
_remap_indexes (&layer_indices, layers_map);
_remap_palette_indexes (&palette_indices, palettes_map);
- colr.fini ();
}
static inline void
@@ -294,8 +290,7 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes,
const hb_set_t *glyphs,
hb_subset_plan_t *plan)
{
- OT::cmap::accelerator_t cmap;
- cmap.init (plan->source);
+ OT::cmap::accelerator_t cmap (plan->source);
constexpr static const int size_threshold = 4096;
@@ -343,8 +338,6 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes,
+ plan->codepoint_to_glyph->keys () | hb_sink (plan->unicodes);
+ plan->codepoint_to_glyph->values () | hb_sink (plan->_glyphset_gsub);
-
- cmap.fini ();
}
static void
@@ -353,13 +346,9 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
bool close_over_gpos,
bool close_over_gdef)
{
- OT::glyf::accelerator_t glyf;
-#ifndef HB_NO_SUBSET_CFF
- OT::cff1::accelerator_t cff;
-#endif
- glyf.init (plan->source);
+ OT::glyf::accelerator_t glyf (plan->source);
#ifndef HB_NO_SUBSET_CFF
- cff.init (plan->source);
+ OT::cff1::accelerator_t cff (plan->source);
#endif
plan->_glyphset_gsub->add (0); // Not-def
@@ -419,11 +408,6 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
plan->layout_variation_indices,
plan->layout_variation_idx_map);
#endif
-
-#ifndef HB_NO_SUBSET_CFF
- cff.fini ();
-#endif
- glyf.fini ();
}
static void
diff --git a/thirdparty/harfbuzz/src/hb-uniscribe.cc b/thirdparty/harfbuzz/src/hb-uniscribe.cc
index 0e5a114f7d..50f71ce9ce 100644
--- a/thirdparty/harfbuzz/src/hb-uniscribe.cc
+++ b/thirdparty/harfbuzz/src/hb-uniscribe.cc
@@ -878,7 +878,8 @@ retry:
if (backward)
hb_buffer_reverse (buffer);
- buffer->clear_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_BREAK);
+ buffer->clear_glyph_flags ();
+ buffer->unsafe_to_break ();
/* Wow, done! */
return true;
diff --git a/thirdparty/harfbuzz/src/hb-vector.hh b/thirdparty/harfbuzz/src/hb-vector.hh
index b0a1e5e966..6c7d32e49d 100644
--- a/thirdparty/harfbuzz/src/hb-vector.hh
+++ b/thirdparty/harfbuzz/src/hb-vector.hh
@@ -32,11 +32,14 @@
#include "hb-null.hh"
-template <typename Type>
-struct hb_vector_t
+template <typename Type,
+ bool sorted=false>
+struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty_t>::type
{
typedef Type item_t;
static constexpr unsigned item_size = hb_static_size (Type);
+ using array_t = typename std::conditional<sorted, hb_sorted_array_t<Type>, hb_array_t<Type>>::type;
+ using c_array_t = typename std::conditional<sorted, hb_sorted_array_t<const Type>, hb_array_t<const Type>>::type;
hb_vector_t () = default;
hb_vector_t (std::initializer_list<Type> lst) : hb_vector_t ()
@@ -82,16 +85,10 @@ struct hb_vector_t
void fini ()
{
+ shrink_vector (0);
hb_free (arrayZ);
init ();
}
- void fini_deep ()
- {
- unsigned int count = length;
- for (unsigned int i = 0; i < count; i++)
- arrayZ[i].fini ();
- fini ();
- }
void reset ()
{
@@ -152,24 +149,24 @@ struct hb_vector_t
template <typename T>
hb_vector_t& operator << (T&& v) { push (std::forward<T> (v)); return *this; }
- hb_array_t< Type> as_array () { return hb_array (arrayZ, length); }
- hb_array_t<const Type> as_array () const { return hb_array (arrayZ, length); }
+ array_t as_array () { return hb_array (arrayZ, length); }
+ c_array_t as_array () const { return hb_array (arrayZ, length); }
/* Iterator. */
- typedef hb_array_t<const Type> iter_t;
- typedef hb_array_t< Type> writer_t;
+ typedef c_array_t iter_t;
+ typedef array_t writer_t;
iter_t iter () const { return as_array (); }
writer_t writer () { return as_array (); }
operator iter_t () const { return iter (); }
operator writer_t () { return writer (); }
- hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
+ c_array_t sub_array (unsigned int start_offset, unsigned int count) const
{ return as_array ().sub_array (start_offset, count); }
- hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
+ c_array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
{ return as_array ().sub_array (start_offset, count); }
- hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
+ array_t sub_array (unsigned int start_offset, unsigned int count)
{ return as_array ().sub_array (start_offset, count); }
- hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
+ array_t sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
{ return as_array ().sub_array (start_offset, count); }
hb_sorted_array_t<Type> as_sorted_array ()
@@ -192,6 +189,7 @@ struct hb_vector_t
template <typename T>
Type *push (T&& v)
{
+ /* TODO Emplace? */
Type *p = push ();
if (p == &Crap (Type))
// If push failed to allocate then don't copy v, since this may cause
@@ -204,6 +202,92 @@ struct hb_vector_t
bool in_error () const { return allocated < 0; }
+ template <typename T = Type,
+ hb_enable_if (std::is_trivially_copy_assignable<T>::value)>
+ Type *
+ realloc_vector (unsigned new_allocated)
+ {
+ return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type));
+ }
+ template <typename T = Type,
+ hb_enable_if (!std::is_trivially_copy_assignable<T>::value)>
+ Type *
+ realloc_vector (unsigned new_allocated)
+ {
+ Type *new_array = (Type *) hb_malloc (new_allocated * sizeof (Type));
+ if (likely (new_array))
+ {
+ for (unsigned i = 0; i < length; i++)
+ new (std::addressof (new_array[i])) Type ();
+ for (unsigned i = 0; i < (unsigned) length; i++)
+ new_array[i] = std::move (arrayZ[i]);
+ unsigned old_length = length;
+ shrink_vector (0);
+ length = old_length;
+ hb_free (arrayZ);
+ }
+ return new_array;
+ }
+
+ template <typename T = Type,
+ hb_enable_if (std::is_trivially_constructible<T>::value ||
+ !std::is_default_constructible<T>::value)>
+ void
+ grow_vector (unsigned size)
+ {
+ memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
+ length = size;
+ }
+ template <typename T = Type,
+ hb_enable_if (!std::is_trivially_constructible<T>::value &&
+ std::is_default_constructible<T>::value)>
+ void
+ grow_vector (unsigned size)
+ {
+ while (length < size)
+ {
+ length++;
+ new (std::addressof (arrayZ[length - 1])) Type ();
+ }
+ }
+
+ template <typename T = Type,
+ hb_enable_if (std::is_trivially_destructible<T>::value)>
+ void
+ shrink_vector (unsigned size)
+ {
+ length = size;
+ }
+ template <typename T = Type,
+ hb_enable_if (!std::is_trivially_destructible<T>::value)>
+ void
+ shrink_vector (unsigned size)
+ {
+ while ((unsigned) length > size)
+ {
+ arrayZ[(unsigned) length - 1].~Type ();
+ length--;
+ }
+ }
+
+ template <typename T = Type,
+ hb_enable_if (std::is_trivially_copy_assignable<T>::value)>
+ void
+ shift_down_vector (unsigned i)
+ {
+ memmove (static_cast<void *> (&arrayZ[i - 1]),
+ static_cast<void *> (&arrayZ[i]),
+ (length - i) * sizeof (Type));
+ }
+ template <typename T = Type,
+ hb_enable_if (!std::is_trivially_copy_assignable<T>::value)>
+ void
+ shift_down_vector (unsigned i)
+ {
+ for (; i < length; i++)
+ arrayZ[i - 1] = std::move (arrayZ[i]);
+ }
+
/* Allocate for size but don't adjust length. */
bool alloc (unsigned int size)
{
@@ -225,7 +309,7 @@ struct hb_vector_t
(new_allocated < (unsigned) allocated) ||
hb_unsigned_mul_overflows (new_allocated, sizeof (Type));
if (likely (!overflows))
- new_array = (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type));
+ new_array = realloc_vector (new_allocated);
if (unlikely (!new_array))
{
@@ -246,7 +330,9 @@ struct hb_vector_t
return false;
if (size > length)
- memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
+ grow_vector (size);
+ else if (size < length)
+ shrink_vector (size);
length = size;
return true;
@@ -255,48 +341,38 @@ struct hb_vector_t
Type pop ()
{
if (!length) return Null (Type);
- return std::move (arrayZ[--length]); /* Does this move actually work? */
+ Type v = std::move (arrayZ[length - 1]);
+ arrayZ[length - 1].~Type ();
+ length--;
+ return v;
}
void remove (unsigned int i)
{
if (unlikely (i >= length))
return;
- memmove (static_cast<void *> (&arrayZ[i]),
- static_cast<void *> (&arrayZ[i + 1]),
- (length - i - 1) * sizeof (Type));
+ arrayZ[i].~Type ();
+ shift_down_vector (i + 1);
length--;
}
void shrink (int size_)
{
unsigned int size = size_ < 0 ? 0u : (unsigned int) size_;
- if (size < length)
- length = size;
- }
+ if (size >= length)
+ return;
- template <typename T>
- Type *find (T v)
- {
- for (unsigned int i = 0; i < length; i++)
- if (arrayZ[i] == v)
- return &arrayZ[i];
- return nullptr;
- }
- template <typename T>
- const Type *find (T v) const
- {
- for (unsigned int i = 0; i < length; i++)
- if (arrayZ[i] == v)
- return &arrayZ[i];
- return nullptr;
+ shrink_vector (size);
}
+
+ /* Sorting API. */
void qsort (int (*cmp)(const void*, const void*))
{ as_array ().qsort (cmp); }
void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1)
{ as_array ().qsort (start, end); }
+ /* Unsorted search API. */
template <typename T>
Type *lsearch (const T &x, Type *not_found = nullptr)
{ return as_array ().lsearch (x, not_found); }
@@ -306,47 +382,25 @@ struct hb_vector_t
template <typename T>
bool lfind (const T &x, unsigned *pos = nullptr) const
{ return as_array ().lfind (x, pos); }
-};
-template <typename Type>
-struct hb_sorted_vector_t : hb_vector_t<Type>
-{
- hb_sorted_vector_t () = default;
- ~hb_sorted_vector_t () = default;
- hb_sorted_vector_t (hb_sorted_vector_t& o) = default;
- hb_sorted_vector_t (hb_sorted_vector_t &&o) = default;
- hb_sorted_vector_t (std::initializer_list<Type> lst) : hb_vector_t<Type> (lst) {}
- template <typename Iterable,
- hb_requires (hb_is_iterable (Iterable))>
- hb_sorted_vector_t (const Iterable &o) : hb_vector_t<Type> (o) {}
- hb_sorted_vector_t& operator = (const hb_sorted_vector_t &o) = default;
- hb_sorted_vector_t& operator = (hb_sorted_vector_t &&o) = default;
- friend void swap (hb_sorted_vector_t& a, hb_sorted_vector_t& b)
- { hb_swap ((hb_vector_t<Type>&) (a), (hb_vector_t<Type>&) (b)); }
-
- hb_sorted_array_t< Type> as_array () { return hb_sorted_array (this->arrayZ, this->length); }
- hb_sorted_array_t<const Type> as_array () const { return hb_sorted_array (this->arrayZ, this->length); }
-
- /* Iterator. */
- typedef hb_sorted_array_t<const Type> const_iter_t;
- typedef hb_sorted_array_t< Type> iter_t;
- const_iter_t iter () const { return as_array (); }
- const_iter_t citer () const { return as_array (); }
- iter_t iter () { return as_array (); }
- operator iter_t () { return iter (); }
- operator const_iter_t () const { return iter (); }
-
- template <typename T>
+ /* Sorted search API. */
+ template <typename T,
+ bool Sorted=sorted, hb_enable_if (Sorted)>
Type *bsearch (const T &x, Type *not_found = nullptr)
{ return as_array ().bsearch (x, not_found); }
- template <typename T>
+ template <typename T,
+ bool Sorted=sorted, hb_enable_if (Sorted)>
const Type *bsearch (const T &x, const Type *not_found = nullptr) const
{ return as_array ().bsearch (x, not_found); }
- template <typename T>
+ template <typename T,
+ bool Sorted=sorted, hb_enable_if (Sorted)>
bool bfind (const T &x, unsigned int *i = nullptr,
hb_not_found_t not_found = HB_NOT_FOUND_DONT_STORE,
unsigned int to_store = (unsigned int) -1) const
{ return as_array ().bfind (x, i, not_found, to_store); }
};
+template <typename Type>
+using hb_sorted_vector_t = hb_vector_t<Type, true>;
+
#endif /* HB_VECTOR_HH */
diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h
index 52b124b745..91ccb3dcde 100644
--- a/thirdparty/harfbuzz/src/hb-version.h
+++ b/thirdparty/harfbuzz/src/hb-version.h
@@ -47,20 +47,20 @@ HB_BEGIN_DECLS
*
* The minor component of the library version available at compile-time.
*/
-#define HB_VERSION_MINOR 2
+#define HB_VERSION_MINOR 3
/**
* HB_VERSION_MICRO:
*
* The micro component of the library version available at compile-time.
*/
-#define HB_VERSION_MICRO 0
+#define HB_VERSION_MICRO 1
/**
* HB_VERSION_STRING:
*
* A string literal containing the library version available at compile-time.
*/
-#define HB_VERSION_STRING "3.2.0"
+#define HB_VERSION_STRING "3.3.1"
/**
* HB_VERSION_ATLEAST:
diff --git a/thirdparty/libwebp/AUTHORS b/thirdparty/libwebp/AUTHORS
index 30abde0326..8307c2099d 100644
--- a/thirdparty/libwebp/AUTHORS
+++ b/thirdparty/libwebp/AUTHORS
@@ -32,6 +32,7 @@ Contributors:
- Pascal Massimino (pascal dot massimino at gmail dot com)
- Paweł Hajdan, Jr (phajdan dot jr at chromium dot org)
- Pierre Joye (pierre dot php at gmail dot com)
+- Roberto Alanis (alanisbaez at google dot com)
- Sam Clegg (sbc at chromium dot org)
- Scott Hancher (seh at google dot com)
- Scott LaVarnway (slavarnway at google dot com)
diff --git a/thirdparty/libwebp/src/dec/vp8_dec.c b/thirdparty/libwebp/src/dec/vp8_dec.c
index 5f405e4c2a..2003935ec4 100644
--- a/thirdparty/libwebp/src/dec/vp8_dec.c
+++ b/thirdparty/libwebp/src/dec/vp8_dec.c
@@ -403,7 +403,7 @@ static const uint8_t kZigzag[16] = {
0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
};
-// See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2
+// See section 13-2: https://datatracker.ietf.org/doc/html/rfc6386#section-13.2
static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) {
int v;
if (!VP8GetBit(br, p[3], "coeffs")) {
diff --git a/thirdparty/libwebp/src/dec/vp8i_dec.h b/thirdparty/libwebp/src/dec/vp8i_dec.h
index 20526a87c4..9af22f8cc6 100644
--- a/thirdparty/libwebp/src/dec/vp8i_dec.h
+++ b/thirdparty/libwebp/src/dec/vp8i_dec.h
@@ -32,7 +32,7 @@ extern "C" {
// version numbers
#define DEC_MAJ_VERSION 1
#define DEC_MIN_VERSION 2
-#define DEC_REV_VERSION 1
+#define DEC_REV_VERSION 2
// YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
// Constraints are: We need to store one 16x16 block of luma samples (y),
diff --git a/thirdparty/libwebp/src/dec/vp8l_dec.c b/thirdparty/libwebp/src/dec/vp8l_dec.c
index 73c3b54fff..78db014030 100644
--- a/thirdparty/libwebp/src/dec/vp8l_dec.c
+++ b/thirdparty/libwebp/src/dec/vp8l_dec.c
@@ -84,7 +84,7 @@ static const uint8_t kCodeToPlane[CODE_TO_PLANE_CODES] = {
// to 256 (green component values) + 24 (length prefix values)
// + color_cache_size (between 0 and 2048).
// All values computed for 8-bit first level lookup with Mark Adler's tool:
-// http://www.hdfgroup.org/ftp/lib-external/zlib/zlib-1.2.5/examples/enough.c
+// https://github.com/madler/zlib/blob/v1.2.5/examples/enough.c
#define FIXED_TABLE_SIZE (630 * 3 + 410)
static const uint16_t kTableSize[12] = {
FIXED_TABLE_SIZE + 654,
diff --git a/thirdparty/libwebp/src/demux/anim_decode.c b/thirdparty/libwebp/src/demux/anim_decode.c
index 2bf4dcffe0..e077ffb536 100644
--- a/thirdparty/libwebp/src/demux/anim_decode.c
+++ b/thirdparty/libwebp/src/demux/anim_decode.c
@@ -23,6 +23,14 @@
#define NUM_CHANNELS 4
+// Channel extraction from a uint32_t representation of a uint8_t RGBA/BGRA
+// buffer.
+#ifdef WORDS_BIGENDIAN
+#define CHANNEL_SHIFT(i) (24 - (i) * 8)
+#else
+#define CHANNEL_SHIFT(i) ((i) * 8)
+#endif
+
typedef void (*BlendRowFunc)(uint32_t* const, const uint32_t* const, int);
static void BlendPixelRowNonPremult(uint32_t* const src,
const uint32_t* const dst, int num_pixels);
@@ -209,35 +217,35 @@ static uint8_t BlendChannelNonPremult(uint32_t src, uint8_t src_a,
const uint8_t dst_channel = (dst >> shift) & 0xff;
const uint32_t blend_unscaled = src_channel * src_a + dst_channel * dst_a;
assert(blend_unscaled < (1ULL << 32) / scale);
- return (blend_unscaled * scale) >> 24;
+ return (blend_unscaled * scale) >> CHANNEL_SHIFT(3);
}
// Blend 'src' over 'dst' assuming they are NOT pre-multiplied by alpha.
static uint32_t BlendPixelNonPremult(uint32_t src, uint32_t dst) {
- const uint8_t src_a = (src >> 24) & 0xff;
+ const uint8_t src_a = (src >> CHANNEL_SHIFT(3)) & 0xff;
if (src_a == 0) {
return dst;
} else {
- const uint8_t dst_a = (dst >> 24) & 0xff;
+ const uint8_t dst_a = (dst >> CHANNEL_SHIFT(3)) & 0xff;
// This is the approximate integer arithmetic for the actual formula:
// dst_factor_a = (dst_a * (255 - src_a)) / 255.
const uint8_t dst_factor_a = (dst_a * (256 - src_a)) >> 8;
const uint8_t blend_a = src_a + dst_factor_a;
const uint32_t scale = (1UL << 24) / blend_a;
- const uint8_t blend_r =
- BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 0);
- const uint8_t blend_g =
- BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 8);
- const uint8_t blend_b =
- BlendChannelNonPremult(src, src_a, dst, dst_factor_a, scale, 16);
+ const uint8_t blend_r = BlendChannelNonPremult(
+ src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(0));
+ const uint8_t blend_g = BlendChannelNonPremult(
+ src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(1));
+ const uint8_t blend_b = BlendChannelNonPremult(
+ src, src_a, dst, dst_factor_a, scale, CHANNEL_SHIFT(2));
assert(src_a + dst_factor_a < 256);
- return (blend_r << 0) |
- (blend_g << 8) |
- (blend_b << 16) |
- ((uint32_t)blend_a << 24);
+ return ((uint32_t)blend_r << CHANNEL_SHIFT(0)) |
+ ((uint32_t)blend_g << CHANNEL_SHIFT(1)) |
+ ((uint32_t)blend_b << CHANNEL_SHIFT(2)) |
+ ((uint32_t)blend_a << CHANNEL_SHIFT(3));
}
}
@@ -247,7 +255,7 @@ static void BlendPixelRowNonPremult(uint32_t* const src,
const uint32_t* const dst, int num_pixels) {
int i;
for (i = 0; i < num_pixels; ++i) {
- const uint8_t src_alpha = (src[i] >> 24) & 0xff;
+ const uint8_t src_alpha = (src[i] >> CHANNEL_SHIFT(3)) & 0xff;
if (src_alpha != 0xff) {
src[i] = BlendPixelNonPremult(src[i], dst[i]);
}
@@ -264,7 +272,7 @@ static WEBP_INLINE uint32_t ChannelwiseMultiply(uint32_t pix, uint32_t scale) {
// Blend 'src' over 'dst' assuming they are pre-multiplied by alpha.
static uint32_t BlendPixelPremult(uint32_t src, uint32_t dst) {
- const uint8_t src_a = (src >> 24) & 0xff;
+ const uint8_t src_a = (src >> CHANNEL_SHIFT(3)) & 0xff;
return src + ChannelwiseMultiply(dst, 256 - src_a);
}
@@ -274,7 +282,7 @@ static void BlendPixelRowPremult(uint32_t* const src, const uint32_t* const dst,
int num_pixels) {
int i;
for (i = 0; i < num_pixels; ++i) {
- const uint8_t src_alpha = (src[i] >> 24) & 0xff;
+ const uint8_t src_alpha = (src[i] >> CHANNEL_SHIFT(3)) & 0xff;
if (src_alpha != 0xff) {
src[i] = BlendPixelPremult(src[i], dst[i]);
}
diff --git a/thirdparty/libwebp/src/demux/demux.c b/thirdparty/libwebp/src/demux/demux.c
index 547a7725de..f04a2b8450 100644
--- a/thirdparty/libwebp/src/demux/demux.c
+++ b/thirdparty/libwebp/src/demux/demux.c
@@ -25,7 +25,7 @@
#define DMUX_MAJ_VERSION 1
#define DMUX_MIN_VERSION 2
-#define DMUX_REV_VERSION 1
+#define DMUX_REV_VERSION 2
typedef struct {
size_t start_; // start location of the data
diff --git a/thirdparty/libwebp/src/dsp/dsp.h b/thirdparty/libwebp/src/dsp/dsp.h
index 513e159bb3..c4f57e4d5b 100644
--- a/thirdparty/libwebp/src/dsp/dsp.h
+++ b/thirdparty/libwebp/src/dsp/dsp.h
@@ -119,7 +119,12 @@ extern "C" {
#define WEBP_USE_NEON
#endif
-#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_M_ARM)
+// Note: ARM64 is supported in Visual Studio 2017, but requires the direct
+// inclusion of arm64_neon.h; Visual Studio 2019 includes this file in
+// arm_neon.h.
+#if defined(_MSC_VER) && \
+ ((_MSC_VER >= 1700 && defined(_M_ARM)) || \
+ (_MSC_VER >= 1920 && defined(_M_ARM64)))
#define WEBP_USE_NEON
#define WEBP_USE_INTRINSICS
#endif
diff --git a/thirdparty/libwebp/src/dsp/enc_neon.c b/thirdparty/libwebp/src/dsp/enc_neon.c
index 43bf1245c5..601962ba76 100644
--- a/thirdparty/libwebp/src/dsp/enc_neon.c
+++ b/thirdparty/libwebp/src/dsp/enc_neon.c
@@ -9,7 +9,7 @@
//
// ARM NEON version of speed-critical encoding functions.
//
-// adapted from libvpx (http://www.webmproject.org/code/)
+// adapted from libvpx (https://www.webmproject.org/code/)
#include "src/dsp/dsp.h"
diff --git a/thirdparty/libwebp/src/dsp/lossless.c b/thirdparty/libwebp/src/dsp/lossless.c
index d8bbb02b35..84a54296fd 100644
--- a/thirdparty/libwebp/src/dsp/lossless.c
+++ b/thirdparty/libwebp/src/dsp/lossless.c
@@ -107,63 +107,77 @@ static WEBP_INLINE uint32_t Select(uint32_t a, uint32_t b, uint32_t c) {
//------------------------------------------------------------------------------
// Predictors
-uint32_t VP8LPredictor0_C(uint32_t left, const uint32_t* const top) {
+uint32_t VP8LPredictor0_C(const uint32_t* const left,
+ const uint32_t* const top) {
(void)top;
(void)left;
return ARGB_BLACK;
}
-uint32_t VP8LPredictor1_C(uint32_t left, const uint32_t* const top) {
+uint32_t VP8LPredictor1_C(const uint32_t* const left,
+ const uint32_t* const top) {
(void)top;
- return left;
+ return *left;
}
-uint32_t VP8LPredictor2_C(uint32_t left, const uint32_t* const top) {
+uint32_t VP8LPredictor2_C(const uint32_t* const left,
+ const uint32_t* const top) {
(void)left;
return top[0];
}
-uint32_t VP8LPredictor3_C(uint32_t left, const uint32_t* const top) {
+uint32_t VP8LPredictor3_C(const uint32_t* const left,
+ const uint32_t* const top) {
(void)left;
return top[1];
}
-uint32_t VP8LPredictor4_C(uint32_t left, const uint32_t* const top) {
+uint32_t VP8LPredictor4_C(const uint32_t* const left,
+ const uint32_t* const top) {
(void)left;
return top[-1];
}
-uint32_t VP8LPredictor5_C(uint32_t left, const uint32_t* const top) {
- const uint32_t pred = Average3(left, top[0], top[1]);
+uint32_t VP8LPredictor5_C(const uint32_t* const left,
+ const uint32_t* const top) {
+ const uint32_t pred = Average3(*left, top[0], top[1]);
return pred;
}
-uint32_t VP8LPredictor6_C(uint32_t left, const uint32_t* const top) {
- const uint32_t pred = Average2(left, top[-1]);
+uint32_t VP8LPredictor6_C(const uint32_t* const left,
+ const uint32_t* const top) {
+ const uint32_t pred = Average2(*left, top[-1]);
return pred;
}
-uint32_t VP8LPredictor7_C(uint32_t left, const uint32_t* const top) {
- const uint32_t pred = Average2(left, top[0]);
+uint32_t VP8LPredictor7_C(const uint32_t* const left,
+ const uint32_t* const top) {
+ const uint32_t pred = Average2(*left, top[0]);
return pred;
}
-uint32_t VP8LPredictor8_C(uint32_t left, const uint32_t* const top) {
+uint32_t VP8LPredictor8_C(const uint32_t* const left,
+ const uint32_t* const top) {
const uint32_t pred = Average2(top[-1], top[0]);
(void)left;
return pred;
}
-uint32_t VP8LPredictor9_C(uint32_t left, const uint32_t* const top) {
+uint32_t VP8LPredictor9_C(const uint32_t* const left,
+ const uint32_t* const top) {
const uint32_t pred = Average2(top[0], top[1]);
(void)left;
return pred;
}
-uint32_t VP8LPredictor10_C(uint32_t left, const uint32_t* const top) {
- const uint32_t pred = Average4(left, top[-1], top[0], top[1]);
+uint32_t VP8LPredictor10_C(const uint32_t* const left,
+ const uint32_t* const top) {
+ const uint32_t pred = Average4(*left, top[-1], top[0], top[1]);
return pred;
}
-uint32_t VP8LPredictor11_C(uint32_t left, const uint32_t* const top) {
- const uint32_t pred = Select(top[0], left, top[-1]);
+uint32_t VP8LPredictor11_C(const uint32_t* const left,
+ const uint32_t* const top) {
+ const uint32_t pred = Select(top[0], *left, top[-1]);
return pred;
}
-uint32_t VP8LPredictor12_C(uint32_t left, const uint32_t* const top) {
- const uint32_t pred = ClampedAddSubtractFull(left, top[0], top[-1]);
+uint32_t VP8LPredictor12_C(const uint32_t* const left,
+ const uint32_t* const top) {
+ const uint32_t pred = ClampedAddSubtractFull(*left, top[0], top[-1]);
return pred;
}
-uint32_t VP8LPredictor13_C(uint32_t left, const uint32_t* const top) {
- const uint32_t pred = ClampedAddSubtractHalf(left, top[0], top[-1]);
+uint32_t VP8LPredictor13_C(const uint32_t* const left,
+ const uint32_t* const top) {
+ const uint32_t pred = ClampedAddSubtractHalf(*left, top[0], top[-1]);
return pred;
}
diff --git a/thirdparty/libwebp/src/dsp/lossless.h b/thirdparty/libwebp/src/dsp/lossless.h
index ebd316d1ed..c26c6bca07 100644
--- a/thirdparty/libwebp/src/dsp/lossless.h
+++ b/thirdparty/libwebp/src/dsp/lossless.h
@@ -28,23 +28,38 @@ extern "C" {
//------------------------------------------------------------------------------
// Decoding
-typedef uint32_t (*VP8LPredictorFunc)(uint32_t left, const uint32_t* const top);
+typedef uint32_t (*VP8LPredictorFunc)(const uint32_t* const left,
+ const uint32_t* const top);
extern VP8LPredictorFunc VP8LPredictors[16];
-uint32_t VP8LPredictor0_C(uint32_t left, const uint32_t* const top);
-uint32_t VP8LPredictor1_C(uint32_t left, const uint32_t* const top);
-uint32_t VP8LPredictor2_C(uint32_t left, const uint32_t* const top);
-uint32_t VP8LPredictor3_C(uint32_t left, const uint32_t* const top);
-uint32_t VP8LPredictor4_C(uint32_t left, const uint32_t* const top);
-uint32_t VP8LPredictor5_C(uint32_t left, const uint32_t* const top);
-uint32_t VP8LPredictor6_C(uint32_t left, const uint32_t* const top);
-uint32_t VP8LPredictor7_C(uint32_t left, const uint32_t* const top);
-uint32_t VP8LPredictor8_C(uint32_t left, const uint32_t* const top);
-uint32_t VP8LPredictor9_C(uint32_t left, const uint32_t* const top);
-uint32_t VP8LPredictor10_C(uint32_t left, const uint32_t* const top);
-uint32_t VP8LPredictor11_C(uint32_t left, const uint32_t* const top);
-uint32_t VP8LPredictor12_C(uint32_t left, const uint32_t* const top);
-uint32_t VP8LPredictor13_C(uint32_t left, const uint32_t* const top);
+uint32_t VP8LPredictor0_C(const uint32_t* const left,
+ const uint32_t* const top);
+uint32_t VP8LPredictor1_C(const uint32_t* const left,
+ const uint32_t* const top);
+uint32_t VP8LPredictor2_C(const uint32_t* const left,
+ const uint32_t* const top);
+uint32_t VP8LPredictor3_C(const uint32_t* const left,
+ const uint32_t* const top);
+uint32_t VP8LPredictor4_C(const uint32_t* const left,
+ const uint32_t* const top);
+uint32_t VP8LPredictor5_C(const uint32_t* const left,
+ const uint32_t* const top);
+uint32_t VP8LPredictor6_C(const uint32_t* const left,
+ const uint32_t* const top);
+uint32_t VP8LPredictor7_C(const uint32_t* const left,
+ const uint32_t* const top);
+uint32_t VP8LPredictor8_C(const uint32_t* const left,
+ const uint32_t* const top);
+uint32_t VP8LPredictor9_C(const uint32_t* const left,
+ const uint32_t* const top);
+uint32_t VP8LPredictor10_C(const uint32_t* const left,
+ const uint32_t* const top);
+uint32_t VP8LPredictor11_C(const uint32_t* const left,
+ const uint32_t* const top);
+uint32_t VP8LPredictor12_C(const uint32_t* const left,
+ const uint32_t* const top);
+uint32_t VP8LPredictor13_C(const uint32_t* const left,
+ const uint32_t* const top);
// These Add/Sub function expects upper[-1] and out[-1] to be readable.
typedef void (*VP8LPredictorAddSubFunc)(const uint32_t* in,
diff --git a/thirdparty/libwebp/src/dsp/lossless_common.h b/thirdparty/libwebp/src/dsp/lossless_common.h
index 96a106f9ee..6a2f736b5e 100644
--- a/thirdparty/libwebp/src/dsp/lossless_common.h
+++ b/thirdparty/libwebp/src/dsp/lossless_common.h
@@ -179,7 +179,7 @@ static void PREDICTOR_ADD(const uint32_t* in, const uint32_t* upper, \
int x; \
assert(upper != NULL); \
for (x = 0; x < num_pixels; ++x) { \
- const uint32_t pred = (PREDICTOR)(out[x - 1], upper + x); \
+ const uint32_t pred = (PREDICTOR)(&out[x - 1], upper + x); \
out[x] = VP8LAddPixels(in[x], pred); \
} \
}
diff --git a/thirdparty/libwebp/src/dsp/lossless_enc.c b/thirdparty/libwebp/src/dsp/lossless_enc.c
index c3e8537ade..1580631e38 100644
--- a/thirdparty/libwebp/src/dsp/lossless_enc.c
+++ b/thirdparty/libwebp/src/dsp/lossless_enc.c
@@ -745,7 +745,7 @@ static void PredictorSub##PREDICTOR_I##_C(const uint32_t* in, \
assert(upper != NULL); \
for (x = 0; x < num_pixels; ++x) { \
const uint32_t pred = \
- VP8LPredictor##PREDICTOR_I##_C(in[x - 1], upper + x); \
+ VP8LPredictor##PREDICTOR_I##_C(&in[x - 1], upper + x); \
out[x] = VP8LSubPixels(in[x], pred); \
} \
}
diff --git a/thirdparty/libwebp/src/dsp/lossless_mips_dsp_r2.c b/thirdparty/libwebp/src/dsp/lossless_mips_dsp_r2.c
index 9888854d57..bfe5ea6b38 100644
--- a/thirdparty/libwebp/src/dsp/lossless_mips_dsp_r2.c
+++ b/thirdparty/libwebp/src/dsp/lossless_mips_dsp_r2.c
@@ -188,46 +188,51 @@ static WEBP_INLINE uint32_t Average4(uint32_t a0, uint32_t a1,
return Average2(Average2(a0, a1), Average2(a2, a3));
}
-static uint32_t Predictor5_MIPSdspR2(uint32_t left, const uint32_t* const top) {
- return Average3(left, top[0], top[1]);
+static uint32_t Predictor5_MIPSdspR2(const uint32_t* const left,
+ const uint32_t* const top) {
+ return Average3(*left, top[0], top[1]);
}
-static uint32_t Predictor6_MIPSdspR2(uint32_t left, const uint32_t* const top) {
- return Average2(left, top[-1]);
+static uint32_t Predictor6_MIPSdspR2(const uint32_t* const left,
+ const uint32_t* const top) {
+ return Average2(*left, top[-1]);
}
-static uint32_t Predictor7_MIPSdspR2(uint32_t left, const uint32_t* const top) {
- return Average2(left, top[0]);
+static uint32_t Predictor7_MIPSdspR2(const uint32_t* const left,
+ const uint32_t* const top) {
+ return Average2(*left, top[0]);
}
-static uint32_t Predictor8_MIPSdspR2(uint32_t left, const uint32_t* const top) {
+static uint32_t Predictor8_MIPSdspR2(const uint32_t* const left,
+ const uint32_t* const top) {
(void)left;
return Average2(top[-1], top[0]);
}
-static uint32_t Predictor9_MIPSdspR2(uint32_t left, const uint32_t* const top) {
+static uint32_t Predictor9_MIPSdspR2(const uint32_t* const left,
+ const uint32_t* const top) {
(void)left;
return Average2(top[0], top[1]);
}
-static uint32_t Predictor10_MIPSdspR2(uint32_t left,
+static uint32_t Predictor10_MIPSdspR2(const uint32_t* const left,
const uint32_t* const top) {
- return Average4(left, top[-1], top[0], top[1]);
+ return Average4(*left, top[-1], top[0], top[1]);
}
-static uint32_t Predictor11_MIPSdspR2(uint32_t left,
+static uint32_t Predictor11_MIPSdspR2(const uint32_t* const left,
const uint32_t* const top) {
- return Select(top[0], left, top[-1]);
+ return Select(top[0], *left, top[-1]);
}
-static uint32_t Predictor12_MIPSdspR2(uint32_t left,
+static uint32_t Predictor12_MIPSdspR2(const uint32_t* const left,
const uint32_t* const top) {
- return ClampedAddSubtractFull(left, top[0], top[-1]);
+ return ClampedAddSubtractFull(*left, top[0], top[-1]);
}
-static uint32_t Predictor13_MIPSdspR2(uint32_t left,
+static uint32_t Predictor13_MIPSdspR2(const uint32_t* const left,
const uint32_t* const top) {
- return ClampedAddSubtractHalf(left, top[0], top[-1]);
+ return ClampedAddSubtractHalf(*left, top[0], top[-1]);
}
// Add green to blue and red channels (i.e. perform the inverse transform of
diff --git a/thirdparty/libwebp/src/dsp/lossless_neon.c b/thirdparty/libwebp/src/dsp/lossless_neon.c
index 76a1b6f873..89e3e013a0 100644
--- a/thirdparty/libwebp/src/dsp/lossless_neon.c
+++ b/thirdparty/libwebp/src/dsp/lossless_neon.c
@@ -188,17 +188,21 @@ static WEBP_INLINE uint32_t Average3_NEON(uint32_t a0, uint32_t a1,
return avg;
}
-static uint32_t Predictor5_NEON(uint32_t left, const uint32_t* const top) {
- return Average3_NEON(left, top[0], top[1]);
+static uint32_t Predictor5_NEON(const uint32_t* const left,
+ const uint32_t* const top) {
+ return Average3_NEON(*left, top[0], top[1]);
}
-static uint32_t Predictor6_NEON(uint32_t left, const uint32_t* const top) {
- return Average2_NEON(left, top[-1]);
+static uint32_t Predictor6_NEON(const uint32_t* const left,
+ const uint32_t* const top) {
+ return Average2_NEON(*left, top[-1]);
}
-static uint32_t Predictor7_NEON(uint32_t left, const uint32_t* const top) {
- return Average2_NEON(left, top[0]);
+static uint32_t Predictor7_NEON(const uint32_t* const left,
+ const uint32_t* const top) {
+ return Average2_NEON(*left, top[0]);
}
-static uint32_t Predictor13_NEON(uint32_t left, const uint32_t* const top) {
- return ClampedAddSubtractHalf_NEON(left, top[0], top[-1]);
+static uint32_t Predictor13_NEON(const uint32_t* const left,
+ const uint32_t* const top) {
+ return ClampedAddSubtractHalf_NEON(*left, top[0], top[-1]);
}
// Batch versions of those functions.
diff --git a/thirdparty/libwebp/src/dsp/lossless_sse2.c b/thirdparty/libwebp/src/dsp/lossless_sse2.c
index 3a0eb440db..396cb0bdfc 100644
--- a/thirdparty/libwebp/src/dsp/lossless_sse2.c
+++ b/thirdparty/libwebp/src/dsp/lossless_sse2.c
@@ -138,42 +138,51 @@ static WEBP_INLINE uint32_t Average4_SSE2(uint32_t a0, uint32_t a1,
return output;
}
-static uint32_t Predictor5_SSE2(uint32_t left, const uint32_t* const top) {
- const uint32_t pred = Average3_SSE2(left, top[0], top[1]);
+static uint32_t Predictor5_SSE2(const uint32_t* const left,
+ const uint32_t* const top) {
+ const uint32_t pred = Average3_SSE2(*left, top[0], top[1]);
return pred;
}
-static uint32_t Predictor6_SSE2(uint32_t left, const uint32_t* const top) {
- const uint32_t pred = Average2_SSE2(left, top[-1]);
+static uint32_t Predictor6_SSE2(const uint32_t* const left,
+ const uint32_t* const top) {
+ const uint32_t pred = Average2_SSE2(*left, top[-1]);
return pred;
}
-static uint32_t Predictor7_SSE2(uint32_t left, const uint32_t* const top) {
- const uint32_t pred = Average2_SSE2(left, top[0]);
+static uint32_t Predictor7_SSE2(const uint32_t* const left,
+ const uint32_t* const top) {
+ const uint32_t pred = Average2_SSE2(*left, top[0]);
return pred;
}
-static uint32_t Predictor8_SSE2(uint32_t left, const uint32_t* const top) {
+static uint32_t Predictor8_SSE2(const uint32_t* const left,
+ const uint32_t* const top) {
const uint32_t pred = Average2_SSE2(top[-1], top[0]);
(void)left;
return pred;
}
-static uint32_t Predictor9_SSE2(uint32_t left, const uint32_t* const top) {
+static uint32_t Predictor9_SSE2(const uint32_t* const left,
+ const uint32_t* const top) {
const uint32_t pred = Average2_SSE2(top[0], top[1]);
(void)left;
return pred;
}
-static uint32_t Predictor10_SSE2(uint32_t left, const uint32_t* const top) {
- const uint32_t pred = Average4_SSE2(left, top[-1], top[0], top[1]);
+static uint32_t Predictor10_SSE2(const uint32_t* const left,
+ const uint32_t* const top) {
+ const uint32_t pred = Average4_SSE2(*left, top[-1], top[0], top[1]);
return pred;
}
-static uint32_t Predictor11_SSE2(uint32_t left, const uint32_t* const top) {
- const uint32_t pred = Select_SSE2(top[0], left, top[-1]);
+static uint32_t Predictor11_SSE2(const uint32_t* const left,
+ const uint32_t* const top) {
+ const uint32_t pred = Select_SSE2(top[0], *left, top[-1]);
return pred;
}
-static uint32_t Predictor12_SSE2(uint32_t left, const uint32_t* const top) {
- const uint32_t pred = ClampedAddSubtractFull_SSE2(left, top[0], top[-1]);
+static uint32_t Predictor12_SSE2(const uint32_t* const left,
+ const uint32_t* const top) {
+ const uint32_t pred = ClampedAddSubtractFull_SSE2(*left, top[0], top[-1]);
return pred;
}
-static uint32_t Predictor13_SSE2(uint32_t left, const uint32_t* const top) {
- const uint32_t pred = ClampedAddSubtractHalf_SSE2(left, top[0], top[-1]);
+static uint32_t Predictor13_SSE2(const uint32_t* const left,
+ const uint32_t* const top) {
+ const uint32_t pred = ClampedAddSubtractHalf_SSE2(*left, top[0], top[-1]);
return pred;
}
diff --git a/thirdparty/libwebp/src/dsp/msa_macro.h b/thirdparty/libwebp/src/dsp/msa_macro.h
index de026a1d9e..51f6c643ab 100644
--- a/thirdparty/libwebp/src/dsp/msa_macro.h
+++ b/thirdparty/libwebp/src/dsp/msa_macro.h
@@ -14,6 +14,10 @@
#ifndef WEBP_DSP_MSA_MACRO_H_
#define WEBP_DSP_MSA_MACRO_H_
+#include "src/dsp/dsp.h"
+
+#if defined(WEBP_USE_MSA)
+
#include <stdint.h>
#include <msa.h>
@@ -1389,4 +1393,5 @@ static WEBP_INLINE uint32_t func_hadd_uh_u32(v8u16 in) {
} while (0)
#define AVER_UB2_UB(...) AVER_UB2(v16u8, __VA_ARGS__)
+#endif // WEBP_USE_MSA
#endif // WEBP_DSP_MSA_MACRO_H_
diff --git a/thirdparty/libwebp/src/dsp/neon.h b/thirdparty/libwebp/src/dsp/neon.h
index aa1dea1301..c591f9b9a7 100644
--- a/thirdparty/libwebp/src/dsp/neon.h
+++ b/thirdparty/libwebp/src/dsp/neon.h
@@ -12,10 +12,12 @@
#ifndef WEBP_DSP_NEON_H_
#define WEBP_DSP_NEON_H_
-#include <arm_neon.h>
-
#include "src/dsp/dsp.h"
+#if defined(WEBP_USE_NEON)
+
+#include <arm_neon.h>
+
// Right now, some intrinsics functions seem slower, so we disable them
// everywhere except newer clang/gcc or aarch64 where the inline assembly is
// incompatible.
@@ -98,4 +100,5 @@ static WEBP_INLINE int32x4x4_t Transpose4x4_NEON(const int32x4x4_t rows) {
} while (0)
#endif
+#endif // WEBP_USE_NEON
#endif // WEBP_DSP_NEON_H_
diff --git a/thirdparty/libwebp/src/dsp/yuv.h b/thirdparty/libwebp/src/dsp/yuv.h
index c12be1d094..66a397d117 100644
--- a/thirdparty/libwebp/src/dsp/yuv.h
+++ b/thirdparty/libwebp/src/dsp/yuv.h
@@ -10,7 +10,7 @@
// inline YUV<->RGB conversion function
//
// The exact naming is Y'CbCr, following the ITU-R BT.601 standard.
-// More information at: http://en.wikipedia.org/wiki/YCbCr
+// More information at: https://en.wikipedia.org/wiki/YCbCr
// Y = 0.2569 * R + 0.5044 * G + 0.0979 * B + 16
// U = -0.1483 * R - 0.2911 * G + 0.4394 * B + 128
// V = 0.4394 * R - 0.3679 * G - 0.0715 * B + 128
diff --git a/thirdparty/libwebp/src/enc/frame_enc.c b/thirdparty/libwebp/src/enc/frame_enc.c
index af538d83ba..b93d9e5b99 100644
--- a/thirdparty/libwebp/src/enc/frame_enc.c
+++ b/thirdparty/libwebp/src/enc/frame_enc.c
@@ -778,6 +778,7 @@ int VP8EncTokenLoop(VP8Encoder* const enc) {
// Roughly refresh the proba eight times per pass
int max_count = (enc->mb_w_ * enc->mb_h_) >> 3;
int num_pass_left = enc->config_->pass;
+ int remaining_progress = 40; // percents
const int do_search = enc->do_search_;
VP8EncIterator it;
VP8EncProba* const proba = &enc->proba_;
@@ -805,6 +806,9 @@ int VP8EncTokenLoop(VP8Encoder* const enc) {
uint64_t size_p0 = 0;
uint64_t distortion = 0;
int cnt = max_count;
+ // The final number of passes is not trivial to know in advance.
+ const int pass_progress = remaining_progress / (2 + num_pass_left);
+ remaining_progress -= pass_progress;
VP8IteratorInit(enc, &it);
SetLoopParams(enc, stats.q);
if (is_last_pass) {
@@ -832,7 +836,7 @@ int VP8EncTokenLoop(VP8Encoder* const enc) {
StoreSideInfo(&it);
VP8StoreFilterStats(&it);
VP8IteratorExport(&it);
- ok = VP8IteratorProgress(&it, 20);
+ ok = VP8IteratorProgress(&it, pass_progress);
}
VP8IteratorSaveBoundary(&it);
} while (ok && VP8IteratorNext(&it));
@@ -878,7 +882,8 @@ int VP8EncTokenLoop(VP8Encoder* const enc) {
ok = VP8EmitTokens(&enc->tokens_, enc->parts_ + 0,
(const uint8_t*)proba->coeffs_, 1);
}
- ok = ok && WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_);
+ ok = ok && WebPReportProgress(enc->pic_, enc->percent_ + remaining_progress,
+ &enc->percent_);
return PostLoopFinalize(&it, ok);
}
diff --git a/thirdparty/libwebp/src/enc/predictor_enc.c b/thirdparty/libwebp/src/enc/predictor_enc.c
index 2e6762ea0d..2b5c767280 100644
--- a/thirdparty/libwebp/src/enc/predictor_enc.c
+++ b/thirdparty/libwebp/src/enc/predictor_enc.c
@@ -249,7 +249,7 @@ static WEBP_INLINE void GetResidual(
} else if (x == 0) {
predict = upper_row[x]; // Top.
} else {
- predict = pred_func(current_row[x - 1], upper_row + x);
+ predict = pred_func(&current_row[x - 1], upper_row + x);
}
#if (WEBP_NEAR_LOSSLESS == 1)
if (max_quantization == 1 || mode == 0 || y == 0 || y == height - 1 ||
diff --git a/thirdparty/libwebp/src/enc/quant_enc.c b/thirdparty/libwebp/src/enc/quant_enc.c
index 01eb565c7f..6cede28ab4 100644
--- a/thirdparty/libwebp/src/enc/quant_enc.c
+++ b/thirdparty/libwebp/src/enc/quant_enc.c
@@ -585,6 +585,9 @@ static WEBP_INLINE score_t RDScoreTrellis(int lambda, score_t rate,
return rate * lambda + RD_DISTO_MULT * distortion;
}
+// Coefficient type.
+enum { TYPE_I16_AC = 0, TYPE_I16_DC = 1, TYPE_CHROMA_A = 2, TYPE_I4_AC = 3 };
+
static int TrellisQuantizeBlock(const VP8Encoder* const enc,
int16_t in[16], int16_t out[16],
int ctx0, int coeff_type,
@@ -593,7 +596,7 @@ static int TrellisQuantizeBlock(const VP8Encoder* const enc,
const ProbaArray* const probas = enc->proba_.coeffs_[coeff_type];
CostArrayPtr const costs =
(CostArrayPtr)enc->proba_.remapped_costs_[coeff_type];
- const int first = (coeff_type == 0) ? 1 : 0;
+ const int first = (coeff_type == TYPE_I16_AC) ? 1 : 0;
Node nodes[16][NUM_NODES];
ScoreState score_states[2][NUM_NODES];
ScoreState* ss_cur = &SCORE_STATE(0, MIN_DELTA);
@@ -657,16 +660,17 @@ static int TrellisQuantizeBlock(const VP8Encoder* const enc,
// test all alternate level values around level0.
for (m = -MIN_DELTA; m <= MAX_DELTA; ++m) {
Node* const cur = &NODE(n, m);
- int level = level0 + m;
+ const int level = level0 + m;
const int ctx = (level > 2) ? 2 : level;
const int band = VP8EncBands[n + 1];
score_t base_score;
- score_t best_cur_score = MAX_COST;
- int best_prev = 0; // default, in case
+ score_t best_cur_score;
+ int best_prev;
+ score_t cost, score;
- ss_cur[m].score = MAX_COST;
ss_cur[m].costs = costs[n + 1][ctx];
if (level < 0 || level > thresh_level) {
+ ss_cur[m].score = MAX_COST;
// Node is dead.
continue;
}
@@ -682,18 +686,24 @@ static int TrellisQuantizeBlock(const VP8Encoder* const enc,
}
// Inspect all possible non-dead predecessors. Retain only the best one.
- for (p = -MIN_DELTA; p <= MAX_DELTA; ++p) {
+ // The base_score is added to all scores so it is only added for the final
+ // value after the loop.
+ cost = VP8LevelCost(ss_prev[-MIN_DELTA].costs, level);
+ best_cur_score =
+ ss_prev[-MIN_DELTA].score + RDScoreTrellis(lambda, cost, 0);
+ best_prev = -MIN_DELTA;
+ for (p = -MIN_DELTA + 1; p <= MAX_DELTA; ++p) {
// Dead nodes (with ss_prev[p].score >= MAX_COST) are automatically
// eliminated since their score can't be better than the current best.
- const score_t cost = VP8LevelCost(ss_prev[p].costs, level);
+ cost = VP8LevelCost(ss_prev[p].costs, level);
// Examine node assuming it's a non-terminal one.
- const score_t score =
- base_score + ss_prev[p].score + RDScoreTrellis(lambda, cost, 0);
+ score = ss_prev[p].score + RDScoreTrellis(lambda, cost, 0);
if (score < best_cur_score) {
best_cur_score = score;
best_prev = p;
}
}
+ best_cur_score += base_score;
// Store best finding in current node.
cur->sign = sign;
cur->level = level;
@@ -701,11 +711,11 @@ static int TrellisQuantizeBlock(const VP8Encoder* const enc,
ss_cur[m].score = best_cur_score;
// Now, record best terminal node (and thus best entry in the graph).
- if (level != 0) {
+ if (level != 0 && best_cur_score < best_score) {
const score_t last_pos_cost =
(n < 15) ? VP8BitCost(0, probas[band][ctx][0]) : 0;
const score_t last_pos_score = RDScoreTrellis(lambda, last_pos_cost, 0);
- const score_t score = best_cur_score + last_pos_score;
+ score = best_cur_score + last_pos_score;
if (score < best_score) {
best_score = score;
best_path[0] = n; // best eob position
@@ -717,10 +727,16 @@ static int TrellisQuantizeBlock(const VP8Encoder* const enc,
}
// Fresh start
- memset(in + first, 0, (16 - first) * sizeof(*in));
- memset(out + first, 0, (16 - first) * sizeof(*out));
+ // Beware! We must preserve in[0]/out[0] value for TYPE_I16_AC case.
+ if (coeff_type == TYPE_I16_AC) {
+ memset(in + 1, 0, 15 * sizeof(*in));
+ memset(out + 1, 0, 15 * sizeof(*out));
+ } else {
+ memset(in, 0, 16 * sizeof(*in));
+ memset(out, 0, 16 * sizeof(*out));
+ }
if (best_path[0] == -1) {
- return 0; // skip!
+ return 0; // skip!
}
{
@@ -775,9 +791,9 @@ static int ReconstructIntra16(VP8EncIterator* const it,
for (y = 0, n = 0; y < 4; ++y) {
for (x = 0; x < 4; ++x, ++n) {
const int ctx = it->top_nz_[x] + it->left_nz_[y];
- const int non_zero =
- TrellisQuantizeBlock(enc, tmp[n], rd->y_ac_levels[n], ctx, 0,
- &dqm->y1_, dqm->lambda_trellis_i16_);
+ const int non_zero = TrellisQuantizeBlock(
+ enc, tmp[n], rd->y_ac_levels[n], ctx, TYPE_I16_AC, &dqm->y1_,
+ dqm->lambda_trellis_i16_);
it->top_nz_[x] = it->left_nz_[y] = non_zero;
rd->y_ac_levels[n][0] = 0;
nz |= non_zero << n;
@@ -818,7 +834,7 @@ static int ReconstructIntra4(VP8EncIterator* const it,
if (DO_TRELLIS_I4 && it->do_trellis_) {
const int x = it->i4_ & 3, y = it->i4_ >> 2;
const int ctx = it->top_nz_[x] + it->left_nz_[y];
- nz = TrellisQuantizeBlock(enc, tmp, levels, ctx, 3, &dqm->y1_,
+ nz = TrellisQuantizeBlock(enc, tmp, levels, ctx, TYPE_I4_AC, &dqm->y1_,
dqm->lambda_trellis_i4_);
} else {
nz = VP8EncQuantizeBlock(tmp, levels, &dqm->y1_);
@@ -927,9 +943,9 @@ static int ReconstructUV(VP8EncIterator* const it, VP8ModeScore* const rd,
for (y = 0; y < 2; ++y) {
for (x = 0; x < 2; ++x, ++n) {
const int ctx = it->top_nz_[4 + ch + x] + it->left_nz_[4 + ch + y];
- const int non_zero =
- TrellisQuantizeBlock(enc, tmp[n], rd->uv_levels[n], ctx, 2,
- &dqm->uv_, dqm->lambda_trellis_uv_);
+ const int non_zero = TrellisQuantizeBlock(
+ enc, tmp[n], rd->uv_levels[n], ctx, TYPE_CHROMA_A, &dqm->uv_,
+ dqm->lambda_trellis_uv_);
it->top_nz_[4 + ch + x] = it->left_nz_[4 + ch + y] = non_zero;
nz |= non_zero << n;
}
diff --git a/thirdparty/libwebp/src/enc/vp8i_enc.h b/thirdparty/libwebp/src/enc/vp8i_enc.h
index 67e9509367..b4bba08f27 100644
--- a/thirdparty/libwebp/src/enc/vp8i_enc.h
+++ b/thirdparty/libwebp/src/enc/vp8i_enc.h
@@ -32,7 +32,7 @@ extern "C" {
// version numbers
#define ENC_MAJ_VERSION 1
#define ENC_MIN_VERSION 2
-#define ENC_REV_VERSION 1
+#define ENC_REV_VERSION 2
enum { MAX_LF_LEVELS = 64, // Maximum loop filter level
MAX_VARIABLE_LEVEL = 67, // last (inclusive) level with variable cost
diff --git a/thirdparty/libwebp/src/mux/muxi.h b/thirdparty/libwebp/src/mux/muxi.h
index 330da66754..d9bf9b3770 100644
--- a/thirdparty/libwebp/src/mux/muxi.h
+++ b/thirdparty/libwebp/src/mux/muxi.h
@@ -29,7 +29,7 @@ extern "C" {
#define MUX_MAJ_VERSION 1
#define MUX_MIN_VERSION 2
-#define MUX_REV_VERSION 1
+#define MUX_REV_VERSION 2
// Chunk object.
typedef struct WebPChunk WebPChunk;
diff --git a/thirdparty/libwebp/src/utils/huffman_encode_utils.c b/thirdparty/libwebp/src/utils/huffman_encode_utils.c
index fd7a47d8f7..585db91951 100644
--- a/thirdparty/libwebp/src/utils/huffman_encode_utils.c
+++ b/thirdparty/libwebp/src/utils/huffman_encode_utils.c
@@ -161,7 +161,7 @@ static void SetBitDepths(const HuffmanTree* const tree,
// especially when population counts are longer than 2**tree_limit, but
// we are not planning to use this with extremely long blocks.
//
-// See http://en.wikipedia.org/wiki/Huffman_coding
+// See https://en.wikipedia.org/wiki/Huffman_coding
static void GenerateOptimalTree(const uint32_t* const histogram,
int histogram_size,
HuffmanTree* tree, int tree_depth_limit,
diff --git a/thirdparty/libwebp/src/utils/quant_levels_dec_utils.c b/thirdparty/libwebp/src/utils/quant_levels_dec_utils.c
index f65b6cdbb6..97e7893704 100644
--- a/thirdparty/libwebp/src/utils/quant_levels_dec_utils.c
+++ b/thirdparty/libwebp/src/utils/quant_levels_dec_utils.c
@@ -30,7 +30,7 @@
#define DFIX 4 // extra precision for ordered dithering
#define DSIZE 4 // dithering size (must be a power of two)
-// cf. http://en.wikipedia.org/wiki/Ordered_dithering
+// cf. https://en.wikipedia.org/wiki/Ordered_dithering
static const uint8_t kOrderedDither[DSIZE][DSIZE] = {
{ 0, 8, 2, 10 }, // coefficients are in DFIX fixed-point precision
{ 12, 4, 14, 6 },
diff --git a/thirdparty/libwebp/src/utils/utils.c b/thirdparty/libwebp/src/utils/utils.c
index 9e464c16ce..a7c3a70fef 100644
--- a/thirdparty/libwebp/src/utils/utils.c
+++ b/thirdparty/libwebp/src/utils/utils.c
@@ -23,7 +23,7 @@
// alloc/free etc) is printed. For debugging/tuning purpose only (it's slow,
// and not multi-thread safe!).
// An interesting alternative is valgrind's 'massif' tool:
-// http://valgrind.org/docs/manual/ms-manual.html
+// https://valgrind.org/docs/manual/ms-manual.html
// Here is an example command line:
/* valgrind --tool=massif --massif-out-file=massif.out \
--stacks=yes --alloc-fn=WebPSafeMalloc --alloc-fn=WebPSafeCalloc
diff --git a/thirdparty/libwebp/src/webp/decode.h b/thirdparty/libwebp/src/webp/decode.h
index 44fcd64a84..d98247509a 100644
--- a/thirdparty/libwebp/src/webp/decode.h
+++ b/thirdparty/libwebp/src/webp/decode.h
@@ -85,7 +85,7 @@ WEBP_EXTERN uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size,
// Upon return, the Y buffer has a stride returned as '*stride', while U and V
// have a common stride returned as '*uv_stride'.
// Return NULL in case of error.
-// (*) Also named Y'CbCr. See: http://en.wikipedia.org/wiki/YCbCr
+// (*) Also named Y'CbCr. See: https://en.wikipedia.org/wiki/YCbCr
WEBP_EXTERN uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
int* width, int* height,
uint8_t** u, uint8_t** v,
diff --git a/thirdparty/thorvg/AUTHORS b/thirdparty/thorvg/AUTHORS
index 66057232b6..ec06c49118 100644
--- a/thirdparty/thorvg/AUTHORS
+++ b/thirdparty/thorvg/AUTHORS
@@ -13,3 +13,5 @@ Pankaj Kumar <pankaj.m1@samsung.com>
Patryk Kaczmarek <patryk.k@partner.samsung.com>
Michal Maciola <m.maciola@samsung.com>
Peter Vullings <peter@projectitis.com>
+K. S. Ernest (iFire) Lee <ernest.lee@chibifire.com>
+RĂ©mi Verschelde <rverschelde@gmail.com>
diff --git a/thirdparty/thorvg/inc/config.h b/thirdparty/thorvg/inc/config.h
index 04a450b1bb..41e8f6dafa 100644
--- a/thirdparty/thorvg/inc/config.h
+++ b/thirdparty/thorvg/inc/config.h
@@ -13,5 +13,5 @@
#define THORVG_JPG_LOADER_SUPPORT 1
-#define THORVG_VERSION_STRING "0.7.0"
+#define THORVG_VERSION_STRING "0.7.1"
#endif
diff --git a/thirdparty/thorvg/patches/thorvg-pr1159-mingw-fix.patch b/thirdparty/thorvg/patches/thorvg-pr1159-mingw-fix.patch
deleted file mode 100644
index a174880306..0000000000
--- a/thirdparty/thorvg/patches/thorvg-pr1159-mingw-fix.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
-index def8ae169a..cf103774c5 100644
---- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
-+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
-@@ -51,6 +51,7 @@
-
- #define _USE_MATH_DEFINES //Math Constants are not defined in Standard C/C++.
-
-+#include <cstring>
- #include <fstream>
- #include <float.h>
- #include <math.h>
-diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp
-index 2b62315de8..32685ee620 100644
---- a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp
-+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp
-@@ -50,6 +50,7 @@
-
- #define _USE_MATH_DEFINES //Math Constants are not defined in Standard C/C++.
-
-+#include <cstring>
- #include <math.h>
- #include <clocale>
- #include <ctype.h>
-diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp
-index 8701fe32b1..ae17634f31 100644
---- a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp
-+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp
-@@ -49,6 +49,7 @@
- */
-
-
-+#include <cstring>
- #include <string>
- #include "tvgMath.h"
- #include "tvgSvgLoaderCommon.h"
-diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp
-index d5b9cdcf7b..9f269b29a2 100644
---- a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp
-+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp
-@@ -20,6 +20,7 @@
- * SOFTWARE.
- */
-
-+#include <cstring>
- #include <math.h>
- #include <memory.h>
- #include "tvgSvgUtil.h"
-diff --git a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp
-index 2e3d5928d9..1571aa4e25 100644
---- a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp
-+++ b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp
-@@ -20,6 +20,7 @@
- * SOFTWARE.
- */
-
-+#include <cstring>
- #include <ctype.h>
- #include <string>
-
-diff --git a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp
-index 9450d80e88..9dd57e5a89 100644
---- a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp
-+++ b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp
-@@ -24,6 +24,8 @@
- #include "tvgTvgSaver.h"
- #include "tvgLzw.h"
-
-+#include <cstring>
-+
- #ifdef _WIN32
- #include <malloc.h>
- #else
diff --git a/thirdparty/thorvg/patches/thorvg-pr1166-vs2017-minmax.patch b/thirdparty/thorvg/patches/thorvg-pr1166-vs2017-minmax.patch
deleted file mode 100644
index 0b045bd05a..0000000000
--- a/thirdparty/thorvg/patches/thorvg-pr1166-vs2017-minmax.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp
-index 78537e7726..c75e73760e 100644
---- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp
-+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp
-@@ -23,6 +23,7 @@
- #include "tvgSwCommon.h"
- #include "tvgTaskScheduler.h"
- #include "tvgSwRenderer.h"
-+#include "tvgMath.h"
-
- /************************************************************************/
- /* Internal Class Implementation */
-@@ -594,10 +595,10 @@ void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform,
- task->surface = surface;
- task->mpool = mpool;
- task->flags = flags;
-- task->bbox.min.x = max(static_cast<SwCoord>(0), static_cast<SwCoord>(vport.x));
-- task->bbox.min.y = max(static_cast<SwCoord>(0), static_cast<SwCoord>(vport.y));
-- task->bbox.max.x = min(static_cast<SwCoord>(surface->w), static_cast<SwCoord>(vport.x + vport.w));
-- task->bbox.max.y = min(static_cast<SwCoord>(surface->h), static_cast<SwCoord>(vport.y + vport.h));
-+ task->bbox.min.x = mathMax(static_cast<SwCoord>(0), static_cast<SwCoord>(vport.x));
-+ task->bbox.min.y = mathMax(static_cast<SwCoord>(0), static_cast<SwCoord>(vport.y));
-+ task->bbox.max.x = mathMin(static_cast<SwCoord>(surface->w), static_cast<SwCoord>(vport.x + vport.w));
-+ task->bbox.max.y = mathMin(static_cast<SwCoord>(surface->h), static_cast<SwCoord>(vport.y + vport.h));
-
- if (!task->pushed) {
- task->pushed = true;
-diff --git a/thirdparty/thorvg/src/lib/tvgMath.h b/thirdparty/thorvg/src/lib/tvgMath.h
-index 9e5c915fc3..94b4fe1cf1 100644
---- a/thirdparty/thorvg/src/lib/tvgMath.h
-+++ b/thirdparty/thorvg/src/lib/tvgMath.h
-@@ -29,6 +29,10 @@
- #include "tvgCommon.h"
-
-
-+#define mathMin(x, y) (((x) < (y)) ? (x) : (y))
-+#define mathMax(x, y) (((x) > (y)) ? (x) : (y))
-+
-+
- static inline bool mathZero(float a)
- {
- return (fabsf(a) < FLT_EPSILON) ? true : false;
-@@ -154,4 +158,4 @@ static inline Matrix mathMultiply(const Matrix* lhs, const Matrix* rhs)
- }
-
-
--#endif //_TVG_MATH_H_
-\ No newline at end of file
-+#endif //_TVG_MATH_H_
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp
index fe22fce017..f9974d9847 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp
@@ -84,8 +84,8 @@ bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipReg
//Fast track: Non-transformed image but just shifted.
if (image->direct) {
- image->ox = -static_cast<uint32_t>(round(transform->e13));
- image->oy = -static_cast<uint32_t>(round(transform->e23));
+ image->ox = -static_cast<int32_t>(round(transform->e13));
+ image->oy = -static_cast<int32_t>(round(transform->e23));
//Figure out the scale factor by transform matrix
} else {
auto scaleX = sqrtf((transform->e11 * transform->e11) + (transform->e21 * transform->e21));
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp
index deebed16ee..56bc2f77dc 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp
@@ -481,7 +481,10 @@ static bool _rasterScaledRleRGBAImage(SwSurface* surface, const SwImage* image,
static bool _scaledRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity)
{
Matrix itransform;
- if (transform && !mathInverse(transform, &itransform)) return false;
+
+ if (transform) {
+ if (!mathInverse(transform, &itransform)) return false;
+ } else mathIdentity(&itransform);
auto halfScale = _halfScale(image->scale);
@@ -816,7 +819,10 @@ static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, con
static bool _scaledRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity)
{
Matrix itransform;
- if (transform && !mathInverse(transform, &itransform)) return false;
+
+ if (transform) {
+ if (!mathInverse(transform, &itransform)) return false;
+ } else mathIdentity(&itransform);
auto halfScale = _halfScale(image->scale);
@@ -1113,12 +1119,12 @@ static bool _rasterTranslucentLinearGradientRle(SwSurface* surface, const SwRleD
auto dst = &surface->buffer[span->y * surface->stride + span->x];
fillFetchLinear(fill, buffer, span->y, span->x, span->len);
if (span->coverage == 255) {
- for (uint32_t i = 0; i < span->len; ++i, ++dst) {
- *dst = buffer[i] + ALPHA_BLEND(*dst, _ialpha(buffer[i]));
+ for (uint32_t x = 0; x < span->len; ++x, ++dst) {
+ *dst = buffer[x] + ALPHA_BLEND(*dst, _ialpha(buffer[x]));
}
} else {
- for (uint32_t i = 0; i < span->len; ++i, ++dst) {
- auto tmp = ALPHA_BLEND(buffer[i], span->coverage);
+ for (uint32_t x = 0; x < span->len; ++x, ++dst) {
+ auto tmp = ALPHA_BLEND(buffer[x], span->coverage);
*dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
}
}
@@ -1142,8 +1148,8 @@ static bool _rasterSolidLinearGradientRle(SwSurface* surface, const SwRleData* r
} else {
fillFetchLinear(fill, buf, span->y, span->x, span->len);
auto dst = &surface->buffer[span->y * surface->stride + span->x];
- for (uint32_t i = 0; i < span->len; ++i) {
- dst[i] = INTERPOLATE(span->coverage, buf[i], dst[i]);
+ for (uint32_t x = 0; x < span->len; ++x) {
+ dst[x] = INTERPOLATE(span->coverage, buf[x], dst[x]);
}
}
}
@@ -1302,12 +1308,12 @@ static bool _rasterTranslucentRadialGradientRle(SwSurface* surface, const SwRleD
auto dst = &surface->buffer[span->y * surface->stride + span->x];
fillFetchRadial(fill, buffer, span->y, span->x, span->len);
if (span->coverage == 255) {
- for (uint32_t i = 0; i < span->len; ++i, ++dst) {
- *dst = buffer[i] + ALPHA_BLEND(*dst, _ialpha(buffer[i]));
+ for (uint32_t x = 0; x < span->len; ++x, ++dst) {
+ *dst = buffer[x] + ALPHA_BLEND(*dst, _ialpha(buffer[x]));
}
} else {
- for (uint32_t i = 0; i < span->len; ++i, ++dst) {
- auto tmp = ALPHA_BLEND(buffer[i], span->coverage);
+ for (uint32_t x = 0; x < span->len; ++x, ++dst) {
+ auto tmp = ALPHA_BLEND(buffer[x], span->coverage);
*dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
}
}
@@ -1332,8 +1338,8 @@ static bool _rasterSolidRadialGradientRle(SwSurface* surface, const SwRleData* r
} else {
fillFetchRadial(fill, buf, span->y, span->x, span->len);
auto ialpha = 255 - span->coverage;
- for (uint32_t i = 0; i < span->len; ++i, ++dst) {
- *dst = ALPHA_BLEND(buf[i], span->coverage) + ALPHA_BLEND(*dst, ialpha);
+ for (uint32_t x = 0; x < span->len; ++x, ++dst) {
+ *dst = ALPHA_BLEND(buf[x], span->coverage) + ALPHA_BLEND(*dst, ialpha);
}
}
}
@@ -1487,7 +1493,7 @@ bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, const SwBBox& bbox, uint32_t opacity)
{
//Verify Boundary
- if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= surface->w || bbox.min.y >= surface->h) return false;
+ if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast<SwCoord>(surface->w) || bbox.min.y >= static_cast<SwCoord>(surface->h)) return false;
//TOOD: switch (image->format)
//TODO: case: _rasterRGBImage()
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h
index 4e8d342137..e96307c874 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h
@@ -58,8 +58,8 @@
y = yStart;
while (y < yEnd) {
- x1 = _xa;
- x2 = _xb;
+ x1 = (int32_t)_xa;
+ x2 = (int32_t)_xb;
if (!region) {
minx = INT32_MAX;
@@ -160,4 +160,4 @@ next:
xb = _xb;
ua = _ua;
va = _va;
-} \ No newline at end of file
+}
diff --git a/thirdparty/thorvg/src/lib/tvgMath.h b/thirdparty/thorvg/src/lib/tvgMath.h
index 94b4fe1cf1..423fb6eb1b 100644
--- a/thirdparty/thorvg/src/lib/tvgMath.h
+++ b/thirdparty/thorvg/src/lib/tvgMath.h
@@ -47,7 +47,7 @@ static inline bool mathEqual(float a, float b)
static inline bool mathRightAngle(const Matrix* m)
{
- auto radian = fabsf(atan2(m->e21, m->e11));
+ auto radian = fabsf(atan2f(m->e21, m->e11));
if (radian < FLT_EPSILON || mathEqual(radian, float(M_PI_2)) || mathEqual(radian, float(M_PI))) return true;
return false;
}
diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp
index 8846613c6b..f27881da42 100644
--- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp
+++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp
@@ -47,6 +47,7 @@ JpgLoader::~JpgLoader()
{
jpgdDelete(decoder);
if (freeData) free(data);
+ free(image);
}
@@ -128,5 +129,9 @@ unique_ptr<Surface> JpgLoader::bitmap()
void JpgLoader::run(unsigned tid)
{
+ if (image) {
+ free(image);
+ image = nullptr;
+ }
image = jpgdDecompress(decoder);
} \ No newline at end of file
diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp
index fa72734ec4..4ccc5788d5 100644
--- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp
+++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp
@@ -1080,7 +1080,9 @@ namespace DCT_Upsample
// Unconditionally frees all allocated m_blocks.
void jpeg_decoder::free_all_blocks()
{
+ delete(m_pStream);
m_pStream = nullptr;
+
for (mem_block *b = m_pMem_blocks; b; ) {
mem_block *n = b->m_pNext;
free(b);
@@ -2815,7 +2817,6 @@ int jpeg_decoder::begin_decoding()
jpeg_decoder::~jpeg_decoder()
{
free_all_blocks();
- delete(m_pStream);
}
@@ -3025,4 +3026,4 @@ unsigned char* jpgdDecompress(jpeg_decoder* decoder)
}
}
return pImage_data;
-} \ No newline at end of file
+}
diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h
index d32ffd99d4..ca9cb35c32 100644
--- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h
+++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp
index c6d95be5ba..3cc08e902b 100644
--- a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp
+++ b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp
@@ -72,6 +72,7 @@ PngLoader::PngLoader()
PngLoader::~PngLoader()
{
if (freeData) free(data);
+ free(image);
}
@@ -121,7 +122,7 @@ bool PngLoader::open(const char* data, uint32_t size, bool copy)
clear();
lodepng_state_init(&state);
-
+
unsigned int width, height;
if (lodepng_inspect(&width, &height, &state, (unsigned char*)(data), size) > 0) return false;
@@ -180,10 +181,14 @@ unique_ptr<Surface> PngLoader::bitmap()
void PngLoader::run(unsigned tid)
{
+ if (image) {
+ free(image);
+ image = nullptr;
+ }
auto width = static_cast<unsigned>(w);
auto height = static_cast<unsigned>(h);
lodepng_decode(&image, &width, &height, &state, data, size);
_premultiply((uint32_t*)(image), width, height);
-} \ No newline at end of file
+}
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
index cf103774c5..08b3308165 100644
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
@@ -541,7 +541,7 @@ static void _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char**
}
}
}
- } else if (len >= 3 && !strncmp(str, "url", 3)) {
+ } else if (ref && len >= 3 && !strncmp(str, "url", 3)) {
*ref = _idFromUrl((const char*)(str + 3));
} else {
//Handle named color
@@ -789,7 +789,7 @@ static bool _attrParseSvgNode(void* data, const char* key, const char* value)
return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader);
}
#ifdef THORVG_LOG_ENABLED
- else if ((!strcmp(key, "x") || !strcmp(key, "y")) && fabsf(svgUtilStrtof(value, nullptr)) > FLT_EPSILON ) {
+ else if ((!strcmp(key, "x") || !strcmp(key, "y")) && fabsf(svgUtilStrtof(value, nullptr)) > FLT_EPSILON) {
TVGLOG("SVG", "Unsupported attributes used [Elements type: Svg][Attribute: %s][Value: %s]", key, value);
}
#endif
@@ -1611,6 +1611,7 @@ static bool _attrParseImageNode(void* data, const char* key, const char* value)
}
if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
+ if (image->href && value) free(image->href);
image->href = _idFromHref(value);
} else if (!strcmp(key, "id")) {
if (node->id && value) free(node->id);
@@ -1728,6 +1729,112 @@ error_grad_alloc:
}
+static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* parent)
+{
+ if (parent == nullptr) return;
+ //Inherit the property of parent if not present in child.
+ if (!child->curColorSet) {
+ child->color = parent->color;
+ child->curColorSet = parent->curColorSet;
+ }
+ //Fill
+ if (!((int)child->fill.flags & (int)SvgFillFlags::Paint)) {
+ child->fill.paint.color = parent->fill.paint.color;
+ child->fill.paint.none = parent->fill.paint.none;
+ child->fill.paint.curColor = parent->fill.paint.curColor;
+ if (parent->fill.paint.url) child->fill.paint.url = _copyId(parent->fill.paint.url);
+ }
+ if (!((int)child->fill.flags & (int)SvgFillFlags::Opacity)) {
+ child->fill.opacity = parent->fill.opacity;
+ }
+ if (!((int)child->fill.flags & (int)SvgFillFlags::FillRule)) {
+ child->fill.fillRule = parent->fill.fillRule;
+ }
+ //Stroke
+ if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Paint)) {
+ child->stroke.paint.color = parent->stroke.paint.color;
+ child->stroke.paint.none = parent->stroke.paint.none;
+ child->stroke.paint.curColor = parent->stroke.paint.curColor;
+ child->stroke.paint.url = parent->stroke.paint.url ? _copyId(parent->stroke.paint.url) : nullptr;
+ }
+ if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Opacity)) {
+ child->stroke.opacity = parent->stroke.opacity;
+ }
+ if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Width)) {
+ child->stroke.width = parent->stroke.width;
+ }
+ if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Dash)) {
+ if (parent->stroke.dash.array.count > 0) {
+ child->stroke.dash.array.clear();
+ child->stroke.dash.array.reserve(parent->stroke.dash.array.count);
+ for (uint32_t i = 0; i < parent->stroke.dash.array.count; ++i) {
+ child->stroke.dash.array.push(parent->stroke.dash.array.data[i]);
+ }
+ }
+ }
+ if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Cap)) {
+ child->stroke.cap = parent->stroke.cap;
+ }
+ if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Join)) {
+ child->stroke.join = parent->stroke.join;
+ }
+}
+
+
+static void _styleCopy(SvgStyleProperty* to, const SvgStyleProperty* from)
+{
+ if (from == nullptr) return;
+ //Copy the properties of 'from' only if they were explicitly set (not the default ones).
+ if (from->curColorSet) {
+ to->color = from->color;
+ to->curColorSet = true;
+ }
+ //Fill
+ to->fill.flags = (SvgFillFlags)((int)to->fill.flags | (int)from->fill.flags);
+ if (((int)from->fill.flags & (int)SvgFillFlags::Paint)) {
+ to->fill.paint.color = from->fill.paint.color;
+ to->fill.paint.none = from->fill.paint.none;
+ to->fill.paint.curColor = from->fill.paint.curColor;
+ if (from->fill.paint.url) to->fill.paint.url = _copyId(from->fill.paint.url);
+ }
+ if (((int)from->fill.flags & (int)SvgFillFlags::Opacity)) {
+ to->fill.opacity = from->fill.opacity;
+ }
+ if (((int)from->fill.flags & (int)SvgFillFlags::FillRule)) {
+ to->fill.fillRule = from->fill.fillRule;
+ }
+ //Stroke
+ to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)from->stroke.flags);
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Paint)) {
+ to->stroke.paint.color = from->stroke.paint.color;
+ to->stroke.paint.none = from->stroke.paint.none;
+ to->stroke.paint.curColor = from->stroke.paint.curColor;
+ to->stroke.paint.url = from->stroke.paint.url ? _copyId(from->stroke.paint.url) : nullptr;
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Opacity)) {
+ to->stroke.opacity = from->stroke.opacity;
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Width)) {
+ to->stroke.width = from->stroke.width;
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Dash)) {
+ if (from->stroke.dash.array.count > 0) {
+ to->stroke.dash.array.clear();
+ to->stroke.dash.array.reserve(from->stroke.dash.array.count);
+ for (uint32_t i = 0; i < from->stroke.dash.array.count; ++i) {
+ to->stroke.dash.array.push(from->stroke.dash.array.data[i]);
+ }
+ }
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Cap)) {
+ to->stroke.cap = from->stroke.cap;
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Join)) {
+ to->stroke.join = from->stroke.join;
+ }
+}
+
+
static void _copyAttr(SvgNode* to, const SvgNode* from)
{
//Copy matrix attribute
@@ -1736,7 +1843,8 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
if (to->transform) *to->transform = *from->transform;
}
//Copy style attribute
- *to->style = *from->style;
+ _styleCopy(to->style, from->style);
+ to->style->flags = (SvgStyleFlags)((int)to->style->flags | (int)from->style->flags);
if (from->style->fill.paint.url) to->style->fill.paint.url = strdup(from->style->fill.paint.url);
if (from->style->stroke.paint.url) to->style->stroke.paint.url = strdup(from->style->stroke.paint.url);
if (from->style->clipPath.url) to->style->clipPath.url = strdup(from->style->clipPath.url);
@@ -1780,15 +1888,17 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
break;
}
case SvgNodeType::Polygon: {
- to->node.polygon.pointsCount = from->node.polygon.pointsCount;
- to->node.polygon.points = (float*)malloc(to->node.polygon.pointsCount * sizeof(float));
- memcpy(to->node.polygon.points, from->node.polygon.points, to->node.polygon.pointsCount * sizeof(float));
+ if ((to->node.polygon.pointsCount = from->node.polygon.pointsCount)) {
+ to->node.polygon.points = (float*)malloc(to->node.polygon.pointsCount * sizeof(float));
+ memcpy(to->node.polygon.points, from->node.polygon.points, to->node.polygon.pointsCount * sizeof(float));
+ }
break;
}
case SvgNodeType::Polyline: {
- to->node.polyline.pointsCount = from->node.polyline.pointsCount;
- to->node.polyline.points = (float*)malloc(to->node.polyline.pointsCount * sizeof(float));
- memcpy(to->node.polyline.points, from->node.polyline.points, to->node.polyline.pointsCount * sizeof(float));
+ if ((to->node.polyline.pointsCount = from->node.polyline.pointsCount)) {
+ to->node.polyline.points = (float*)malloc(to->node.polyline.pointsCount * sizeof(float));
+ memcpy(to->node.polyline.points, from->node.polyline.points, to->node.polyline.pointsCount * sizeof(float));
+ }
break;
}
case SvgNodeType::Image: {
@@ -1806,35 +1916,45 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
}
-static void _cloneNode(SvgNode* from, SvgNode* parent)
+static void _cloneNode(SvgNode* from, SvgNode* parent, int depth)
{
+ /* Exception handling: Prevent invalid SVG data input.
+ The size is the arbitrary value, we need an experimental size. */
+ if (depth == 8192) {
+ TVGERR("SVG", "Infinite recursive call - stopped after %d calls! Svg file may be incorrectly formatted.", depth);
+ return;
+ }
+
SvgNode* newNode;
- if (!from || !parent) return;
+ if (!from || !parent || from == parent) return;
newNode = _createNode(parent, from->type);
-
if (!newNode) return;
+ _styleInherit(newNode->style, parent->style);
_copyAttr(newNode, from);
auto child = from->child.data;
for (uint32_t i = 0; i < from->child.count; ++i, ++child) {
- _cloneNode(*child, newNode);
+ _cloneNode(*child, newNode, depth + 1);
}
}
-static void _postponeCloneNode(SvgLoaderData* loader, SvgNode *node, char* id) {
+static void _postponeCloneNode(SvgLoaderData* loader, SvgNode *node, char* id)
+{
loader->cloneNodes.push({node, id});
}
-static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes) {
+static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes, SvgNode* doc)
+{
for (uint32_t i = 0; i < cloneNodes->count; ++i) {
auto nodeIdPair = cloneNodes->data[i];
auto defs = _getDefsNode(nodeIdPair.node);
auto nodeFrom = _findChildById(defs, nodeIdPair.id);
- _cloneNode(nodeFrom, nodeIdPair.node);
+ if (!nodeFrom) nodeFrom = _findChildById(doc, nodeIdPair.id);
+ _cloneNode(nodeFrom, nodeIdPair.node, 0);
free(nodeIdPair.id);
}
}
@@ -1875,7 +1995,7 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value)
defs = _getDefsNode(node);
nodeFrom = _findChildById(defs, id);
if (nodeFrom) {
- _cloneNode(nodeFrom, node);
+ _cloneNode(nodeFrom, node, 0);
free(id);
} else {
//some svg export software include <defs> element at the end of the file
@@ -1883,10 +2003,6 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value)
//after the whole file is parsed
_postponeCloneNode(loader, node, id);
}
- } else if (!strcmp(key, "clip-path")) {
- _handleClipPathAttr(loader, node, value);
- } else if (!strcmp(key, "mask")) {
- _handleMaskAttr(loader, node, value);
} else {
return _attrParseGNode(data, key, value);
}
@@ -2081,10 +2197,12 @@ static bool _attrParseRadialGradientNode(void* data, const char* key, const char
}
if (!strcmp(key, "id")) {
+ if (grad->id && value) free(grad->id);
grad->id = _copyId(value);
} else if (!strcmp(key, "spreadMethod")) {
grad->spread = _parseSpreadValue(value);
} else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
+ if (grad->ref && value) free(grad->ref);
grad->ref = _idFromHref(value);
} else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse")) {
grad->userSpace = true;
@@ -2269,10 +2387,12 @@ static bool _attrParseLinearGradientNode(void* data, const char* key, const char
}
if (!strcmp(key, "id")) {
+ if (grad->id && value) free(grad->id);
grad->id = _copyId(value);
} else if (!strcmp(key, "spreadMethod")) {
grad->spread = _parseSpreadValue(value);
} else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
+ if (grad->ref && value) free(grad->ref);
grad->ref = _idFromHref(value);
} else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse")) {
grad->userSpace = true;
@@ -2408,6 +2528,7 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
if ((method = _findGroupFactory(tagName))) {
//Group
+ if (empty) return;
if (!loader->doc) {
if (strcmp(tagName, "svg")) return; //Not a valid svg document
node = method(loader, nullptr, attrs, attrsLength);
@@ -2493,59 +2614,8 @@ static bool _svgLoaderParser(void* data, SimpleXMLType type, const char* content
}
-static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* parent)
+static void _inefficientNodeCheck(TVG_UNUSED SvgNode* node)
{
- if (parent == nullptr) return;
- //Inherit the property of parent if not present in child.
- //Fill
- if (!((int)child->fill.flags & (int)SvgFillFlags::Paint)) {
- child->fill.paint.color = parent->fill.paint.color;
- child->fill.paint.none = parent->fill.paint.none;
- child->fill.paint.curColor = parent->fill.paint.curColor;
- if (parent->fill.paint.url) child->fill.paint.url = _copyId(parent->fill.paint.url);
- } else if (child->fill.paint.curColor && !child->curColorSet) {
- child->color = parent->color;
- }
- if (!((int)child->fill.flags & (int)SvgFillFlags::Opacity)) {
- child->fill.opacity = parent->fill.opacity;
- }
- if (!((int)child->fill.flags & (int)SvgFillFlags::FillRule)) {
- child->fill.fillRule = parent->fill.fillRule;
- }
- //Stroke
- if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Paint)) {
- child->stroke.paint.color = parent->stroke.paint.color;
- child->stroke.paint.none = parent->stroke.paint.none;
- child->stroke.paint.curColor = parent->stroke.paint.curColor;
- child->stroke.paint.url = parent->stroke.paint.url ? _copyId(parent->stroke.paint.url) : nullptr;
- } else if (child->stroke.paint.curColor && !child->curColorSet) {
- child->color = parent->color;
- }
- if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Opacity)) {
- child->stroke.opacity = parent->stroke.opacity;
- }
- if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Width)) {
- child->stroke.width = parent->stroke.width;
- }
- if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Dash)) {
- if (parent->stroke.dash.array.count > 0) {
- child->stroke.dash.array.clear();
- child->stroke.dash.array.reserve(parent->stroke.dash.array.count);
- for (uint32_t i = 0; i < parent->stroke.dash.array.count; ++i) {
- child->stroke.dash.array.push(parent->stroke.dash.array.data[i]);
- }
- }
- }
- if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Cap)) {
- child->stroke.cap = parent->stroke.cap;
- }
- if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Join)) {
- child->stroke.join = parent->stroke.join;
- }
-}
-
-
-static void _inefficientNodeCheck(TVG_UNUSED SvgNode* node){
#ifdef THORVG_LOG_ENABLED
auto type = simpleXmlNodeTypeToString(node->type);
@@ -2838,14 +2908,14 @@ void SvgLoader::run(unsigned tid)
if (loaderData.doc) {
_updateStyle(loaderData.doc, nullptr);
auto defs = loaderData.doc->node.doc.defs;
- if (defs) _updateGradient(loaderData.doc, &defs->node.defs.gradients);
-
- if (loaderData.gradients.count > 0) _updateGradient(loaderData.doc, &loaderData.gradients);
_updateComposite(loaderData.doc, loaderData.doc);
if (defs) _updateComposite(loaderData.doc, defs);
- if (loaderData.cloneNodes.count > 0) _clonePostponedNodes(&loaderData.cloneNodes);
+ if (loaderData.cloneNodes.count > 0) _clonePostponedNodes(&loaderData.cloneNodes, loaderData.doc);
+
+ if (loaderData.gradients.count > 0) _updateGradient(loaderData.doc, &loaderData.gradients);
+ if (defs) _updateGradient(loaderData.doc, &defs->node.defs.gradients);
}
root = svgSceneBuild(loaderData.doc, vx, vy, vw, vh, w, h, preserveAspect, svgPath);
}
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp
index 1571aa4e25..ee199da231 100644
--- a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp
+++ b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp
@@ -220,15 +220,15 @@ static SimpleXMLType _getXMLType(const char* itr, const char* itrEnd, size_t &to
if ((itr + sizeof("<!DOCTYPE>") - 1 < itrEnd) && (!memcmp(itr + 2, "DOCTYPE", sizeof("DOCTYPE") - 1)) && ((itr[2 + sizeof("DOCTYPE") - 1] == '>') || (isspace((unsigned char)itr[2 + sizeof("DOCTYPE") - 1])))) {
toff = sizeof("!DOCTYPE") - 1;
return SimpleXMLType::Doctype;
- } else if (itr + sizeof("<!>") - 1 < itrEnd) {
- toff = sizeof("!") - 1;
- return SimpleXMLType::DoctypeChild;
} else if ((itr + sizeof("<![CDATA[]]>") - 1 < itrEnd) && (!memcmp(itr + 2, "[CDATA[", sizeof("[CDATA[") - 1))) {
toff = sizeof("![CDATA[") - 1;
return SimpleXMLType::CData;
} else if ((itr + sizeof("<!---->") - 1 < itrEnd) && (!memcmp(itr + 2, "--", sizeof("--") - 1))) {
toff = sizeof("!--") - 1;
return SimpleXMLType::Comment;
+ } else if (itr + sizeof("<!>") - 1 < itrEnd) {
+ toff = sizeof("!") - 1;
+ return SimpleXMLType::DoctypeChild;
}
return SimpleXMLType::Open;
}
diff --git a/thirdparty/thorvg/update-thorvg.sh b/thirdparty/thorvg/update-thorvg.sh
index c200131eba..ce3d5eed1c 100755
--- a/thirdparty/thorvg/update-thorvg.sh
+++ b/thirdparty/thorvg/update-thorvg.sh
@@ -1,4 +1,4 @@
-VERSION=0.7.0
+VERSION=0.7.1
rm -rf AUTHORS inc LICENSE src *.zip
curl -L -O https://github.com/Samsung/thorvg/archive/refs/tags/v$VERSION.zip
bsdtar --strip-components=1 -xvf *.zip